diff --git a/civicrm/CRM/Admin/Form/WordReplacements.php b/civicrm/CRM/Admin/Form/WordReplacements.php
index 0a5fabdb0c5f127b86352e33aa98c302b6ee549c..a130f505d2d9b41baaa0e332a9e63ffe947dd5db 100644
--- a/civicrm/CRM/Admin/Form/WordReplacements.php
+++ b/civicrm/CRM/Admin/Form/WordReplacements.php
@@ -226,7 +226,8 @@ class CRM_Admin_Form_WordReplacements extends CRM_Core_Form {
     CRM_Core_BAO_WordReplacement::setLocaleCustomStrings($config->lcMessages, $overrides);
 
     // This controller was originally written to CRUD $config->locale_custom_strings,
-    // but that's no longer the canonical store. Sync changes to canonical store.
+    // but that's no longer the canonical store. Sync changes to canonical store
+    // (civicrm_word_replacement table in the database).
     // This is inefficient - at some point, we should rewrite this UI.
     CRM_Core_BAO_WordReplacement::rebuildWordReplacementTable();
 
diff --git a/civicrm/CRM/Batch/Form/Entry.php b/civicrm/CRM/Batch/Form/Entry.php
index 1eed1209e4730ccad0a1bb73ad8474b43eb24eda..f8fceff8cdea04921b2edd92b69b43f924b3906d 100644
--- a/civicrm/CRM/Batch/Form/Entry.php
+++ b/civicrm/CRM/Batch/Form/Entry.php
@@ -108,6 +108,13 @@ class CRM_Batch_Form_Entry extends CRM_Core_Form {
 
   }
 
+  /**
+   * Used in test to set Batch ID
+   */
+  public function setBatchID($id) {
+    $this->_batchId = $id;
+  }
+
   /**
    * Build the form object.
    */
diff --git a/civicrm/CRM/Campaign/Controller/Search.php b/civicrm/CRM/Campaign/Controller/Search.php
index 12ff9b1c478a3c6ebef157324720f9ede35b4256..976e58c9db9a1b7f824baa7ab578356fda599673 100644
--- a/civicrm/CRM/Campaign/Controller/Search.php
+++ b/civicrm/CRM/Campaign/Controller/Search.php
@@ -37,9 +37,9 @@
  *  - the search controller is used for building/processing multiform
  *    searches.
  *
- * Typically the first form will display the search criteria and it's results
+ * Typically the first form will display the search criteria and its results
  *
- * The second form is used to process search results with the asscociated actions
+ * The second form is used to process search results with the associated actions
  *
  */
 class CRM_Campaign_Controller_Search extends CRM_Core_Controller {
diff --git a/civicrm/CRM/Case/Controller/Search.php b/civicrm/CRM/Case/Controller/Search.php
index 74811c4cab648d22a132349e902354e33667e841..3488d3775e9a717d3d503a7512f5f00efa8d9cf3 100644
--- a/civicrm/CRM/Case/Controller/Search.php
+++ b/civicrm/CRM/Case/Controller/Search.php
@@ -37,9 +37,9 @@
  *  - the search controller is used for building/processing multiform
  *    searches.
  *
- * Typically the first form will display the search criteria and it's results
+ * Typically the first form will display the search criteria and its results
  *
- * The second form is used to process search results with the asscociated actions
+ * The second form is used to process search results with the associated actions
  *
  */
 class CRM_Case_Controller_Search extends CRM_Core_Controller {
diff --git a/civicrm/CRM/Contact/BAO/Group.php b/civicrm/CRM/Contact/BAO/Group.php
index 4715fead973ba9e70b33d9c045b856486be851e2..69e043be8a2c7b59d9a311d89c550f610af8608f 100644
--- a/civicrm/CRM/Contact/BAO/Group.php
+++ b/civicrm/CRM/Contact/BAO/Group.php
@@ -1359,4 +1359,26 @@ WHERE {$whereClause}";
     }
   }
 
+  /**
+   * Get child group ids
+   *
+   * @param array $ids
+   *    Parent Group IDs
+   *
+   * @return array
+   */
+  public static function getChildGroupIds($ids) {
+    $notFound = FALSE;
+    $childGroupIds = array();
+    foreach ($ids as $id) {
+      $childId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $id, 'children');
+      while (!empty($childId)) {
+        $childGroupIds[] = $childId;
+        $childId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $childId, 'children');
+      }
+    }
+
+    return $childGroupIds;
+  }
+
 }
diff --git a/civicrm/CRM/Contact/BAO/Query.php b/civicrm/CRM/Contact/BAO/Query.php
index 2f76936e54916ebf629710cd4deca2c4cd4c50fa..cb9a448a34519991bc45da806f37edbee4d4221c 100644
--- a/civicrm/CRM/Contact/BAO/Query.php
+++ b/civicrm/CRM/Contact/BAO/Query.php
@@ -1791,18 +1791,7 @@ class CRM_Contact_BAO_Query {
         return;
 
       case 'group':
-        $this->group($values);
-        return;
-
       case 'group_type':
-        // so we resolve this into a list of groups & proceed as if they had been
-        // handed in
-        list($name, $op, $value, $grouping, $wildcard) = $values;
-        $values[0] = 'group';
-        $values[1] = 'IN';
-        $this->_paramLookup['group'][0][0] = 'group';
-        $this->_paramLookup['group'][0][1] = 'IN';
-        $this->_paramLookup['group'][0][2] = $values[2] = $this->getGroupsFromTypeCriteria($value);
         $this->group($values);
         return;
 
@@ -2919,7 +2908,19 @@ class CRM_Contact_BAO_Query {
       $value = CRM_Utils_Array::value($op, $value, $value);
     }
 
-    $groupIds = NULL;
+    if ($name == 'group_type') {
+      $value = array_keys($this->getGroupsFromTypeCriteria($value));
+    }
+
+    $regularGroupIDs = $smartGroupIDs = array();
+    foreach ((array) $value as $id) {
+      if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $id, 'saved_search_id')) {
+        $smartGroupIDs[] = $id;
+      }
+      else {
+        $regularGroupIDs[] = $id;
+      }
+    }
 
     $isNotOp = ($op == 'NOT IN' || $op == '!=');
 
@@ -2935,32 +2936,12 @@ class CRM_Contact_BAO_Query {
       }
     }
     else {
-      $statii[] = '"Added"';
-    }
-
-    //CRM-19589: contact(s) removed from a Smart Group, resides in civicrm_group_contact table
-    $ssClause = NULL;
-    if (empty($gcsValues) || // if no status selected
-      in_array("'Added'", $statii) ||  // if both Added and Removed statuses are selected
-      (count($statii) == 1 && $statii[0] == 'Removed') // if only Removed status is selected
-    ) {
-      $ssClause = $this->addGroupContactCache($value, NULL, "contact_a", $op);
-    }
-
-    $isSmart = (!$ssClause) ? FALSE : TRUE;
-    if (!is_array($value) &&
-      count($statii) == 1 &&
-      $statii[0] == '"Added"' &&
-      !$isNotOp
-    ) {
-      if (!empty($value) && CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $value, 'saved_search_id')) {
-        $isSmart = TRUE;
-      }
+      $statii[] = "'Added'";
     }
-    $groupClause = NULL;
 
-    if (!$isSmart || in_array("'Added'", $statii)) {
-      $groupIds = implode(',', (array) $value);
+    $groupClause = array();
+    if (count($regularGroupIDs) || empty($value)) {
+      $groupIds = implode(',', (array) $regularGroupIDs);
       $gcTable = "`civicrm_group_contact-{$groupIds}`";
       $joinClause = array("contact_a.id = {$gcTable}.contact_id");
       if ($statii) {
@@ -2968,35 +2949,38 @@ class CRM_Contact_BAO_Query {
       }
       $this->_tables[$gcTable] = $this->_whereTables[$gcTable] = " LEFT JOIN civicrm_group_contact {$gcTable} ON (" . implode(' AND ', $joinClause) . ")";
       if (strpos($op, 'IN') !== FALSE) {
-        $groupClause = "{$gcTable}.group_id $op ( $groupIds )";
+        $clause = "{$gcTable}.group_id $op ( $groupIds ) %s ";
       }
       elseif ($op == '!=') {
-        $groupClause = "{$gcTable}.contact_id NOT IN (SELECT contact_id FROM civicrm_group_contact cgc WHERE cgc.group_id = $groupIds)";
+        $clause = "{$gcTable}.contact_id NOT IN (SELECT contact_id FROM civicrm_group_contact cgc WHERE cgc.group_id = $groupIds %s)";
       }
       else {
-        $groupClause = "{$gcTable}.group_id $op $groupIds";
+        $clause = "{$gcTable}.group_id $op $groupIds %s ";
       }
-    }
 
-    if ($ssClause) {
-      $and = ($op == 'IS NULL') ? 'AND' : 'OR';
-      if ($groupClause) {
-        $groupClause = "( ( $groupClause ) $and ( $ssClause ) )";
-      }
-      else {
-        $groupClause = $ssClause;
+      // include child groups IDs if any
+      $childGroupIds = CRM_Contact_BAO_Group::getChildGroupIds($regularGroupIDs);
+      $childClause = '';
+      if (count($childGroupIds)) {
+        $gcTable = ($op == '!=') ? 'cgc' : $gcTable;
+        $childClause = " OR {$gcTable}.group_id IN (" . implode(',', $childGroupIds) . ") ";
       }
+      $groupClause[] = sprintf($clause, $childClause);
+    }
+
+    //CRM-19589: contact(s) removed from a Smart Group, resides in civicrm_group_contact table
+    if (count($smartGroupIDs)) {
+      $groupClause[] = " ( " . $this->addGroupContactCache($smartGroupIDs, NULL, "contact_a", $op) . " ) ";
     }
 
+    $and = ($op == 'IS NULL') ? ' AND ' : ' OR ';
+    $this->_where[$grouping][] = implode($and, $groupClause);
+
     list($qillop, $qillVal) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Contact_DAO_Group', 'id', $value, $op);
     $this->_qill[$grouping][] = ts("Group(s) %1 %2", array(1 => $qillop, 2 => $qillVal));
     if (strpos($op, 'NULL') === FALSE) {
       $this->_qill[$grouping][] = ts("Group Status %1", array(1 => implode(' ' . ts('or') . ' ', $statii)));
     }
-
-    if ($groupClause) {
-      $this->_where[$grouping][] = $groupClause;
-    }
   }
 
   /**
@@ -5944,6 +5928,13 @@ AND   displayRelType.is_active = 1
   ) {
     $qillOperators = CRM_Core_SelectValues::getSearchBuilderOperators();
 
+    //API usually have fieldValue format as array(operator => array(values)),
+    //so we need to separate operator out of fieldValue param
+    if (is_array($fieldValue) && in_array(key($fieldValue), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) {
+      $op = key($fieldValue);
+      $fieldValue = $fieldValue[$op];
+    }
+
     // if Operator chosen is NULL/EMPTY then
     if (strpos($op, 'NULL') !== FALSE || strpos($op, 'EMPTY') !== FALSE) {
       return array(CRM_Utils_Array::value($op, $qillOperators, $op), '');
@@ -5970,17 +5961,13 @@ AND   displayRelType.is_active = 1
     elseif ($daoName == 'CRM_Contact_DAO_Group' && $fieldName == 'id') {
       $pseudoOptions = CRM_Core_PseudoConstant::group();
     }
+    elseif ($daoName == 'CRM_Batch_BAO_EntityBatch' && $fieldName == 'batch_id') {
+      $pseudoOptions = CRM_Contribute_PseudoConstant::batch();
+    }
     elseif ($daoName) {
       $pseudoOptions = CRM_Core_PseudoConstant::get($daoName, $fieldName, $pseudoExtraParam);
     }
 
-    //API usually have fieldValue format as array(operator => array(values)),
-    //so we need to separate operator out of fieldValue param
-    if (is_array($fieldValue) && in_array(key($fieldValue), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) {
-      $op = key($fieldValue);
-      $fieldValue = $fieldValue[$op];
-    }
-
     if (is_array($fieldValue)) {
       $qillString = array();
       if (!empty($pseudoOptions)) {
@@ -6055,6 +6042,9 @@ AND   displayRelType.is_active = 1
    *   Array of fields whose name should be changed
    */
   public static function processSpecialFormValue(&$formValues, $specialFields, $changeNames = array()) {
+    // Array of special fields whose value are considered only for NULL or EMPTY operators
+    $nullableFields = array('contribution_batch_id');
+
     foreach ($specialFields as $element) {
       $value = CRM_Utils_Array::value($element, $formValues);
       if ($value) {
@@ -6065,7 +6055,10 @@ AND   displayRelType.is_active = 1
           }
           $formValues[$element] = array('IN' => $value);
         }
-        else {
+        elseif (in_array($value, array('IS NULL', 'IS NOT NULL', 'IS EMPTY', 'IS NOT EMPTY'))) {
+          $formValues[$element] = array($value => 1);
+        }
+        elseif (!in_array($element, $nullableFields)) {
           // if wildcard is already present return searchString as it is OR append and/or prepend with wildcard
           $isWilcard = strstr($value, '%') ? FALSE : CRM_Core_Config::singleton()->includeWildCardInName;
           $formValues[$element] = array('LIKE' => self::getWildCardedValue($isWilcard, 'LIKE', $value));
diff --git a/civicrm/CRM/Contact/Form/Search/Custom/ContributionAggregate.php b/civicrm/CRM/Contact/Form/Search/Custom/ContributionAggregate.php
index c5015b0a3a1dc907ac4bbbe9325842ef778d817e..b545c07387e99eb4735c540fd3b9a98ced50773b 100644
--- a/civicrm/CRM/Contact/Form/Search/Custom/ContributionAggregate.php
+++ b/civicrm/CRM/Contact/Form/Search/Custom/ContributionAggregate.php
@@ -83,9 +83,7 @@ class CRM_Contact_Form_Search_Custom_ContributionAggregate extends CRM_Contact_F
       ts('...and $')
     );
     $form->addRule('max_amount', ts('Please enter a valid amount (numbers and decimal point only).'), 'money');
-
-    $form->addDate('start_date', ts('Contribution Date From'), FALSE, array('formatType' => 'custom'));
-    $form->addDate('end_date', ts('...through'), FALSE, array('formatType' => 'custom'));
+    CRM_Core_Form_Date::buildDateRange($form, 'contribution_date', 1, '_low', '_high', ts('From:'), FALSE, FALSE);
 
     $form->addSelect('financial_type_id',
       array('entity' => 'contribution', 'multiple' => 'multiple', 'context' => 'search')
@@ -95,7 +93,7 @@ class CRM_Contact_Form_Search_Custom_ContributionAggregate extends CRM_Contact_F
      * If you are using the sample template, this array tells the template fields to render
      * for the search form.
      */
-    $form->assign('elements', array('min_amount', 'max_amount', 'start_date', 'end_date'));
+    $form->assign('elements', array('min_amount', 'max_amount'));
   }
 
   /**
@@ -197,22 +195,24 @@ civicrm_contact AS contact_a {$this->_aclFrom}
    * @return string
    */
   public function where($includeContactIDs = FALSE) {
-    $clauses = array();
-
-    $clauses[] = "contrib.contact_id = contact_a.id";
-    $clauses[] = "contrib.is_test = 0";
-
-    $startTime = !empty($this->_formValues['start_date_time']) ? $this->_formValues['start_date_time'] : '00:00:00';
-    $endTime = !empty($this->_formValues['end_date_time']) ? $this->_formValues['end_date_time'] : '23:59:59';
-
-    $startDate = CRM_Utils_Date::processDate($this->_formValues['start_date'], $startTime);
-    if ($startDate) {
-      $clauses[] = "contrib.receive_date >= $startDate";
-    }
+    $clauses = array(
+      "contrib.contact_id = contact_a.id",
+      "contrib.is_test = 0",
+    );
 
-    $endDate = CRM_Utils_Date::processDate($this->_formValues['end_date'], $endTime);
-    if ($endDate) {
-      $clauses[] = "contrib.receive_date <= $endDate";
+    $dateParams = array(
+      'contribution_date_relative' => $this->_formValues['contribution_date_relative'],
+      'contribution_date_low' => $this->_formValues['contribution_date_low'],
+      'contribution_date_high' => $this->_formValues['contribution_date_high'],
+    );
+    foreach (CRM_Contact_BAO_Query::convertFormValues($dateParams) as $values) {
+      list($name, $op, $value) = $values;
+      if (strstr($name, '_low')) {
+        $clauses[] = "contrib.receive_date >= " . CRM_Utils_Date::processDate($value);
+      }
+      else {
+        $clauses[] = "contrib.receive_date <= " . CRM_Utils_Date::processDate($value);
+      }
     }
 
     if ($includeContactIDs) {
diff --git a/civicrm/CRM/Contact/Form/Task.php b/civicrm/CRM/Contact/Form/Task.php
index 8f3771cd76e4afda4ac70f84cbdf9347969786d5..4fbedd6d18dc9bfdd234dbc934bd41f7c4650e87 100644
--- a/civicrm/CRM/Contact/Form/Task.php
+++ b/civicrm/CRM/Contact/Form/Task.php
@@ -428,7 +428,7 @@ class CRM_Contact_Form_Task extends CRM_Core_Form {
       $today = date('Ymd');
       $relationActive = " AND (crel.is_active = 1 AND ( crel.end_date is NULL OR crel.end_date >= {$today} ) )";
       $relationWhere = " WHERE contact_household.is_deleted = 0  AND crel.{$contactA} IN ( {$relID} ) {$relationActive}";
-      $relationGroupBy = " GROUP BY crel.{$contactA}";
+      $relationGroupBy = " GROUP BY crel.{$contactA}, contact_household.id";
       $relationQueryString = "$relationSelect $relationFrom $relationWhere $relationGroupBy";
 
       $householdsDAO = CRM_Core_DAO::executeQuery($relationQueryString);
diff --git a/civicrm/CRM/Contact/Form/Task/Label.php b/civicrm/CRM/Contact/Form/Task/Label.php
index adf8ef63683e97bb34f35c3dbfb5caaca85c7ae6..fc2f1c9ce708ba8ef6620051765c9e2d7d3e6471 100644
--- a/civicrm/CRM/Contact/Form/Task/Label.php
+++ b/civicrm/CRM/Contact/Form/Task/Label.php
@@ -48,27 +48,34 @@ class CRM_Contact_Form_Task_Label extends CRM_Contact_Form_Task {
    * Build the form object.
    */
   public function buildQuickForm() {
+    self::buildLabelForm($this);
+  }
+
+  /**
+   * Common Function to build Mailing Label Form.
+   */
+  public static function buildLabelForm($form) {
     CRM_Utils_System::setTitle(ts('Make Mailing Labels'));
 
     //add select for label
     $label = CRM_Core_BAO_LabelFormat::getList(TRUE);
 
-    $this->add('select', 'label_name', ts('Select Label'), array('' => ts('- select label -')) + $label, TRUE);
+    $form->add('select', 'label_name', ts('Select Label'), array('' => ts('- select label -')) + $label, TRUE);
 
     // add select for Location Type
-    $this->addElement('select', 'location_type_id', ts('Select Location'),
+    $form->addElement('select', 'location_type_id', ts('Select Location'),
       array(
         '' => ts('Primary'),
       ) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'), TRUE
     );
 
     // checkbox for SKIP contacts with Do Not Mail privacy option
-    $this->addElement('checkbox', 'do_not_mail', ts('Do not print labels for contacts with "Do Not Mail" privacy option checked'));
+    $form->addElement('checkbox', 'do_not_mail', ts('Do not print labels for contacts with "Do Not Mail" privacy option checked'));
 
-    $this->add('checkbox', 'merge_same_address', ts('Merge labels for contacts with the same address'), NULL);
-    $this->add('checkbox', 'merge_same_household', ts('Merge labels for contacts belonging to the same household'), NULL);
+    $form->add('checkbox', 'merge_same_address', ts('Merge labels for contacts with the same address'), NULL);
+    $form->add('checkbox', 'merge_same_household', ts('Merge labels for contacts belonging to the same household'), NULL);
 
-    $this->addButtons(array(
+    $form->addButtons(array(
       array(
         'type' => 'submit',
         'name' => ts('Make Mailing Labels'),
diff --git a/civicrm/CRM/Contribute/BAO/Contribution.php b/civicrm/CRM/Contribute/BAO/Contribution.php
index af79d62d5dcf98c45ada20aa4fbf448ce6479856..d1cbe5b895d778313b9fc90d2f09c3eb846b1b87 100644
--- a/civicrm/CRM/Contribute/BAO/Contribution.php
+++ b/civicrm/CRM/Contribute/BAO/Contribution.php
@@ -1916,6 +1916,9 @@ LEFT JOIN  civicrm_contribution contribution ON ( componentPayment.contribution_
             //update related Memberships.
             CRM_Member_BAO_Membership::updateRelatedMemberships($membership->id, $formattedParams);
 
+            //CRM-19678: No Membership Renewal Activity is created when a Pay Later is set to Completed
+            CRM_Activity_BAO_Activity::addActivity($membership, 'Membership Renewal', $membership->contact_id);
+
             $updateResult['membership_end_date'] = CRM_Utils_Date::customFormat($dates['end_date'],
               '%B %E%f, %Y'
             );
@@ -3188,7 +3191,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac
         'payment_instrument_id' => CRM_Utils_Array::value('payment_instrument_id', $params, $params['contribution']->payment_instrument_id),
         'check_number' => CRM_Utils_Array::value('check_number', $params),
       );
-      if ($contributionStatus == 'Refunded' || $contributionStatus == 'Chargeback') {
+      if ($contributionStatus == 'Refunded' || $contributionStatus == 'Chargeback' || $contributionStatus == 'Cancelled') {
         $trxnParams['trxn_date'] = !empty($params['contribution']->cancel_date) ? $params['contribution']->cancel_date : date('YmdHis');
         if (isset($params['refund_trxn_id'])) {
           // CRM-17751 allow a separate trxn_id for the refund to be passed in via api & form.
@@ -4597,6 +4600,8 @@ LIMIT 1;";
             $var = TRUE;
             CRM_Member_BAO_Membership::createRelatedMemberships($var, $var, TRUE);
             civicrm_api3('Membership', 'create', $membershipParams);
+            //CRM-19600: Add Membership Renewal activity
+            CRM_Activity_BAO_Activity::addActivity($membership, 'Membership Renewal', $membership->contact_id);
           }
         }
       }
diff --git a/civicrm/CRM/Contribute/BAO/ContributionRecur.php b/civicrm/CRM/Contribute/BAO/ContributionRecur.php
index 276c7677d0c01f29a1e2861dfc62794b511f9f78..937f8af3012dff4a8909c2ac8817a18ae8bcedde 100644
--- a/civicrm/CRM/Contribute/BAO/ContributionRecur.php
+++ b/civicrm/CRM/Contribute/BAO/ContributionRecur.php
@@ -395,8 +395,7 @@ SELECT rec.id                   as recur_id,
       FROM civicrm_contribution_recur rec
 LEFT JOIN civicrm_contribution       con ON ( con.contribution_recur_id = rec.id )
 LEFT  JOIN civicrm_membership_payment mp  ON ( mp.contribution_id = con.id )
-     WHERE rec.id = %1
-  GROUP BY rec.id";
+     WHERE rec.id = %1";
     }
     elseif ($entity == 'contribution') {
       $sql .= "
diff --git a/civicrm/CRM/Contribute/BAO/Query.php b/civicrm/CRM/Contribute/BAO/Query.php
index 85f1f32cdbb1ed0fe915b6b20a38e70166b2874b..b152dedf5cf01c4d1dec1c4f5b6ca7d11aaf460b 100644
--- a/civicrm/CRM/Contribute/BAO/Query.php
+++ b/civicrm/CRM/Contribute/BAO/Query.php
@@ -567,9 +567,9 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query {
         return;
 
       case 'contribution_batch_id':
-        $batches = CRM_Contribute_PseudoConstant::batch();
-        $query->_where[$grouping][] = " civicrm_entity_batch.batch_id $op $value";
-        $query->_qill[$grouping][] = ts('Batch Name %1 %2', array(1 => $op, 2 => $batches[$value]));
+        list($qillOp, $qillValue) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Batch_BAO_EntityBatch', 'batch_id', $value, $op);
+        $query->_qill[$grouping][] = ts('Batch Name %1 %2', array(1 => $qillOp, 2 => $qillValue));
+        $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause('civicrm_entity_batch.batch_id', $op, $value);
         $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
         $query->_tables['contribution_batch'] = $query->_whereTables['contribution_batch'] = 1;
         return;
@@ -1123,7 +1123,11 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query {
     if (!empty($batches)) {
       $form->add('select', 'contribution_batch_id',
         ts('Batch Name'),
-        array('' => ts('- any -')) + $batches,
+        array(
+          '' => ts('- any -'),
+          // CRM-19325
+          'IS NULL' => ts('None'),
+        ) + $batches,
         FALSE, array('class' => 'crm-select2')
       );
     }
diff --git a/civicrm/CRM/Contribute/Controller/ContributionPage.php b/civicrm/CRM/Contribute/Controller/ContributionPage.php
index a5e761b177428460bfbf9e06f4fb84440d4b65ed..7cec06ddf2905fe840a55fb674ab25c42b87254e 100644
--- a/civicrm/CRM/Contribute/Controller/ContributionPage.php
+++ b/civicrm/CRM/Contribute/Controller/ContributionPage.php
@@ -37,9 +37,9 @@
  *  - the search controller is used for building/processing multiform
  *    searches.
  *
- * Typically the first form will display the search criteria and it's results
+ * Typically the first form will display the search criteria and its results
  *
- * The second form is used to process search results with the asscociated actions
+ * The second form is used to process search results with the associated actions
  */
 class CRM_Contribute_Controller_ContributionPage extends CRM_Core_Controller {
 
diff --git a/civicrm/CRM/Contribute/Controller/Search.php b/civicrm/CRM/Contribute/Controller/Search.php
index c4ae7dfb7d04b519207b0ea59fe48eb3250e6d45..4d0c3ca58e25b53632c4465dcd82c54449a047ba 100644
--- a/civicrm/CRM/Contribute/Controller/Search.php
+++ b/civicrm/CRM/Contribute/Controller/Search.php
@@ -37,9 +37,9 @@
  *  - the search controller is used for building/processing multiform
  *    searches.
  *
- * Typically the first form will display the search criteria and it's results
+ * Typically the first form will display the search criteria and its results
  *
- * The second form is used to process search results with the asscociated actions
+ * The second form is used to process search results with the associated actions
  *
  */
 class CRM_Contribute_Controller_Search extends CRM_Core_Controller {
diff --git a/civicrm/CRM/Contribute/Form/Contribution.php b/civicrm/CRM/Contribute/Form/Contribution.php
index 31667ac21e03f0870477e60ac5ad9a05bc724f2c..757073e6fec9d216644df7cc709859ab30ebf819 100644
--- a/civicrm/CRM/Contribute/Form/Contribution.php
+++ b/civicrm/CRM/Contribute/Form/Contribution.php
@@ -1404,6 +1404,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
         'id' => $params['id'],
       ));
       $this->_id = $params['id'];
+      $this->_values = $existingContribution;
     }
     else {
       $existingContribution = array();
diff --git a/civicrm/CRM/Contribute/Form/Contribution/Confirm.php b/civicrm/CRM/Contribute/Form/Contribution/Confirm.php
index 5f3a119cb6db4a83cb781167f7297149ae408124..9192e912261527a45ce674a862435d39010af26e 100644
--- a/civicrm/CRM/Contribute/Form/Contribution/Confirm.php
+++ b/civicrm/CRM/Contribute/Form/Contribution/Confirm.php
@@ -2268,6 +2268,10 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       // Make it explict that we are letting the processConfirm function figure out the line items.
       $paymentParams['skipLineItem'] = 0;
 
+      if (!isset($paymentParams['line_item'])) {
+        $paymentParams['line_item'] = $this->_lineItem;
+      }
+
       if (!empty($paymentParams['onbehalf']) &&
         is_array($paymentParams['onbehalf'])
       ) {
diff --git a/civicrm/CRM/Contribute/Form/Contribution/Main.php b/civicrm/CRM/Contribute/Form/Contribution/Main.php
index 363ca318909cf0b8db43ccafc0fcac2ff845fa0c..74e8216889c9ea6d7e81fc06c2f6f11e6eb89410 100644
--- a/civicrm/CRM/Contribute/Form/Contribution/Main.php
+++ b/civicrm/CRM/Contribute/Form/Contribution/Main.php
@@ -861,9 +861,16 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
         $fields, $lineItem
       );
 
+      $minAmt = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $fields['priceSetId'], 'min_amount');
       if ($fields['amount'] < 0) {
         $errors['_qf_default'] = ts('Contribution can not be less than zero. Please select the options accordingly');
       }
+      elseif (!empty($minAmt) && $fields['amount'] < $minAmt) {
+        $errors['_qf_default'] = ts('A minimum amount of %1 should be selected from Contribution(s).', array(
+          1 => CRM_Utils_Money::format($minAmt),
+        ));
+      }
+
       $amount = $fields['amount'];
     }
 
diff --git a/civicrm/CRM/Contribute/Form/ContributionBase.php b/civicrm/CRM/Contribute/Form/ContributionBase.php
index 7bbff8c6c1a24222f2b52a4ca42d6ad391e626e8..ab112e2a8d9132969b51f174c8b0f60836f252d2 100644
--- a/civicrm/CRM/Contribute/Form/ContributionBase.php
+++ b/civicrm/CRM/Contribute/Form/ContributionBase.php
@@ -292,9 +292,15 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
       // check for is_monetary status
       $isMonetary = CRM_Utils_Array::value('is_monetary', $this->_values);
       $isPayLater = CRM_Utils_Array::value('is_pay_later', $this->_values);
-      if (!empty($this->_ccid) && $isPayLater) {
-        $isPayLater = FALSE;
-        $this->_values['is_pay_later'] = FALSE;
+      if (!empty($this->_ccid)) {
+        $this->_values['financial_type_id'] = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution',
+          $this->_ccid,
+          'financial_type_id'
+        );
+        if ($isPayLater) {
+          $isPayLater = FALSE;
+          $this->_values['is_pay_later'] = FALSE;
+        }
       }
 
       if ($isMonetary &&
@@ -658,6 +664,10 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
             else {
               $viewOnlyFileValues[$key] = $fileValue;
             }
+
+            // On viewOnly use-case (as in online contribution Confirm page) we no longer need to set
+            // required property because being required file is already uploaded while registration
+            $field['is_required'] = FALSE;
           }
           if ($profileContactType) {
             //Since we are showing honoree name separately so we are removing it from honoree profile just for display
diff --git a/civicrm/CRM/Contribute/Form/Search.php b/civicrm/CRM/Contribute/Form/Search.php
index a2b8b89861cb0d3ba79e2fa92b8f07768274af47..8b78f7c0923d6adcf83e66e0e4706b0068db6a9e 100644
--- a/civicrm/CRM/Contribute/Form/Search.php
+++ b/civicrm/CRM/Contribute/Form/Search.php
@@ -280,6 +280,7 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
         'contribution_product_id',
         'invoice_id',
         'payment_instrument_id',
+        'contribution_batch_id',
       );
       CRM_Contact_BAO_Query::processSpecialFormValue($this->_formValues, $specialParams);
 
diff --git a/civicrm/CRM/Contribute/Form/Task.php b/civicrm/CRM/Contribute/Form/Task.php
index 9e943e35a5e3959093ce91c637bfba37cc5a87cc..df277b28545da16b3e858c3004b6cfe9a9568bee 100644
--- a/civicrm/CRM/Contribute/Form/Task.php
+++ b/civicrm/CRM/Contribute/Form/Task.php
@@ -101,12 +101,12 @@ class CRM_Contribute_Form_Task extends CRM_Core_Form {
 
     $values = $form->controller->exportValues($form->get('searchFormName'));
 
-    $form->_task = $values['task'];
+    $form->_task = CRM_Utils_Array::value('task', $values);
     $contributeTasks = CRM_Contribute_Task::tasks();
-    $form->assign('taskName', $contributeTasks[$form->_task]);
+    $form->assign('taskName', CRM_Utils_Array::value($form->_task, $contributeTasks));
 
     $ids = array();
-    if ($values['radio_ts'] == 'ts_sel') {
+    if (isset($values['radio_ts']) && $values['radio_ts'] == 'ts_sel') {
       foreach ($values as $name => $value) {
         if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) {
           $ids[] = substr($name, CRM_Core_Form::CB_PREFIX_LEN);
@@ -115,13 +115,17 @@ class CRM_Contribute_Form_Task extends CRM_Core_Form {
     }
     else {
       $queryParams = $form->get('queryParams');
-      $sortOrder = NULL;
+      $returnProperties = array('contribution_id' => 1);
+      $sortOrder = $sortCol = NULL;
       if ($form->get(CRM_Utils_Sort::SORT_ORDER)) {
         $sortOrder = $form->get(CRM_Utils_Sort::SORT_ORDER);
+        //Include sort column in select clause.
+        $sortCol = trim(str_replace(array('`', 'asc', 'desc'), '', $sortOrder));
+        $returnProperties[$sortCol] = 1;
       }
 
       $form->_includesSoftCredits = CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled($queryParams);
-      $query = new CRM_Contact_BAO_Query($queryParams, array('contribution_id'), NULL, FALSE, FALSE,
+      $query = new CRM_Contact_BAO_Query($queryParams, $returnProperties, NULL, FALSE, FALSE,
         CRM_Contact_BAO_Query::MODE_CONTRIBUTE
       );
       // @todo the function CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled should handle this
@@ -158,6 +162,7 @@ class CRM_Contribute_Form_Task extends CRM_Core_Form {
     }
 
     $form->_contributionIds = $form->_componentIds = $ids;
+    $form->set('contributionIds', $form->_contributionIds);
 
     //set the context for redirection for any task actions
     $session = CRM_Core_Session::singleton();
diff --git a/civicrm/CRM/Contribute/Form/UpdateBilling.php b/civicrm/CRM/Contribute/Form/UpdateBilling.php
index a46bb7a236762a099bec8dbfe61406aecfb85102..9852a1115dbf95396f15b9fcb0fab1c16304eccb 100644
--- a/civicrm/CRM/Contribute/Form/UpdateBilling.php
+++ b/civicrm/CRM/Contribute/Form/UpdateBilling.php
@@ -50,8 +50,6 @@ class CRM_Contribute_Form_UpdateBilling extends CRM_Core_Form {
    */
   public $_paymentProcessor = array();
 
-  public $_paymentProcessorObj = NULL;
-
   /**
    * Set variables up before form is built.
    */
@@ -60,7 +58,7 @@ class CRM_Contribute_Form_UpdateBilling extends CRM_Core_Form {
     $this->_crid = CRM_Utils_Request::retrieve('crid', 'Integer', $this, FALSE);
     if ($this->_crid) {
       $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'info');
-      $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'obj');
+      $this->_paymentProcessor['object'] = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'obj');
       $this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_crid);
 
       // Are we cancelling a recurring contribution that is linked to an auto-renew membership?
@@ -244,9 +242,7 @@ class CRM_Contribute_Form_UpdateBilling extends CRM_Core_Form {
     $processorParams['year'] = $processorParams['credit_card_exp_date']['Y'];
     $processorParams['subscriptionId'] = $this->_subscriptionDetails->subscription_id;
     $processorParams['amount'] = $this->_subscriptionDetails->amount;
-
-    $updateSubscription = $this->_paymentProcessorObj->updateSubscriptionBillingInfo($message, $processorParams);
-
+    $updateSubscription = $this->_paymentProcessor['object']->updateSubscriptionBillingInfo($message, $processorParams);
     if (is_a($updateSubscription, 'CRM_Core_Error')) {
       CRM_Core_Error::displaySessionError($updateSubscription);
     }
diff --git a/civicrm/CRM/Core/BAO/Dashboard.php b/civicrm/CRM/Core/BAO/Dashboard.php
index 91e560c6c7f5b5bfa72f18c75f1be8d72d92a76c..7fbfa07c70f45d0b9ddb1aabcef232042a41a628 100644
--- a/civicrm/CRM/Core/BAO/Dashboard.php
+++ b/civicrm/CRM/Core/BAO/Dashboard.php
@@ -431,31 +431,34 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
     $contactIDs = array();
     if ($admin) {
       $query = "SELECT distinct( contact_id )
-                        FROM civicrm_dashboard_contact
-                        WHERE contact_id NOT IN (
-                            SELECT distinct( contact_id )
-                            FROM civicrm_dashboard_contact WHERE dashboard_id = {$dashlet->id}
-                            )";
-
+                        FROM civicrm_dashboard_contact";
       $dao = CRM_Core_DAO::executeQuery($query);
       while ($dao->fetch()) {
-        $contactIDs[] = $dao->contact_id;
+        $contactIDs[$dao->contact_id] = NULL;
       }
     }
     else {
       //Get the id of Logged in User
-      $session = CRM_Core_Session::singleton();
-      $contactID = $session->get('userID');
+      $contactID = CRM_Core_Session::getLoggedInContactID();
       if (!empty($contactID)) {
-        $contactIDs[] = $session->get('userID');
+        $contactIDs[$contactID] = NULL;
       }
     }
 
+    // Remove contact ids that already have this dashlet to avoid DB
+    // constraint violation.
+    $query = "SELECT distinct( contact_id )
+              FROM civicrm_dashboard_contact WHERE dashboard_id = {$dashlet->id}";
+    $dao = CRM_Core_DAO::executeQuery($query);
+    while ($dao->fetch()) {
+      if (array_key_exists($dao->contact_id, $contactIDs)) {
+        unset($contactIDs[$dao->contact_id]);
+      }
+    }
     if (!empty($contactIDs)) {
-      foreach ($contactIDs as $contactID) {
+      foreach ($contactIDs as $contactID => $value) {
         $valuesArray[] = " ( {$dashlet->id}, {$contactID} )";
       }
-
       $valuesString = implode(',', $valuesArray);
       $query = "
                   INSERT INTO civicrm_dashboard_contact ( dashboard_id, contact_id )
diff --git a/civicrm/CRM/Core/BAO/WordReplacement.php b/civicrm/CRM/Core/BAO/WordReplacement.php
index 6f880fca6a1b5ceda71964dd672e24e9193d62c2..cef03ad579ef2c5b4af8938028339efd3b2b65e5 100644
--- a/civicrm/CRM/Core/BAO/WordReplacement.php
+++ b/civicrm/CRM/Core/BAO/WordReplacement.php
@@ -205,8 +205,9 @@ WHERE  domain_id = %1
   /**
    * Get word replacements for the api.
    *
-   * Get all the word-replacements stored in config-arrays
-   * and convert them to params for the WordReplacement.create API.
+   * Get all the word-replacements stored in config-arrays for the
+   * configured language, and convert them to params for the
+   * WordReplacement.create API.
    *
    * Note: This function is duplicated in CRM_Core_BAO_WordReplacement and
    * CRM_Upgrade_Incremental_php_FourFour to ensure that the incremental upgrade
@@ -222,6 +223,12 @@ WHERE  domain_id = %1
    * @see CRM_Core_BAO_WordReplacement::convertConfigArraysToAPIParams
    */
   public static function getConfigArraysAsAPIParams($rebuildEach) {
+    $settingsResult = civicrm_api3('Setting', 'get', array(
+      'return' => 'lcMessages',
+    ));
+    $returnValues = CRM_Utils_Array::first($settingsResult['values']);
+    $lang = $returnValues['lcMessages'];
+
     $wordReplacementCreateParams = array();
     // get all domains
     $result = civicrm_api3('domain', 'get', array(
@@ -236,19 +243,20 @@ WHERE  domain_id = %1
         $localeCustomArray = unserialize($value["locale_custom_strings"]);
         if (!empty($localeCustomArray)) {
           $wordMatchArray = array();
-          // Traverse Language array
-          foreach ($localeCustomArray as $localCustomData) {
-            // Traverse status array "enabled" "disabled"
-            foreach ($localCustomData as $status => $matchTypes) {
-              $params["is_active"] = ($status == "enabled") ? TRUE : FALSE;
-              // Traverse Match Type array "wildcardMatch" "exactMatch"
-              foreach ($matchTypes as $matchType => $words) {
-                $params["match_type"] = $matchType;
-                foreach ($words as $word => $replace) {
-                  $params["find_word"] = $word;
-                  $params["replace_word"] = $replace;
-                  $wordReplacementCreateParams[] = $params;
-                }
+          // Only return the replacement strings of the current language,
+          // otherwise some replacements will be duplicated, which will
+          // lead to undesired results, like CRM-19683.
+          $localCustomData = $localeCustomArray[$lang];
+          // Traverse status array "enabled" "disabled"
+          foreach ($localCustomData as $status => $matchTypes) {
+            $params["is_active"] = ($status == "enabled") ? TRUE : FALSE;
+            // Traverse Match Type array "wildcardMatch" "exactMatch"
+            foreach ($matchTypes as $matchType => $words) {
+              $params["match_type"] = $matchType;
+              foreach ($words as $word => $replace) {
+                $params["find_word"] = $word;
+                $params["replace_word"] = $replace;
+                $wordReplacementCreateParams[] = $params;
               }
             }
           }
diff --git a/civicrm/CRM/Core/DAO/AllCoreTables.data.php b/civicrm/CRM/Core/DAO/AllCoreTables.data.php
index 0dbf28032f9791919c233554a6a3c509ee114a5f..6f3b7e174add8a8ef72bbf333cfb118c52af22b1 100644
--- a/civicrm/CRM/Core/DAO/AllCoreTables.data.php
+++ b/civicrm/CRM/Core/DAO/AllCoreTables.data.php
@@ -24,7 +24,7 @@
 | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
 +--------------------------------------------------------------------+
 */
-// (GenCodeChecksum:89f332e5e88581181224fac51b45a1a4)
+// (GenCodeChecksum:adc57a6fcde47d2eeabf043734987a37)
 return array(
   'CRM_Core_DAO_AddressFormat' => array(
     'name' => 'AddressFormat',
diff --git a/civicrm/CRM/Core/DAO/StateProvince.php b/civicrm/CRM/Core/DAO/StateProvince.php
index a134384c1f6eb1e45f97a4511582ac5e1164ea3f..f5f037e88511df0c042b953098abe736b518b2ae 100644
--- a/civicrm/CRM/Core/DAO/StateProvince.php
+++ b/civicrm/CRM/Core/DAO/StateProvince.php
@@ -30,7 +30,7 @@
  *
  * Generated from xml/schema/CRM/Core/StateProvince.xml
  * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:c27dc7717825021cafc443d7d3244c8d)
+ * (GenCodeChecksum:70c072816098c4cbd13b7c13218c35e8)
  */
 require_once 'CRM/Core/DAO.php';
 require_once 'CRM/Utils/Type.php';
@@ -134,7 +134,7 @@ class CRM_Core_DAO_StateProvince extends CRM_Core_DAO {
         'country_id' => array(
           'name' => 'country_id',
           'type' => CRM_Utils_Type::T_INT,
-          'title' => ts('County') ,
+          'title' => ts('Country') ,
           'description' => 'ID of Country that State/Province belong',
           'required' => true,
           'FKClassName' => 'CRM_Core_DAO_Country',
diff --git a/civicrm/CRM/Core/Menu.php b/civicrm/CRM/Core/Menu.php
index 588bac05dbd4f7deca35ae09ca8685b9efc26a11..cc5c1bec0cb9dacd88af69a468f8dbc6a2c49a02 100644
--- a/civicrm/CRM/Core/Menu.php
+++ b/civicrm/CRM/Core/Menu.php
@@ -624,9 +624,11 @@ class CRM_Core_Menu {
   }
 
   /**
-   * @param $path
+   * @param $path string
+   *   Path of menu item to retrieve.
    *
-   * @return null
+   * @return array
+   *   Menu entry array.
    */
   public static function get($path) {
     // return null if menu rebuild
diff --git a/civicrm/CRM/Core/PseudoConstant.php b/civicrm/CRM/Core/PseudoConstant.php
index 344259f0d8ef493b8845b841df3c27a5c5b17213..71d514e313d0d7202328de31f4e301d2ade876ed 100644
--- a/civicrm/CRM/Core/PseudoConstant.php
+++ b/civicrm/CRM/Core/PseudoConstant.php
@@ -220,7 +220,7 @@ class CRM_Core_PseudoConstant {
     if (strpos($fieldName, 'custom_') === 0 && is_numeric($fieldName[7])) {
       $customField = new CRM_Core_BAO_CustomField();
       $customField->id = (int) substr($fieldName, 7);
-      $options = $customField->getOptions();
+      $options = $customField->getOptions($context);
       if ($options && $flip) {
         $options = array_flip($options);
       }
diff --git a/civicrm/CRM/Core/Resources.php b/civicrm/CRM/Core/Resources.php
index d998717d43612a7bd4fcf40a4eb860fcc988b35b..0e89d4c6766fb1ed1f37721ce91b617be9ffbd01 100644
--- a/civicrm/CRM/Core/Resources.php
+++ b/civicrm/CRM/Core/Resources.php
@@ -712,7 +712,6 @@ class CRM_Core_Resources {
       "bower_components/select2/select2.min.js",
       "bower_components/select2/select2.min.css",
       "bower_components/font-awesome/css/font-awesome.min.css",
-      "packages/jquery/plugins/jquery.tableHeader.js",
       "packages/jquery/plugins/jquery.form.min.js",
       "packages/jquery/plugins/jquery.timeentry.min.js",
       "packages/jquery/plugins/jquery.blockUI.min.js",
@@ -727,13 +726,18 @@ class CRM_Core_Resources {
     // add wysiwyg editor
     $editor = Civi::settings()->get('editor_id');
     if ($editor == "CKEditor") {
-      $items[] = "js/wysiwyg/crm.ckeditor.js";
       CRM_Admin_Page_CKEditorConfig::setConfigDefault();
-      $items[] = array('config' => array('CKEditorCustomConfig' => CRM_Admin_Page_CKEditorConfig::getConfigUrl()));
+      $items[] = array(
+        'config' => array(
+          'wysisygScriptLocation' => Civi::paths()->getUrl("[civicrm.root]/js/wysiwyg/crm.ckeditor.js"),
+          'CKEditorCustomConfig' => CRM_Admin_Page_CKEditorConfig::getConfigUrl(),
+        ),
+      );
     }
 
     // These scripts are only needed by back-office users
     if (CRM_Core_Permission::check('access CiviCRM')) {
+      $items[] = "packages/jquery/plugins/jquery.tableHeader.js";
       $items[] = "packages/jquery/plugins/jquery.menu.min.js";
       $items[] = "css/civicrmNavigation.css";
       $items[] = "packages/jquery/plugins/jquery.jeditable.min.js";
diff --git a/civicrm/CRM/Event/BAO/Query.php b/civicrm/CRM/Event/BAO/Query.php
index 4d3c728b66f777ce6cbe5a2b6d36a90fba8979ae..ba13d92bf0c27a30e25bee685f619b7402bb3b9e 100644
--- a/civicrm/CRM/Event/BAO/Query.php
+++ b/civicrm/CRM/Event/BAO/Query.php
@@ -410,6 +410,8 @@ class CRM_Event_BAO_Query extends CRM_Core_BAO_Query {
         $qillName = $name;
         $name = 'role_id';
 
+        $dataType = !empty($fields[$qillName]['type']) ? CRM_Utils_Type::typeToString($fields[$qillName]['type']) : 'String';
+        $tableName = empty($tableName) ? 'civicrm_participant' : $tableName;
         if (is_array($value) && in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) {
           $op = key($value);
           $value = $value[$op];
diff --git a/civicrm/CRM/Event/Controller/Search.php b/civicrm/CRM/Event/Controller/Search.php
index 1766ca46bb88116f4e83e080f0f4e97a461b7b07..fba7098485ac5acf659d9e1d445ae42fee2d5b1d 100644
--- a/civicrm/CRM/Event/Controller/Search.php
+++ b/civicrm/CRM/Event/Controller/Search.php
@@ -39,9 +39,9 @@
  *  - the search controller is used for building/processing multiform
  *    searches.
  *
- * Typically the first form will display the search criteria and it's results
+ * Typically the first form will display the search criteria and its results
  *
- * The second form is used to process search results with the asscociated actions
+ * The second form is used to process search results with the associated actions
  *
  */
 class CRM_Event_Controller_Search extends CRM_Core_Controller {
diff --git a/civicrm/CRM/Event/Form/Registration/Register.php b/civicrm/CRM/Event/Form/Registration/Register.php
index 9ec3fb30fc6728ef54d6535fe057fe22b1198916..0c8a4790b8de316f23953ed20d69b62ebcced5c6 100644
--- a/civicrm/CRM/Event/Form/Registration/Register.php
+++ b/civicrm/CRM/Event/Form/Registration/Register.php
@@ -803,9 +803,16 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
 
       $lineItem = array();
       CRM_Price_BAO_PriceSet::processAmount($self->_values['fee'], $fields, $lineItem);
+
+      $minAmt = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $fields['priceSetId'], 'min_amount');
       if ($fields['amount'] < 0) {
         $errors['_qf_default'] = ts('Event Fee(s) can not be less than zero. Please select the options accordingly');
       }
+      elseif (!empty($minAmt) && $fields['amount'] < $minAmt) {
+        $errors['_qf_default'] = ts('A minimum amount of %1 should be selected from Event Fee(s).', array(
+          1 => CRM_Utils_Money::format($minAmt),
+        ));
+      }
     }
 
     // @todo - can we remove the 'is_monetary' concept?
diff --git a/civicrm/CRM/Event/Page/AJAX.php b/civicrm/CRM/Event/Page/AJAX.php
index 60718f37a543b998d1dfb61e8a5a1f28f969bf85..7edc9c09ed8cca7b73a5af02525edc515fa60581 100644
--- a/civicrm/CRM/Event/Page/AJAX.php
+++ b/civicrm/CRM/Event/Page/AJAX.php
@@ -57,8 +57,8 @@ cv.label
 FROM civicrm_price_field_value cv
 LEFT JOIN civicrm_price_field cf ON cv.price_field_id = cf.id
 LEFT JOIN civicrm_price_set_entity ce ON ce.price_set_id = cf.price_set_id
-WHERE ce.entity_table = 'civicrm_event' AND {$whereClause}
-GROUP BY cv.label";
+WHERE ce.entity_table = 'civicrm_event' AND {$whereClause}";
+
     $dao = CRM_Core_DAO::executeQuery($query);
     $results = array();
     while ($dao->fetch()) {
diff --git a/civicrm/CRM/Export/BAO/Export.php b/civicrm/CRM/Export/BAO/Export.php
index 78db1701084b923ca5b0d8767f36be284c35621f..cd05826b1a3a7a43ce3b5b786d5a8951aa1df327 100644
--- a/civicrm/CRM/Export/BAO/Export.php
+++ b/civicrm/CRM/Export/BAO/Export.php
@@ -645,7 +645,7 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c
         $today = date('Ymd');
         $relationActive = " AND (crel.is_active = 1 AND ( crel.end_date is NULL OR crel.end_date >= {$today} ) )";
         $relationWhere = " WHERE contact_a.is_deleted = 0 {$relationshipClause} {$relationActive}";
-        $relationGroupBy = " GROUP BY crel.{$contactA}";
+        $relationGroupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($relationQuery[$rel]->_select, "crel.{$contactA}");
         $relationSelect = "{$relationSelect}, {$contactA} as refContact ";
         $relationQueryString = "$relationSelect $relationFrom $relationWhere $relationHaving $relationGroupBy";
 
diff --git a/civicrm/CRM/Grant/Controller/Search.php b/civicrm/CRM/Grant/Controller/Search.php
index 7514a7d6a309326c40fdf161e6222f58fea7d2b1..ed6e449afc05c2417e2da5167ca1733397de69e5 100644
--- a/civicrm/CRM/Grant/Controller/Search.php
+++ b/civicrm/CRM/Grant/Controller/Search.php
@@ -39,9 +39,9 @@
  *  - the search controller is used for building/processing multiform
  *    searches.
  *
- * Typically the first form will display the search criteria and it's results
+ * Typically the first form will display the search criteria and its results
  *
- * The second form is used to process search results with the asscociated actions
+ * The second form is used to process search results with the associated actions
  *
  */
 class CRM_Grant_Controller_Search extends CRM_Core_Controller {
diff --git a/civicrm/CRM/Mailing/BAO/Mailing.php b/civicrm/CRM/Mailing/BAO/Mailing.php
index a04124a4760c1033596214b393b4435338678670..19b7e774f12110ffcdd7e8c85761e83194046e92 100644
--- a/civicrm/CRM/Mailing/BAO/Mailing.php
+++ b/civicrm/CRM/Mailing/BAO/Mailing.php
@@ -538,23 +538,28 @@ WHERE  mailing_id = %1
       $params = array(1 => array($mailing_id, 'Integer'));
       CRM_Core_DAO::executeQuery($sql, $params);
 
+      $selectClause = array('%1', 'i.contact_id', "i.{$tempColumn}");
+      $select = "SELECT " . implode(', ', $selectClause);
       // CRM-3975
       $groupBy = $groupJoin = '';
+      $orderBy = "i.contact_id, i.{$tempColumn}";
       if ($dedupeEmail) {
+        $orderBy = "MIN(i.contact_id), MIN(i.{$tempColumn})";
         $groupJoin = " INNER JOIN civicrm_email e ON e.id = i.email_id";
         $groupBy = " GROUP BY e.email ";
+        $select = CRM_Contact_BAO_Query::appendAnyValueToSelect($selectClause, 'e.email');
       }
 
       $sql = "
 INSERT INTO civicrm_mailing_recipients ( mailing_id, contact_id, {$tempColumn} )
-SELECT %1, i.contact_id, i.{$tempColumn}
+{$select}
 FROM       civicrm_contact contact_a
 INNER JOIN I_$job_id i ON contact_a.id = i.contact_id
            $groupJoin
            {$aclFrom}
            {$aclWhere}
            $groupBy
-ORDER BY   i.contact_id, i.{$tempColumn}
+ORDER BY   {$orderBy}
 ";
 
       CRM_Core_DAO::executeQuery($sql, $params);
diff --git a/civicrm/CRM/Mailing/Event/BAO/Bounce.php b/civicrm/CRM/Mailing/Event/BAO/Bounce.php
index d0e005a3c07317d6dc69f4cb2bec96532b6e2549..84cdd4b27743fe4faced5f6f8cd674643da60a5c 100644
--- a/civicrm/CRM/Mailing/Event/BAO/Bounce.php
+++ b/civicrm/CRM/Mailing/Event/BAO/Bounce.php
@@ -238,7 +238,7 @@ class CRM_Mailing_Event_BAO_Bounce extends CRM_Mailing_Event_DAO_Bounce {
     }
 
     if ($is_distinct) {
-      $query .= " GROUP BY $queue.id ";
+      $query .= " GROUP BY $queue.id, $bounce.time_stamp, $bounce.bounce_reason, $bounceType.name ";
     }
 
     $orderBy = "sort_name ASC, {$bounce}.time_stamp DESC";
diff --git a/civicrm/CRM/Mailing/Event/BAO/Delivered.php b/civicrm/CRM/Mailing/Event/BAO/Delivered.php
index ee20d437b1f8aed4cfea61e26d5e6839fca7ee68..17bcaf0300c206b6259e2eed2fcce0c17f92bd9a 100644
--- a/civicrm/CRM/Mailing/Event/BAO/Delivered.php
+++ b/civicrm/CRM/Mailing/Event/BAO/Delivered.php
@@ -200,7 +200,7 @@ class CRM_Mailing_Event_BAO_Delivered extends CRM_Mailing_Event_DAO_Delivered {
     }
 
     if ($is_distinct) {
-      $query .= " GROUP BY $queue.id ";
+      $query .= " GROUP BY $queue.id, $delivered.id";
     }
 
     $orderBy = "sort_name ASC, {$delivered}.time_stamp DESC";
diff --git a/civicrm/CRM/Mailing/Event/BAO/Forward.php b/civicrm/CRM/Mailing/Event/BAO/Forward.php
index ea3faed8e582b226b1878b88591d64e793cb881f..3061d271ada0e913dfe0b39d696a9bf89a6bb34e 100644
--- a/civicrm/CRM/Mailing/Event/BAO/Forward.php
+++ b/civicrm/CRM/Mailing/Event/BAO/Forward.php
@@ -339,10 +339,10 @@ class CRM_Mailing_Event_BAO_Forward extends CRM_Mailing_Event_DAO_Forward {
     }
 
     if ($is_distinct) {
-      $query .= " GROUP BY $queue.id ";
+      $query .= " GROUP BY $queue.id, dest_contact.id, dest_email.email, $forward.time_stamp ";
     }
 
-    $orderBy = "sort_name ASC, {$forward}.time_stamp DESC";
+    $orderBy = "$contact.sort_name ASC, {$forward}.time_stamp DESC";
     if ($sort) {
       if (is_string($sort)) {
         $sort = CRM_Utils_Type::escape($sort, 'String');
diff --git a/civicrm/CRM/Mailing/Event/BAO/Opened.php b/civicrm/CRM/Mailing/Event/BAO/Opened.php
index 451e8b9b90436e11e7618ecfdf01d70a141aa0a1..3e8eda136c7ccc1655fa2e2d5f8b990770940e27 100644
--- a/civicrm/CRM/Mailing/Event/BAO/Opened.php
+++ b/civicrm/CRM/Mailing/Event/BAO/Opened.php
@@ -267,7 +267,7 @@ class CRM_Mailing_Event_BAO_Opened extends CRM_Mailing_Event_DAO_Opened {
     }
 
     if ($is_distinct) {
-      $query .= " GROUP BY $queue.id ";
+      $query .= " GROUP BY $queue.id, $open.time_stamp ";
     }
 
     $orderBy = "sort_name ASC, {$open}.time_stamp DESC";
diff --git a/civicrm/CRM/Mailing/Event/BAO/Reply.php b/civicrm/CRM/Mailing/Event/BAO/Reply.php
index 6a8e7a8c16e876a0e566f81ee8c18b0526875e3a..57a5da2b27bb59f5b0be8b3ff7008069200037fd 100644
--- a/civicrm/CRM/Mailing/Event/BAO/Reply.php
+++ b/civicrm/CRM/Mailing/Event/BAO/Reply.php
@@ -403,7 +403,7 @@ class CRM_Mailing_Event_BAO_Reply extends CRM_Mailing_Event_DAO_Reply {
     }
 
     if ($is_distinct) {
-      $query .= " GROUP BY $queue.id ";
+      $query .= " GROUP BY $queue.id, $contact.id, $reply.time_stamp ";
     }
 
     $orderBy = "sort_name ASC, {$reply}.time_stamp DESC";
diff --git a/civicrm/CRM/Mailing/Event/BAO/TrackableURLOpen.php b/civicrm/CRM/Mailing/Event/BAO/TrackableURLOpen.php
index 94e05b2e7cd57e05656d3da3a2e014a05df3f7ff..1b765e5740a352699ea1501ae4d525fcb22457e0 100644
--- a/civicrm/CRM/Mailing/Event/BAO/TrackableURLOpen.php
+++ b/civicrm/CRM/Mailing/Event/BAO/TrackableURLOpen.php
@@ -337,7 +337,7 @@ class CRM_Mailing_Event_BAO_TrackableURLOpen extends CRM_Mailing_Event_DAO_Track
     }
 
     if ($is_distinct) {
-      $query .= " GROUP BY $queue.id ";
+      $query .= " GROUP BY $queue.id, $click.time_stamp, $url.url ";
     }
 
     $orderBy = "sort_name ASC, {$click}.time_stamp DESC";
diff --git a/civicrm/CRM/Mailing/Event/BAO/Unsubscribe.php b/civicrm/CRM/Mailing/Event/BAO/Unsubscribe.php
index 71171d1f1b4a8903a5913db98c4d2a585b65ad6d..290b3e90ae129b0578d2b6166383ff2ffa7d568a 100644
--- a/civicrm/CRM/Mailing/Event/BAO/Unsubscribe.php
+++ b/civicrm/CRM/Mailing/Event/BAO/Unsubscribe.php
@@ -549,7 +549,7 @@ WHERE  email = %2
     }
 
     if ($is_distinct) {
-      $query .= " GROUP BY $queue.id ";
+      $query .= " GROUP BY $queue.id, $unsub.time_stamp, $unsub.org_unsubscribe";
     }
 
     $orderBy = "sort_name ASC, {$unsub}.time_stamp DESC";
diff --git a/civicrm/CRM/Member/Controller/Search.php b/civicrm/CRM/Member/Controller/Search.php
index 46b46a4f6dc5deb17f6dbf4e1e270d1224caa60b..15c909b739fcff20c4b4dd69f713b94a8b0f6012 100644
--- a/civicrm/CRM/Member/Controller/Search.php
+++ b/civicrm/CRM/Member/Controller/Search.php
@@ -39,9 +39,9 @@
  *  - the search controller is used for building/processing multiform
  *    searches.
  *
- * Typically the first form will display the search criteria and it's results
+ * Typically the first form will display the search criteria and its results
  *
- * The second form is used to process search results with the asscociated actions
+ * The second form is used to process search results with the associated actions
  *
  */
 class CRM_Member_Controller_Search extends CRM_Core_Controller {
diff --git a/civicrm/CRM/Member/Form/Task/Label.php b/civicrm/CRM/Member/Form/Task/Label.php
index d888c1bb4a1c7dce5672170bd51a33fac534ea26..f6d252f97d4007e21f46a1f3117cac73baba1b74 100644
--- a/civicrm/CRM/Member/Form/Task/Label.php
+++ b/civicrm/CRM/Member/Form/Task/Label.php
@@ -57,7 +57,7 @@ class CRM_Member_Form_Task_Label extends CRM_Member_Form_Task {
    * @return void
    */
   public function buildQuickForm() {
-    CRM_Contact_Form_Task_Label::buildQuickForm($this);
+    CRM_Contact_Form_Task_Label::buildLabelForm($this);
     $this->addElement('checkbox', 'per_membership', ts('Print one label per Membership (rather than per contact)'));
   }
 
diff --git a/civicrm/CRM/PCP/Controller/PCP.php b/civicrm/CRM/PCP/Controller/PCP.php
index 4561c90e5bd8d504a935324a52dba21045457a4d..c303d6b481e46acc4d55d14557fc59923a957926 100644
--- a/civicrm/CRM/PCP/Controller/PCP.php
+++ b/civicrm/CRM/PCP/Controller/PCP.php
@@ -39,9 +39,9 @@
  *  - the search controller is used for building/processing multiform
  *    searches.
  *
- * Typically the first form will display the search criteria and it's results
+ * Typically the first form will display the search criteria and its results
  *
- * The second form is used to process search results with the asscociated actions
+ * The second form is used to process search results with the associated actions
  *
  */
 class CRM_PCP_Controller_PCP extends CRM_Core_Controller {
diff --git a/civicrm/CRM/Pledge/BAO/Pledge.php b/civicrm/CRM/Pledge/BAO/Pledge.php
index c8594c0618a0506bad53d66a75746c6e7ed051ab..6e5371c793c4b58aef7b7a77804035aad0873572 100644
--- a/civicrm/CRM/Pledge/BAO/Pledge.php
+++ b/civicrm/CRM/Pledge/BAO/Pledge.php
@@ -154,7 +154,6 @@ class CRM_Pledge_BAO_Pledge extends CRM_Pledge_DAO_Pledge {
     $transaction = new CRM_Core_Transaction();
 
     $paymentParams = array();
-    $paymentParams['status_id'] = CRM_Utils_Array::value('status_id', $params);
     if (!empty($params['installment_amount'])) {
       $params['amount'] = $params['installment_amount'] * $params['installments'];
     }
@@ -174,6 +173,7 @@ class CRM_Pledge_BAO_Pledge extends CRM_Pledge_DAO_Pledge {
         }
       }
     }
+    $paymentParams['status_id'] = CRM_Utils_Array::value('status_id', $params);
 
     $pledge = self::add($params);
     if (is_a($pledge, 'CRM_Core_Error')) {
diff --git a/civicrm/CRM/Pledge/Controller/Search.php b/civicrm/CRM/Pledge/Controller/Search.php
index e5004478b81e9c8ea5493af3a21f32811524c5f8..f5743ce44929fcd0158531f7ec7ba42448fc9934 100644
--- a/civicrm/CRM/Pledge/Controller/Search.php
+++ b/civicrm/CRM/Pledge/Controller/Search.php
@@ -37,9 +37,9 @@
  *  - the search controller is used for building/processing multiform
  *    searches.
  *
- * Typically the first form will display the search criteria and it's results.
+ * Typically the first form will display the search criteria and its results.
  *
- * The second form is used to process search results with the asscociated actions.
+ * The second form is used to process search results with the associated actions.
  */
 class CRM_Pledge_Controller_Search extends CRM_Core_Controller {
 
diff --git a/civicrm/CRM/Pledge/Form/Pledge.php b/civicrm/CRM/Pledge/Form/Pledge.php
index 555c4b0a4fb258c5e821d21f2ed9d6a2d0a091cc..0c5758d2756a1739c3f440c7d10d1e0d695021af 100644
--- a/civicrm/CRM/Pledge/Form/Pledge.php
+++ b/civicrm/CRM/Pledge/Form/Pledge.php
@@ -352,11 +352,17 @@ class CRM_Pledge_Form_Pledge extends CRM_Core_Form {
       $this->addDate('start_date', ts('Payments Start'), TRUE);
     }
 
+    if (!empty($this->_values['currency'])) {
+      $this->assign('currency', $this->_values['currency']);
+    }
+    elseif (!empty($this->_submitValues['currency'])) {
+      $this->assign('currency', $this->_submitValues['currency']);
+    }
+
     if ($this->_id &&
       !$this->_isPending
     ) {
       $eachPaymentAmount = $this->_values['original_installment_amount'];
-      $this->assign('currency', $this->_values['currency']);
       $this->assign('eachPaymentAmount', $eachPaymentAmount);
       $this->assign('hideCalender', TRUE);
     }
diff --git a/civicrm/CRM/Price/BAO/PriceSet.php b/civicrm/CRM/Price/BAO/PriceSet.php
index 36dc1dcd16a0262eee0d18ddc72236c9812e547a..83f7c51467ceddf71bb8be54ece6e23f2a0fb7fb 100644
--- a/civicrm/CRM/Price/BAO/PriceSet.php
+++ b/civicrm/CRM/Price/BAO/PriceSet.php
@@ -592,7 +592,7 @@ AND ( expire_on IS NULL OR expire_on >= {$currentTime} )
 
     // also get the pre and post help from this price set
     $sql = "
-SELECT extends, financial_type_id, help_pre, help_post, is_quick_config
+SELECT extends, financial_type_id, help_pre, help_post, is_quick_config, min_amount
 FROM   civicrm_price_set
 WHERE  id = %1";
     $dao = CRM_Core_DAO::executeQuery($sql, $params);
@@ -602,6 +602,7 @@ WHERE  id = %1";
       $setTree[$setID]['help_pre'] = $dao->help_pre;
       $setTree[$setID]['help_post'] = $dao->help_post;
       $setTree[$setID]['is_quick_config'] = $dao->is_quick_config;
+      $setTree[$setID]['min_amount'] = $dao->min_amount;
     }
     return $setTree;
   }
diff --git a/civicrm/CRM/Price/DAO/PriceSet.php b/civicrm/CRM/Price/DAO/PriceSet.php
index bda7ba9467aa92cce876464edcc746b8b3478798..f07500a2bd45e62ecdc27aed5e91e1c3b189499d 100644
--- a/civicrm/CRM/Price/DAO/PriceSet.php
+++ b/civicrm/CRM/Price/DAO/PriceSet.php
@@ -30,7 +30,7 @@
  *
  * Generated from xml/schema/CRM/Price/PriceSet.xml
  * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:cf1125145d52414335549f50501ff5fc)
+ * (GenCodeChecksum:1642f2b38411573c40848c0d7c83c74c)
  */
 require_once 'CRM/Core/DAO.php';
 require_once 'CRM/Utils/Type.php';
@@ -120,6 +120,12 @@ class CRM_Price_DAO_PriceSet extends CRM_Core_DAO {
    * @var boolean
    */
   public $is_reserved;
+  /**
+   * Minimum Amount required for this set.
+   *
+   * @var int unsigned
+   */
+  public $min_amount;
   /**
    * class constructor
    *
@@ -292,6 +298,15 @@ class CRM_Price_DAO_PriceSet extends CRM_Core_DAO {
             'type' => 'CheckBox',
           ) ,
         ) ,
+        'min_amount' => array(
+          'name' => 'min_amount',
+          'type' => CRM_Utils_Type::T_INT,
+          'title' => ts('Minimum Amount') ,
+          'description' => 'Minimum Amount required for this set.',
+          'html' => array(
+            'type' => 'Text',
+          ) ,
+        ) ,
       );
       CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
     }
diff --git a/civicrm/CRM/Price/Form/Set.php b/civicrm/CRM/Price/Form/Set.php
index 90d9be60fd3ce1e5ac5f25b22fd3927acbcb6826..1e689ecfa2d4baea39664909da5e278cbb2d2b4c 100644
--- a/civicrm/CRM/Price/Form/Set.php
+++ b/civicrm/CRM/Price/Form/Set.php
@@ -183,6 +183,8 @@ class CRM_Price_Form_Set extends CRM_Core_Form {
       }
     }
 
+    $this->addElement('text', 'min_amount', ts('Minimum Amount'));
+
     if (CRM_Utils_System::isNull($extends)) {
       $this->assign('extends', FALSE);
     }
diff --git a/civicrm/CRM/Profile/Page/MultipleRecordFieldsListing.php b/civicrm/CRM/Profile/Page/MultipleRecordFieldsListing.php
index 7ad6318131862d0b67dacbe8200102bde5a06837..3b22b56cf5aa42d80feaa5d3bf869e8c29004569 100644
--- a/civicrm/CRM/Profile/Page/MultipleRecordFieldsListing.php
+++ b/civicrm/CRM/Profile/Page/MultipleRecordFieldsListing.php
@@ -167,7 +167,7 @@ class CRM_Profile_Page_MultipleRecordFieldsListing extends CRM_Core_Page_Basic {
    */
   public function browse() {
     $dateFields = NULL;
-    $cgcount = 0;
+    $newCgCount = $cgcount = 0;
     $attributes = $result = $headerAttr = array();
     $dateFieldsVals = NULL;
     if ($this->_pageViewType == 'profileDataView' && $this->_profileId) {
@@ -259,7 +259,7 @@ class CRM_Profile_Page_MultipleRecordFieldsListing extends CRM_Core_Page_Basic {
       $linkAction = array_sum(array_keys($this->links()));
     }
 
-    if (!empty($fieldIDs) && $this->_contactId && empty($this->_headersOnly)) {
+    if (!empty($fieldIDs) && $this->_contactId) {
       $DTparams = !empty($this->_DTparams) ? $this->_DTparams : NULL;
       // commonly used for both views i.e profile listing view (profileDataView) and custom data listing view (customDataView)
       $result = CRM_Core_BAO_CustomValueTable::getEntityValues($this->_contactId, NULL, $fieldIDs, TRUE, $DTparams);
@@ -288,7 +288,8 @@ class CRM_Profile_Page_MultipleRecordFieldsListing extends CRM_Core_Page_Basic {
       // $cgcount is defined before 'if' condition as entity may have no record
       // and $cgcount is used to build new record url
       $cgcount = 1;
-      if ($result && !empty($result)) {
+      $newCgCount = (!$reached) ? $resultCount + 1 : NULL;
+      if (!empty($result) && empty($this->_headersOnly)) {
         $links = self::links();
         if ($this->_pageViewType == 'profileDataView') {
           $pageCheckSum = $this->get('pageCheckSum');
@@ -302,7 +303,6 @@ class CRM_Profile_Page_MultipleRecordFieldsListing extends CRM_Core_Page_Basic {
         if ($reached) {
           unset($links[CRM_Core_Action::COPY]);
         }
-        $newCgCount = (!$reached) ? $resultCount + 1 : NULL;
         if (!empty($DTparams)) {
           $this->_total = $resultCount;
           $cgcount = $DTparams['offset'] + 1;
@@ -452,6 +452,7 @@ class CRM_Profile_Page_MultipleRecordFieldsListing extends CRM_Core_Page_Basic {
     $this->assign('dateFields', $dateFields);
     $this->assign('dateFieldsVals', $dateFieldsVals);
     $this->assign('cgcount', $cgcount);
+    $this->assign('newCgCount', $newCgCount);
     $this->assign('contactId', $this->_contactId);
     $this->assign('contactType', $this->_contactType);
     $this->assign('customGroupTitle', $this->_customGroupTitle);
diff --git a/civicrm/CRM/Report/Form/Contribute/Bookkeeping.php b/civicrm/CRM/Report/Form/Contribute/Bookkeeping.php
index 34bdb94f23e90a43abff6bfa5de31ee2edcd8504..ab94313f8e066aba4373dabcf230a7b3d4b82b0d 100644
--- a/civicrm/CRM/Report/Form/Contribute/Bookkeeping.php
+++ b/civicrm/CRM/Report/Form/Contribute/Bookkeeping.php
@@ -335,6 +335,12 @@ class CRM_Report_Form_Contribute_Bookkeeping extends CRM_Report_Form {
             'operatorType' => CRM_Report_Form::OP_DATE,
             'type' => CRM_Utils_Type::T_DATE,
           ),
+          'status_id' => array(
+            'title' => ts('Financial Transaction Status'),
+            'operatorType' => CRM_Report_Form::OP_MULTISELECT,
+            'options' => CRM_Contribute_PseudoConstant::contributionStatus(),
+            'default' => array(1),
+          ),
         ),
         'order_bys' => array(
           'payment_instrument_id' => array('title' => ts('Payment Method')),
diff --git a/civicrm/CRM/Report/Utils/Get.php b/civicrm/CRM/Report/Utils/Get.php
index 8669159425a3b3c5277e1610f7a99c0157a0c42d..21005661f3fe1926cc8ea5e6e0108fed28c0571a 100644
--- a/civicrm/CRM/Report/Utils/Get.php
+++ b/civicrm/CRM/Report/Utils/Get.php
@@ -66,9 +66,12 @@ class CRM_Report_Utils_Get {
     $from = self::getTypedValue("{$fieldName}_from", $type);
     $to = self::getTypedValue("{$fieldName}_to", $type);
 
-    $relative = CRM_Utils_Array::value("{$fieldName}_relative", $_GET);
+    $relative = self::getTypedValue("{$fieldName}_relative", CRM_Utils_Type::T_STRING);
+    if ($relative !== NULL) {
+      $defaults["{$fieldName}_relative"] = $relative;
+    }
     if ($relative) {
-      list($from, $to) = CRM_Report_Form::getFromTo($relative, NULL, NULL);
+      list($from, $to) = CRM_Utils_Date::getFromTo($relative, NULL, NULL);
       $from = substr($from, 0, 8);
       $to = substr($to, 0, 8);
     }
diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.7.15.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.7.15.mysql.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..4ac2399c60a67f868a9eb52c43633b1cbf1b105c
--- /dev/null
+++ b/civicrm/CRM/Upgrade/Incremental/sql/4.7.15.mysql.tpl
@@ -0,0 +1,7 @@
+{* file to handle db changes in 4.7.15 during upgrade *}
+
+-- CRM-19685 (fix for inconsistencies)
+UPDATE civicrm_contact SET preferred_mail_format = 'Both' WHERE preferred_mail_format IS NULL;
+
+-- CRM-19626
+ALTER TABLE civicrm_price_set ADD min_amount INT(10) UNSIGNED DEFAULT '0' COMMENT 'Minimum Amount required for this set.';
diff --git a/civicrm/CRM/Utils/Migrate/Import.php b/civicrm/CRM/Utils/Migrate/Import.php
index 927f82385c6a4f5b502379043dc930ba7f13c171..912e5f1b8bfda3657bfc5d11b9a61c34aa47c290 100644
--- a/civicrm/CRM/Utils/Migrate/Import.php
+++ b/civicrm/CRM/Utils/Migrate/Import.php
@@ -155,6 +155,10 @@ class CRM_Utils_Migrate_Import {
       foreach ($optionValuesXML->OptionValue as $optionValueXML) {
         $optionValue = new CRM_Core_DAO_OptionValue();
         $optionValue->option_group_id = $idMap['option_group'][(string ) $optionValueXML->option_group_name];
+        if (empty($optionValue->option_group_id)) {
+          //CRM-17410 check if option group already exist.
+          $optionValue->option_group_id = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', $optionValueXML->option_group_name, 'id', 'name');
+        }
         $this->copyData($optionValue, $optionValueXML, FALSE, 'label');
         if (!isset($optionValue->value)) {
           $sql = "
diff --git a/civicrm/CRM/Utils/QueryFormatter.php b/civicrm/CRM/Utils/QueryFormatter.php
index 4f61473dc2f546f925ec94ab1387ce13b563172c..8514bf3af434160478fc30ef8871b7f24c8eb65c 100644
--- a/civicrm/CRM/Utils/QueryFormatter.php
+++ b/civicrm/CRM/Utils/QueryFormatter.php
@@ -287,6 +287,20 @@ class CRM_Utils_QueryFormatter {
    */
   protected function _formatFtsBool($text, $mode) {
     $result = NULL;
+    $operators = array('+', '-', '~', '(', ')');
+    $wildCards = array('@', '%', '*');
+    $expression = preg_quote(implode('', array_merge($operators, $wildCards)), '/');
+
+    //Return if searched string ends with an unsupported operator.
+    //Or if the string contains an invalid joint occurrence of operators.
+    foreach ($operators as $val) {
+      if ($text == '@' || CRM_Utils_String::endsWith($text, $val) || preg_match("/[{$expression}]{2,}/", $text)) {
+        $csid = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', 'CRM_Contact_Form_Search_Custom_FullText', 'value', 'name');
+        $url = CRM_Utils_System::url("civicrm/contact/search/custom", "csid={$csid}&reset=1");
+        $operators = implode("', '", $operators);
+        CRM_Core_Error::statusBounce("Full-Text Search does not support the use of a search with two attached operators or string ending with any of these operators ('{$operators}' or a single '@'). Please adjust your search term and try again.", $url, 'Invalid Search String');
+      }
+    }
 
     // normalize user-inputted wildcards
     $text = str_replace('%', '*', $text);
@@ -309,7 +323,7 @@ class CRM_Utils_QueryFormatter {
     else {
       switch ($mode) {
         case self::MODE_NONE:
-          $result = $this->mapWords($text, '+word');
+          $result = $this->mapWords($text, '+word', TRUE);
           break;
 
         case self::MODE_PHRASE:
@@ -380,11 +394,13 @@ class CRM_Utils_QueryFormatter {
    *   User-supplied query string.
    * @param string $template
    *   A prototypical description of each word, eg "word%" or "word*" or "*word*".
+   * @param bool $quotes
+   *   True if each searched keyword need to be surrounded with quotes.
    * @return string
    */
-  protected function mapWords($text, $template) {
+  protected function mapWords($text, $template, $quotes = FALSE) {
     $result = array();
-    foreach ($this->parseWords($text) as $word) {
+    foreach ($this->parseWords($text, $quotes) as $word) {
       $result[] = str_replace('word', $word, $template);
     }
     return implode(' ', $result);
@@ -392,9 +408,10 @@ class CRM_Utils_QueryFormatter {
 
   /**
    * @param $text
+   * @bool $quotes
    * @return array
    */
-  protected function parseWords($text) {
+  protected function parseWords($text, $quotes) {
     //NYSS 9692 special handling for emails
     if (preg_match('/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/', $text)) {
       $parts = explode('@', $text);
@@ -403,7 +420,19 @@ class CRM_Utils_QueryFormatter {
     }
 
     //NYSS also replace other occurrences of @
-    return explode(' ', preg_replace('/[ \r\n\t\@]+/', ' ', trim($text)));
+    $replacedText = preg_replace('/[ \r\n\t\@]+/', ' ', trim($text));
+    //filter empty values if any
+    $keywords = array_filter(explode(' ', $replacedText));
+
+    //Ensure each searched keywords are wrapped in double quotes.
+    if ($quotes) {
+      foreach ($keywords as &$val) {
+        if (!is_numeric($val)) {
+          $val = "\"{$val}\"";
+        }
+      }
+    }
+    return $keywords;
   }
 
   /**
diff --git a/civicrm/CRM/Utils/System/Drupal.php b/civicrm/CRM/Utils/System/Drupal.php
index 8beb99405cd36012fe2d7d8bea3267a0c0b83c14..646b9250f45644feeb71f9ba32b7d7112c7a0456 100644
--- a/civicrm/CRM/Utils/System/Drupal.php
+++ b/civicrm/CRM/Utils/System/Drupal.php
@@ -162,8 +162,8 @@ class CRM_Utils_System_Drupal extends CRM_Utils_System_DrupalBase {
    * @inheritDoc
    */
   public function getLoginURL($destination = '') {
-    $query = $destination ? array('destination' => $destination) : array();
-    return url('user', array('query' => $query), TRUE);
+    $query = $destination ? array('destination' => $destination) : NULL;
+    return CRM_Utils_System::url('user', $query, TRUE);
   }
 
   /**
diff --git a/civicrm/api/v3/StateProvince.php b/civicrm/api/v3/StateProvince.php
new file mode 100644
index 0000000000000000000000000000000000000000..d363f27ea3806122c6aa28ed4e6fa12bcdaa22a1
--- /dev/null
+++ b/civicrm/api/v3/StateProvince.php
@@ -0,0 +1,84 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.7                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2016                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM 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 Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * This api exposes CiviCRM states/provinces
+ *
+ * @package CiviCRM_APIv3
+ */
+
+/**
+ * Add a state/province.
+ *
+ * @param array $params
+ *   Array per getfields metadata.
+ *
+ * @return array
+ *   API result array
+ * @throws \API_Exception
+ */
+function civicrm_api3_state_province_create($params) {
+  return _civicrm_api3_basic_create(_civicrm_api3_get_DAO(__FUNCTION__), $params);
+}
+
+/**
+ * Adjust Metadata for Create action.
+ *
+ * The metadata is used for setting defaults, documentation & validation.
+ *
+ * @param array $params
+ *   Array of parameters determined by getfields.
+ */
+function _civicrm_api3_state_province_create_spec(&$params) {
+  $params['name']['api.required'] = 1;
+  $params['country_id']['api.required'] = 1;
+  $params['abbreviation']['api.required'] = 1;
+}
+
+/**
+ * Deletes an existing state/province.
+ *
+ * @param array $params
+ *
+ * @return array
+ */
+function civicrm_api3_state_province_delete($params) {
+  return _civicrm_api3_basic_delete(_civicrm_api3_get_DAO(__FUNCTION__), $params);
+}
+
+/**
+ * Retrieve one or more states/provinces.
+ *
+ * @param array $params
+ *   Array per getfields metadata.
+ *
+ * @return array
+ *   api result array
+ */
+function civicrm_api3_state_province_get($params) {
+  return _civicrm_api3_basic_get(_civicrm_api3_get_DAO(__FUNCTION__), $params);
+}
diff --git a/civicrm/api/v3/utils.php b/civicrm/api/v3/utils.php
index 1d9c82a2366093c0157acd91143340553b488332..ddf19f85ea136efda8f98ff89e18a89fb0cef019 100644
--- a/civicrm/api/v3/utils.php
+++ b/civicrm/api/v3/utils.php
@@ -813,12 +813,6 @@ function _civicrm_api3_get_options_from_params(&$params, $queryObject = FALSE, $
       $returnProperties[$lowercase_entity . '_id'] = 1;
       unset($returnProperties['id']);
     }
-    switch (trim(strtolower($sort))) {
-      case 'id':
-      case 'id desc':
-      case 'id asc':
-        $sort = str_replace('id', $lowercase_entity . '_id', $sort);
-    }
   }
 
   $options = array(
@@ -833,6 +827,14 @@ function _civicrm_api3_get_options_from_params(&$params, $queryObject = FALSE, $
   if (!empty($sort)) {
     foreach ((array) $sort as $s) {
       if (CRM_Utils_Rule::mysqlOrderBy($s)) {
+        if ($entity && $action == 'get') {
+          switch (trim(strtolower($s))) {
+            case 'id':
+            case 'id desc':
+            case 'id asc':
+              $s = str_replace('id', $lowercase_entity . '_id', $s);
+          }
+        }
         $finalSort[] = $s;
       }
       else {
@@ -1635,7 +1637,7 @@ function _civicrm_api3_validate_foreign_keys($entity, $action, &$params, $fields
         _civicrm_api3_validate_constraint($params[$fieldName], $fieldName, $fieldInfo);
       }
       elseif (!empty($fieldInfo['required'])) {
-        throw new Exception("DB Constraint Violation - possibly $fieldName should possibly be marked as mandatory for this API. If so, please raise a bug report.");
+        throw new Exception("DB Constraint Violation - $fieldName should possibly be marked as mandatory for $entity,$action API. If so, please raise a bug report.");
       }
     }
     if (!empty($fieldInfo['api.unique'])) {
diff --git a/civicrm/bower_components/select2/.bower.json b/civicrm/bower_components/select2/.bower.json
index 90d969c82bece5b61e8f30b6350bfbe308e77023..1e2fc6272cc9c766546a45e3feecc1f2010dfd88 100644
--- a/civicrm/bower_components/select2/.bower.json
+++ b/civicrm/bower_components/select2/.bower.json
@@ -11,11 +11,11 @@
     "jquery": ">= 1.7.1"
   },
   "homepage": "https://github.com/colemanw/select2",
-  "_release": "8bcec8afd1",
+  "_release": "90d4b9ee38",
   "_resolution": {
     "type": "branch",
     "branch": "stable/3.5",
-    "commit": "8bcec8afd14a35807ae8582a1d9c45280370376a"
+    "commit": "90d4b9ee388b33e17c9f58a2866a4765f00b9a55"
   },
   "_source": "https://github.com/colemanw/select2.git",
   "_target": "stable/3.5",
diff --git a/civicrm/bower_components/select2/select2.js b/civicrm/bower_components/select2/select2.js
index d0e06ab022e2b90ac024689614e7ece38d88ae9c..066e2d953e8fd79a3b780aa2b5ff702f39d1ff9f 100644
--- a/civicrm/bower_components/select2/select2.js
+++ b/civicrm/bower_components/select2/select2.js
@@ -2441,9 +2441,16 @@ the specific language governing permissions and limitations under the Apache Lic
             // hide the search box if this is the first we got the results and there are enough of them for search
 
             if (initial === true) {
-                var min = this.opts.minimumResultsForSearch;
+                var resultCount = 0, min = this.opts.minimumResultsForSearch;
+                if ($(this.opts.element).is('select')) {
+                    resultCount = $('option', this.opts.element).length;
+                }
+		else {
+                    resultCount = countResults(data.results);
+                }
+
                 if (min >= 0) {
-                    this.showSearch(countResults(data.results) >= min);
+                    this.showSearch(resultCount >= min);
                 }
             }
         },
diff --git a/civicrm/bower_components/select2/select2.min.js b/civicrm/bower_components/select2/select2.min.js
index efee1adfffa5f5ffcfdafba55e778b6eb410cb39..a526f1bf4328c51abfbdfd8ad275674d0ed90112 100644
--- a/civicrm/bower_components/select2/select2.min.js
+++ b/civicrm/bower_components/select2/select2.min.js
@@ -1,3 +1,2 @@
-!function(a){"undefined"==typeof a.fn.each2&&a.extend(a.fn,{each2:function(b){for(var c=a([0]),d=-1,e=this.length;++d<e&&(c.context=c[0]=this[d])&&b.call(c[0],d,c)!==!1;);return this}})}(jQuery),function(a,b){"use strict";function n(b){var c=a(document.createTextNode(""));b.before(c),c.before(b),c.remove()}function o(a){function b(a){return m[a]||a}return a.replace(/[^\u0000-\u007E]/g,b)}function p(a,b){for(var c=0,d=b.length;d>c;c+=1)if(r(a,b[c]))return c;return-1}function q(){var b=a(l);b.appendTo(document.body);var c={width:b.width()-b[0].clientWidth,height:b.height()-b[0].clientHeight};return b.remove(),c}function r(a,c){return a===c?!0:a===b||c===b?!1:null===a||null===c?!1:a.constructor===String?a+""==c+"":c.constructor===String?c+""==a+"":!1}function s(a,b,c){var d,e,f;if(null===a||a.length<1)return[];for(d=a.split(b),e=0,f=d.length;f>e;e+=1)d[e]=c(d[e]);return d}function t(a){return a.outerWidth(!1)-a.width()}function u(c){var d="keyup-change-value";c.on("keydown",function(){a.data(c,d)===b&&a.data(c,d,c.val())}),c.on("keyup",function(){var e=a.data(c,d);e!==b&&c.val()!==e&&(a.removeData(c,d),c.trigger("keyup-change"))})}function v(c){c.on("mousemove",function(c){var d=h;(d===b||d.x!==c.pageX||d.y!==c.pageY)&&a(c.target).trigger("mousemove-filtered",c)})}function w(a,c,d){d=d||b;var e;return function(){var b=arguments;window.clearTimeout(e),e=window.setTimeout(function(){c.apply(d,b)},a)}}function x(a,b){var c=w(a,function(a){b.trigger("scroll-debounced",a)});b.on("scroll",function(a){p(a.target,b.get())>=0&&c(a)})}function y(a){a[0]!==document.activeElement&&window.setTimeout(function(){var d,b=a[0],c=a.val().length;a.focus();var e=b.offsetWidth>0||b.offsetHeight>0;e&&b===document.activeElement&&(b.setSelectionRange?b.setSelectionRange(c,c):b.createTextRange&&(d=b.createTextRange(),d.collapse(!1),d.select()))},0)}function z(b){b=a(b)[0];var c=0,d=0;if("selectionStart"in b)c=b.selectionStart,d=b.selectionEnd-c;else if("selection"in document){b.focus();var e=document.selection.createRange();d=document.selection.createRange().text.length,e.moveStart("character",-b.value.length),c=e.text.length-d}return{offset:c,length:d}}function A(a){a.preventDefault(),a.stopPropagation()}function B(a){a.preventDefault(),a.stopImmediatePropagation()}function C(b){if(!g){var c=b[0].currentStyle||window.getComputedStyle(b[0],null);g=a(document.createElement("div")).css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:c.fontSize,fontFamily:c.fontFamily,fontStyle:c.fontStyle,fontWeight:c.fontWeight,letterSpacing:c.letterSpacing,textTransform:c.textTransform,whiteSpace:"nowrap"}),g.attr("class","select2-sizer"),a(document.body).append(g)}return g.text(b.val()),g.width()}function D(b,c,d){var e,g,f=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each2(function(){0===this.indexOf("select2-")&&f.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each2(function(){0!==this.indexOf("select2-")&&(g=d(this),g&&f.push(g))})),b.attr("class",f.join(" "))}function E(a,b,c,d){var e=o(a.toUpperCase()).indexOf(o(b.toUpperCase())),f=b.length;return 0>e?(c.push(d(a)),void 0):(c.push(d(a.substring(0,e))),c.push("<span class='select2-match'>"),c.push(d(a.substring(e,e+f))),c.push("</span>"),c.push(d(a.substring(e+f,a.length))),void 0)}function F(a){var b={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};return String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})}function G(c){var d,e=null,f=c.quietMillis||100,g=c.url,h=this;return function(i){window.clearTimeout(d),d=window.setTimeout(function(){var d=c.data,f=g,j=c.transport||a.fn.select2.ajaxDefaults.transport,k={type:c.type||"GET",cache:c.cache||!1,jsonpCallback:c.jsonpCallback||b,dataType:c.dataType||"json"},l=a.extend({},a.fn.select2.ajaxDefaults.params,k);d=d?d.call(h,i.term,i.page,i.context):null,f="function"==typeof f?f.call(h,i.term,i.page,i.context):f,e&&"function"==typeof e.abort&&e.abort(),c.params&&(a.isFunction(c.params)?a.extend(l,c.params.call(h)):a.extend(l,c.params)),a.extend(l,{url:f,dataType:c.dataType,data:d,success:function(a){var b=c.results(a,i.page,i);i.callback(b)},error:function(a,b,c){var d={hasError:!0,jqXHR:a,textStatus:b,errorThrown:c};i.callback(d)}}),e=j.call(h,l)},f)}}function H(b){var d,e,c=b,f=function(a){return""+a.text};a.isArray(c)&&(e=c,c={results:e}),a.isFunction(c)===!1&&(e=c,c=function(){return e});var g=c();return g.text&&(f=g.text,a.isFunction(f)||(d=g.text,f=function(a){return a[d]})),function(b){var g,d=b.term,e={results:[]};return""===d?(b.callback(c()),void 0):(g=function(c,e){var h,i;if(c=c[0],c.children){h={};for(i in c)c.hasOwnProperty(i)&&(h[i]=c[i]);h.children=[],a(c.children).each2(function(a,b){g(b,h.children)}),(h.children.length||b.matcher(d,f(h),c))&&e.push(h)}else b.matcher(d,f(c),c)&&e.push(c)},a(c().results).each2(function(a,b){g(b,e.results)}),b.callback(e),void 0)}}function I(c){var d=a.isFunction(c);return function(e){var f=e.term,g={results:[]},h=d?c(e):c;a.isArray(h)&&(a(h).each(function(){var a=this.text!==b,c=a?this.text:this;(""===f||e.matcher(f,c))&&g.results.push(a?this:{id:this,text:this})}),e.callback(g))}}function J(b,c){if(a.isFunction(b))return!0;if(!b)return!1;if("string"==typeof b)return!0;throw new Error(c+" must be a string, function, or falsy value")}function K(b,c){if(a.isFunction(b)){var d=Array.prototype.slice.call(arguments,2);return b.apply(c,d)}return b}function L(b){var c=0;return a.each(b,function(a,b){b.children?c+=L(b.children):c++}),c}function M(a,c,d,e){var h,i,j,k,l,f=a,g=!1;if(!e.createSearchChoice||!e.tokenSeparators||e.tokenSeparators.length<1)return b;for(;;){for(i=-1,j=0,k=e.tokenSeparators.length;k>j&&(l=e.tokenSeparators[j],i=a.indexOf(l),!(i>=0));j++);if(0>i)break;if(h=a.substring(0,i),a=a.substring(i+l.length),h.length>0&&(h=e.createSearchChoice.call(this,h,c),h!==b&&null!==h&&e.id(h)!==b&&null!==e.id(h))){for(g=!1,j=0,k=c.length;k>j;j++)if(r(e.id(h),e.id(c[j]))){g=!0;break}g||d(h)}}return f!==a?a:void 0}function N(){var b=this;a.each(arguments,function(a,c){b[c].remove(),b[c]=null})}function O(b,c){var d=function(){};return d.prototype=new b,d.prototype.constructor=d,d.prototype.parent=b.prototype,d.prototype=a.extend(d.prototype,c),d}var c,d,e,f,g,i,j,h={x:0,y:0},k={TAB:9,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40,SHIFT:16,CTRL:17,ALT:18,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,BACKSPACE:8,DELETE:46,isArrow:function(a){switch(a=a.which?a.which:a){case k.LEFT:case k.RIGHT:case k.UP:case k.DOWN:return!0}return!1},isControl:function(a){var b=a.which;switch(b){case k.SHIFT:case k.CTRL:case k.ALT:return!0}return a.metaKey?!0:!1},isFunctionKey:function(a){return a=a.which?a.which:a,a>=112&&123>=a}},l="<div class='select2-measure-scrollbar'></div>",m={"\u24b6":"A","\uff21":"A","\xc0":"A","\xc1":"A","\xc2":"A","\u1ea6":"A","\u1ea4":"A","\u1eaa":"A","\u1ea8":"A","\xc3":"A","\u0100":"A","\u0102":"A","\u1eb0":"A","\u1eae":"A","\u1eb4":"A","\u1eb2":"A","\u0226":"A","\u01e0":"A","\xc4":"A","\u01de":"A","\u1ea2":"A","\xc5":"A","\u01fa":"A","\u01cd":"A","\u0200":"A","\u0202":"A","\u1ea0":"A","\u1eac":"A","\u1eb6":"A","\u1e00":"A","\u0104":"A","\u023a":"A","\u2c6f":"A","\ua732":"AA","\xc6":"AE","\u01fc":"AE","\u01e2":"AE","\ua734":"AO","\ua736":"AU","\ua738":"AV","\ua73a":"AV","\ua73c":"AY","\u24b7":"B","\uff22":"B","\u1e02":"B","\u1e04":"B","\u1e06":"B","\u0243":"B","\u0182":"B","\u0181":"B","\u24b8":"C","\uff23":"C","\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\xc7":"C","\u1e08":"C","\u0187":"C","\u023b":"C","\ua73e":"C","\u24b9":"D","\uff24":"D","\u1e0a":"D","\u010e":"D","\u1e0c":"D","\u1e10":"D","\u1e12":"D","\u1e0e":"D","\u0110":"D","\u018b":"D","\u018a":"D","\u0189":"D","\ua779":"D","\u01f1":"DZ","\u01c4":"DZ","\u01f2":"Dz","\u01c5":"Dz","\u24ba":"E","\uff25":"E","\xc8":"E","\xc9":"E","\xca":"E","\u1ec0":"E","\u1ebe":"E","\u1ec4":"E","\u1ec2":"E","\u1ebc":"E","\u0112":"E","\u1e14":"E","\u1e16":"E","\u0114":"E","\u0116":"E","\xcb":"E","\u1eba":"E","\u011a":"E","\u0204":"E","\u0206":"E","\u1eb8":"E","\u1ec6":"E","\u0228":"E","\u1e1c":"E","\u0118":"E","\u1e18":"E","\u1e1a":"E","\u0190":"E","\u018e":"E","\u24bb":"F","\uff26":"F","\u1e1e":"F","\u0191":"F","\ua77b":"F","\u24bc":"G","\uff27":"G","\u01f4":"G","\u011c":"G","\u1e20":"G","\u011e":"G","\u0120":"G","\u01e6":"G","\u0122":"G","\u01e4":"G","\u0193":"G","\ua7a0":"G","\ua77d":"G","\ua77e":"G","\u24bd":"H","\uff28":"H","\u0124":"H","\u1e22":"H","\u1e26":"H","\u021e":"H","\u1e24":"H","\u1e28":"H","\u1e2a":"H","\u0126":"H","\u2c67":"H","\u2c75":"H","\ua78d":"H","\u24be":"I","\uff29":"I","\xcc":"I","\xcd":"I","\xce":"I","\u0128":"I","\u012a":"I","\u012c":"I","\u0130":"I","\xcf":"I","\u1e2e":"I","\u1ec8":"I","\u01cf":"I","\u0208":"I","\u020a":"I","\u1eca":"I","\u012e":"I","\u1e2c":"I","\u0197":"I","\u24bf":"J","\uff2a":"J","\u0134":"J","\u0248":"J","\u24c0":"K","\uff2b":"K","\u1e30":"K","\u01e8":"K","\u1e32":"K","\u0136":"K","\u1e34":"K","\u0198":"K","\u2c69":"K","\ua740":"K","\ua742":"K","\ua744":"K","\ua7a2":"K","\u24c1":"L","\uff2c":"L","\u013f":"L","\u0139":"L","\u013d":"L","\u1e36":"L","\u1e38":"L","\u013b":"L","\u1e3c":"L","\u1e3a":"L","\u0141":"L","\u023d":"L","\u2c62":"L","\u2c60":"L","\ua748":"L","\ua746":"L","\ua780":"L","\u01c7":"LJ","\u01c8":"Lj","\u24c2":"M","\uff2d":"M","\u1e3e":"M","\u1e40":"M","\u1e42":"M","\u2c6e":"M","\u019c":"M","\u24c3":"N","\uff2e":"N","\u01f8":"N","\u0143":"N","\xd1":"N","\u1e44":"N","\u0147":"N","\u1e46":"N","\u0145":"N","\u1e4a":"N","\u1e48":"N","\u0220":"N","\u019d":"N","\ua790":"N","\ua7a4":"N","\u01ca":"NJ","\u01cb":"Nj","\u24c4":"O","\uff2f":"O","\xd2":"O","\xd3":"O","\xd4":"O","\u1ed2":"O","\u1ed0":"O","\u1ed6":"O","\u1ed4":"O","\xd5":"O","\u1e4c":"O","\u022c":"O","\u1e4e":"O","\u014c":"O","\u1e50":"O","\u1e52":"O","\u014e":"O","\u022e":"O","\u0230":"O","\xd6":"O","\u022a":"O","\u1ece":"O","\u0150":"O","\u01d1":"O","\u020c":"O","\u020e":"O","\u01a0":"O","\u1edc":"O","\u1eda":"O","\u1ee0":"O","\u1ede":"O","\u1ee2":"O","\u1ecc":"O","\u1ed8":"O","\u01ea":"O","\u01ec":"O","\xd8":"O","\u01fe":"O","\u0186":"O","\u019f":"O","\ua74a":"O","\ua74c":"O","\u01a2":"OI","\ua74e":"OO","\u0222":"OU","\u24c5":"P","\uff30":"P","\u1e54":"P","\u1e56":"P","\u01a4":"P","\u2c63":"P","\ua750":"P","\ua752":"P","\ua754":"P","\u24c6":"Q","\uff31":"Q","\ua756":"Q","\ua758":"Q","\u024a":"Q","\u24c7":"R","\uff32":"R","\u0154":"R","\u1e58":"R","\u0158":"R","\u0210":"R","\u0212":"R","\u1e5a":"R","\u1e5c":"R","\u0156":"R","\u1e5e":"R","\u024c":"R","\u2c64":"R","\ua75a":"R","\ua7a6":"R","\ua782":"R","\u24c8":"S","\uff33":"S","\u1e9e":"S","\u015a":"S","\u1e64":"S","\u015c":"S","\u1e60":"S","\u0160":"S","\u1e66":"S","\u1e62":"S","\u1e68":"S","\u0218":"S","\u015e":"S","\u2c7e":"S","\ua7a8":"S","\ua784":"S","\u24c9":"T","\uff34":"T","\u1e6a":"T","\u0164":"T","\u1e6c":"T","\u021a":"T","\u0162":"T","\u1e70":"T","\u1e6e":"T","\u0166":"T","\u01ac":"T","\u01ae":"T","\u023e":"T","\ua786":"T","\ua728":"TZ","\u24ca":"U","\uff35":"U","\xd9":"U","\xda":"U","\xdb":"U","\u0168":"U","\u1e78":"U","\u016a":"U","\u1e7a":"U","\u016c":"U","\xdc":"U","\u01db":"U","\u01d7":"U","\u01d5":"U","\u01d9":"U","\u1ee6":"U","\u016e":"U","\u0170":"U","\u01d3":"U","\u0214":"U","\u0216":"U","\u01af":"U","\u1eea":"U","\u1ee8":"U","\u1eee":"U","\u1eec":"U","\u1ef0":"U","\u1ee4":"U","\u1e72":"U","\u0172":"U","\u1e76":"U","\u1e74":"U","\u0244":"U","\u24cb":"V","\uff36":"V","\u1e7c":"V","\u1e7e":"V","\u01b2":"V","\ua75e":"V","\u0245":"V","\ua760":"VY","\u24cc":"W","\uff37":"W","\u1e80":"W","\u1e82":"W","\u0174":"W","\u1e86":"W","\u1e84":"W","\u1e88":"W","\u2c72":"W","\u24cd":"X","\uff38":"X","\u1e8a":"X","\u1e8c":"X","\u24ce":"Y","\uff39":"Y","\u1ef2":"Y","\xdd":"Y","\u0176":"Y","\u1ef8":"Y","\u0232":"Y","\u1e8e":"Y","\u0178":"Y","\u1ef6":"Y","\u1ef4":"Y","\u01b3":"Y","\u024e":"Y","\u1efe":"Y","\u24cf":"Z","\uff3a":"Z","\u0179":"Z","\u1e90":"Z","\u017b":"Z","\u017d":"Z","\u1e92":"Z","\u1e94":"Z","\u01b5":"Z","\u0224":"Z","\u2c7f":"Z","\u2c6b":"Z","\ua762":"Z","\u24d0":"a","\uff41":"a","\u1e9a":"a","\xe0":"a","\xe1":"a","\xe2":"a","\u1ea7":"a","\u1ea5":"a","\u1eab":"a","\u1ea9":"a","\xe3":"a","\u0101":"a","\u0103":"a","\u1eb1":"a","\u1eaf":"a","\u1eb5":"a","\u1eb3":"a","\u0227":"a","\u01e1":"a","\xe4":"a","\u01df":"a","\u1ea3":"a","\xe5":"a","\u01fb":"a","\u01ce":"a","\u0201":"a","\u0203":"a","\u1ea1":"a","\u1ead":"a","\u1eb7":"a","\u1e01":"a","\u0105":"a","\u2c65":"a","\u0250":"a","\ua733":"aa","\xe6":"ae","\u01fd":"ae","\u01e3":"ae","\ua735":"ao","\ua737":"au","\ua739":"av","\ua73b":"av","\ua73d":"ay","\u24d1":"b","\uff42":"b","\u1e03":"b","\u1e05":"b","\u1e07":"b","\u0180":"b","\u0183":"b","\u0253":"b","\u24d2":"c","\uff43":"c","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\xe7":"c","\u1e09":"c","\u0188":"c","\u023c":"c","\ua73f":"c","\u2184":"c","\u24d3":"d","\uff44":"d","\u1e0b":"d","\u010f":"d","\u1e0d":"d","\u1e11":"d","\u1e13":"d","\u1e0f":"d","\u0111":"d","\u018c":"d","\u0256":"d","\u0257":"d","\ua77a":"d","\u01f3":"dz","\u01c6":"dz","\u24d4":"e","\uff45":"e","\xe8":"e","\xe9":"e","\xea":"e","\u1ec1":"e","\u1ebf":"e","\u1ec5":"e","\u1ec3":"e","\u1ebd":"e","\u0113":"e","\u1e15":"e","\u1e17":"e","\u0115":"e","\u0117":"e","\xeb":"e","\u1ebb":"e","\u011b":"e","\u0205":"e","\u0207":"e","\u1eb9":"e","\u1ec7":"e","\u0229":"e","\u1e1d":"e","\u0119":"e","\u1e19":"e","\u1e1b":"e","\u0247":"e","\u025b":"e","\u01dd":"e","\u24d5":"f","\uff46":"f","\u1e1f":"f","\u0192":"f","\ua77c":"f","\u24d6":"g","\uff47":"g","\u01f5":"g","\u011d":"g","\u1e21":"g","\u011f":"g","\u0121":"g","\u01e7":"g","\u0123":"g","\u01e5":"g","\u0260":"g","\ua7a1":"g","\u1d79":"g","\ua77f":"g","\u24d7":"h","\uff48":"h","\u0125":"h","\u1e23":"h","\u1e27":"h","\u021f":"h","\u1e25":"h","\u1e29":"h","\u1e2b":"h","\u1e96":"h","\u0127":"h","\u2c68":"h","\u2c76":"h","\u0265":"h","\u0195":"hv","\u24d8":"i","\uff49":"i","\xec":"i","\xed":"i","\xee":"i","\u0129":"i","\u012b":"i","\u012d":"i","\xef":"i","\u1e2f":"i","\u1ec9":"i","\u01d0":"i","\u0209":"i","\u020b":"i","\u1ecb":"i","\u012f":"i","\u1e2d":"i","\u0268":"i","\u0131":"i","\u24d9":"j","\uff4a":"j","\u0135":"j","\u01f0":"j","\u0249":"j","\u24da":"k","\uff4b":"k","\u1e31":"k","\u01e9":"k","\u1e33":"k","\u0137":"k","\u1e35":"k","\u0199":"k","\u2c6a":"k","\ua741":"k","\ua743":"k","\ua745":"k","\ua7a3":"k","\u24db":"l","\uff4c":"l","\u0140":"l","\u013a":"l","\u013e":"l","\u1e37":"l","\u1e39":"l","\u013c":"l","\u1e3d":"l","\u1e3b":"l","\u017f":"l","\u0142":"l","\u019a":"l","\u026b":"l","\u2c61":"l","\ua749":"l","\ua781":"l","\ua747":"l","\u01c9":"lj","\u24dc":"m","\uff4d":"m","\u1e3f":"m","\u1e41":"m","\u1e43":"m","\u0271":"m","\u026f":"m","\u24dd":"n","\uff4e":"n","\u01f9":"n","\u0144":"n","\xf1":"n","\u1e45":"n","\u0148":"n","\u1e47":"n","\u0146":"n","\u1e4b":"n","\u1e49":"n","\u019e":"n","\u0272":"n","\u0149":"n","\ua791":"n","\ua7a5":"n","\u01cc":"nj","\u24de":"o","\uff4f":"o","\xf2":"o","\xf3":"o","\xf4":"o","\u1ed3":"o","\u1ed1":"o","\u1ed7":"o","\u1ed5":"o","\xf5":"o","\u1e4d":"o","\u022d":"o","\u1e4f":"o","\u014d":"o","\u1e51":"o","\u1e53":"o","\u014f":"o","\u022f":"o","\u0231":"o","\xf6":"o","\u022b":"o","\u1ecf":"o","\u0151":"o","\u01d2":"o","\u020d":"o","\u020f":"o","\u01a1":"o","\u1edd":"o","\u1edb":"o","\u1ee1":"o","\u1edf":"o","\u1ee3":"o","\u1ecd":"o","\u1ed9":"o","\u01eb":"o","\u01ed":"o","\xf8":"o","\u01ff":"o","\u0254":"o","\ua74b":"o","\ua74d":"o","\u0275":"o","\u01a3":"oi","\u0223":"ou","\ua74f":"oo","\u24df":"p","\uff50":"p","\u1e55":"p","\u1e57":"p","\u01a5":"p","\u1d7d":"p","\ua751":"p","\ua753":"p","\ua755":"p","\u24e0":"q","\uff51":"q","\u024b":"q","\ua757":"q","\ua759":"q","\u24e1":"r","\uff52":"r","\u0155":"r","\u1e59":"r","\u0159":"r","\u0211":"r","\u0213":"r","\u1e5b":"r","\u1e5d":"r","\u0157":"r","\u1e5f":"r","\u024d":"r","\u027d":"r","\ua75b":"r","\ua7a7":"r","\ua783":"r","\u24e2":"s","\uff53":"s","\xdf":"s","\u015b":"s","\u1e65":"s","\u015d":"s","\u1e61":"s","\u0161":"s","\u1e67":"s","\u1e63":"s","\u1e69":"s","\u0219":"s","\u015f":"s","\u023f":"s","\ua7a9":"s","\ua785":"s","\u1e9b":"s","\u24e3":"t","\uff54":"t","\u1e6b":"t","\u1e97":"t","\u0165":"t","\u1e6d":"t","\u021b":"t","\u0163":"t","\u1e71":"t","\u1e6f":"t","\u0167":"t","\u01ad":"t","\u0288":"t","\u2c66":"t","\ua787":"t","\ua729":"tz","\u24e4":"u","\uff55":"u","\xf9":"u","\xfa":"u","\xfb":"u","\u0169":"u","\u1e79":"u","\u016b":"u","\u1e7b":"u","\u016d":"u","\xfc":"u","\u01dc":"u","\u01d8":"u","\u01d6":"u","\u01da":"u","\u1ee7":"u","\u016f":"u","\u0171":"u","\u01d4":"u","\u0215":"u","\u0217":"u","\u01b0":"u","\u1eeb":"u","\u1ee9":"u","\u1eef":"u","\u1eed":"u","\u1ef1":"u","\u1ee5":"u","\u1e73":"u","\u0173":"u","\u1e77":"u","\u1e75":"u","\u0289":"u","\u24e5":"v","\uff56":"v","\u1e7d":"v","\u1e7f":"v","\u028b":"v","\ua75f":"v","\u028c":"v","\ua761":"vy","\u24e6":"w","\uff57":"w","\u1e81":"w","\u1e83":"w","\u0175":"w","\u1e87":"w","\u1e85":"w","\u1e98":"w","\u1e89":"w","\u2c73":"w","\u24e7":"x","\uff58":"x","\u1e8b":"x","\u1e8d":"x","\u24e8":"y","\uff59":"y","\u1ef3":"y","\xfd":"y","\u0177":"y","\u1ef9":"y","\u0233":"y","\u1e8f":"y","\xff":"y","\u1ef7":"y","\u1e99":"y","\u1ef5":"y","\u01b4":"y","\u024f":"y","\u1eff":"y","\u24e9":"z","\uff5a":"z","\u017a":"z","\u1e91":"z","\u017c":"z","\u017e":"z","\u1e93":"z","\u1e95":"z","\u01b6":"z","\u0225":"z","\u0240":"z","\u2c6c":"z","\ua763":"z","\u0386":"\u0391","\u0388":"\u0395","\u0389":"\u0397","\u038a":"\u0399","\u03aa":"\u0399","\u038c":"\u039f","\u038e":"\u03a5","\u03ab":"\u03a5","\u038f":"\u03a9","\u03ac":"\u03b1","\u03ad":"\u03b5","\u03ae":"\u03b7","\u03af":"\u03b9","\u03ca":"\u03b9","\u0390":"\u03b9","\u03cc":"\u03bf","\u03cd":"\u03c5","\u03cb":"\u03c5","\u03b0":"\u03c5","\u03c9":"\u03c9","\u03c2":"\u03c3"};i=a(document),f=function(){var a=1;return function(){return a++}}(),c=O(Object,{bind:function(a){var b=this;return function(){a.apply(b,arguments)}},init:function(c){var d,e,g=".select2-results";this.opts=c=this.prepareOpts(c),this.id=c.id,c.element.data("select2")!==b&&null!==c.element.data("select2")&&c.element.data("select2").destroy(),this.container=this.createContainer(),this.liveRegion=a(".select2-hidden-accessible"),0==this.liveRegion.length&&(this.liveRegion=a("<span>",{role:"status","aria-live":"polite"}).addClass("select2-hidden-accessible").appendTo(document.body)),this.containerId="s2id_"+(c.element.attr("id")||"autogen"+f()),this.containerEventName=this.containerId.replace(/([.])/g,"_").replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g,"\\$1"),this.container.attr("id",this.containerId),this.container.attr("title",c.element.attr("title")),this.body=a(document.body),D(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.attr("style",c.element.attr("style")),this.container.css(K(c.containerCss,this.opts.element)),this.container.addClass(K(c.containerCssClass,this.opts.element)),this.elementTabIndex=this.opts.element.attr("tabindex"),this.opts.element.data("select2",this).attr("tabindex","-1").before(this.container).on("click.select2",A),this.container.data("select2",this),this.dropdown=this.container.find(".select2-drop"),D(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(K(c.dropdownCssClass,this.opts.element)),this.dropdown.data("select2",this),this.dropdown.on("click",A),this.results=d=this.container.find(g),this.search=e=this.container.find("input.select2-input"),this.queryCount=0,this.resultsPage=0,this.context=null,this.initContainer(),this.container.on("click",A),v(this.results),this.dropdown.on("mousemove-filtered",g,this.bind(this.highlightUnderEvent)),this.dropdown.on("touchstart touchmove touchend",g,this.bind(function(a){this._touchEvent=!0,this.highlightUnderEvent(a)})),this.dropdown.on("touchmove",g,this.bind(this.touchMoved)),this.dropdown.on("touchstart touchend",g,this.bind(this.clearTouchMoved)),this.dropdown.on("click",this.bind(function(){this._touchEvent&&(this._touchEvent=!1,this.selectHighlighted())})),x(80,this.results),this.dropdown.on("scroll-debounced",g,this.bind(this.loadMoreIfNeeded)),a(this.container).on("change",".select2-input",function(a){a.stopPropagation()}),a(this.dropdown).on("change",".select2-input",function(a){a.stopPropagation()}),a.fn.mousewheel&&d.mousewheel(function(a,b,c,e){var f=d.scrollTop();e>0&&0>=f-e?(d.scrollTop(0),A(a)):0>e&&d.get(0).scrollHeight-d.scrollTop()+e<=d.height()&&(d.scrollTop(d.get(0).scrollHeight-d.height()),A(a))}),u(e),e.on("keyup-change input paste",this.bind(this.updateResults)),e.on("focus",function(){e.addClass("select2-focused")}),e.on("blur",function(){e.removeClass("select2-focused")}),this.dropdown.on("mouseup",g,this.bind(function(b){a(b.target).closest(".select2-result-selectable").length>0&&(this.highlightUnderEvent(b),this.selectHighlighted(b))})),this.dropdown.on("click mouseup mousedown touchstart touchend focusin",function(a){a.stopPropagation()}),this.lastSearchTerm=b,a.isFunction(this.opts.initSelection)&&(this.initSelection(),this.monitorSource()),null!==c.maximumInputLength&&this.search.attr("maxlength",c.maximumInputLength);var h=c.element.prop("disabled");h===b&&(h=!1),this.enable(!h);var i=c.element.prop("readonly");i===b&&(i=!1),this.readonly(i),j=j||q(),this.autofocus=c.element.prop("autofocus"),c.element.prop("autofocus",!1),this.autofocus&&this.focus(),this.search.attr("placeholder",c.searchInputPlaceholder)},destroy:function(){var a=this.opts.element,c=a.data("select2"),d=this;this.close(),a.length&&a[0].detachEvent&&d._sync&&a.each(function(){d._sync&&this.detachEvent("onpropertychange",d._sync)}),this.propertyObserver&&(this.propertyObserver.disconnect(),this.propertyObserver=null),this._sync=null,c!==b&&(c.container.remove(),c.liveRegion.remove(),c.dropdown.remove(),a.removeData("select2").off(".select2"),a.is("input[type='hidden']")?a.css("display",""):(a.show().prop("autofocus",this.autofocus||!1),this.elementTabIndex?a.attr({tabindex:this.elementTabIndex}):a.removeAttr("tabindex"),a.show())),N.call(this,"container","liveRegion","dropdown","results","search")},optionToData:function(a){return a.is("option")?{id:a.prop("value"),text:a.text(),element:a.get(),css:a.attr("class"),disabled:a.prop("disabled"),locked:r(a.attr("locked"),"locked")||r(a.data("locked"),!0)}:a.is("optgroup")?{text:a.attr("label"),children:[],element:a.get(),css:a.attr("class")}:void 0},prepareOpts:function(c){var d,e,g,h,i=this;if(d=c.element,"select"===d.get(0).tagName.toLowerCase()&&(this.select=e=c.element),e&&a.each(["id","multiple","ajax","query","createSearchChoice","initSelection","data","tags"],function(){if(this in c)throw new Error("Option '"+this+"' is not allowed for Select2 when attached to a <select> element.")}),c=a.extend({},{populateResults:function(d,e,g){var h,j=this.opts.id,k=this.liveRegion;h=function(d,e,l){var m,n,o,p,q,r,s,t,u,v;d=c.sortResults(d,e,g);var w=[];for(m=0,n=d.length;n>m;m+=1)o=d[m],q=o.disabled===!0,p=!q&&j(o)!==b,r=o.children&&o.children.length>0,s=a("<li></li>"),s.addClass("select2-results-dept-"+l),s.addClass("select2-result"),s.addClass(p?"select2-result-selectable":"select2-result-unselectable"),q&&s.addClass("select2-disabled"),r&&s.addClass("select2-result-with-children"),s.addClass(i.opts.formatResultCssClass(o)),s.attr("role","presentation"),t=a(document.createElement("div")),t.addClass("select2-result-label"),t.attr("id","select2-result-label-"+f()),t.attr("role","option"),v=c.formatResult(o,t,g,i.opts.escapeMarkup),v!==b&&(t.html(v),s.append(t)),r&&(u=a("<ul></ul>"),u.addClass("select2-result-sub"),h(o.children,u,l+1),s.append(u)),s.data("select2-data",o),w.push(s[0]);e.append(w),k.text(c.formatMatches(d.length))},h(e,d,0)}},a.fn.select2.defaults,c),"function"!=typeof c.id&&(g=c.id,c.id=function(a){return a[g]}),a.isArray(c.element.data("select2Tags"))){if("tags"in c)throw"tags specified as both an attribute 'data-select2-tags' and in options of Select2 "+c.element.attr("id");c.tags=c.element.data("select2Tags")}if(e?(c.query=this.bind(function(a){var f,g,h,c={results:[],more:!1},e=a.term;h=function(b,c){var d;b.is("option")?a.matcher(e,b.text(),b)&&c.push(i.optionToData(b)):b.is("optgroup")&&(d=i.optionToData(b),b.children().each2(function(a,b){h(b,d.children)}),d.children.length>0&&c.push(d))},f=d.children(),this.getPlaceholder()!==b&&f.length>0&&(g=this.getPlaceholderOption(),g&&(f=f.not(g))),f.each2(function(a,b){h(b,c.results)}),a.callback(c)}),c.id=function(a){return a.id}):"query"in c||("ajax"in c?(h=c.element.data("ajax-url"),h&&h.length>0&&(c.ajax.url=h),c.query=G.call(c.element,c.ajax)):"data"in c?c.query=H(c.data):"tags"in c&&(c.query=I(c.tags),c.createSearchChoice===b&&(c.createSearchChoice=function(b){return{id:a.trim(b),text:a.trim(b)}}),c.initSelection===b&&(c.initSelection=function(b,d){var e=[];a(s(b.val(),c.separator,c.transformVal)).each(function(){var b={id:this,text:this},d=c.tags;a.isFunction(d)&&(d=d()),a(d).each(function(){return r(this.id,b.id)?(b=this,!1):void 0}),e.push(b)}),d(e)}))),"function"!=typeof c.query)throw"query function not defined for Select2 "+c.element.attr("id");if("top"===c.createSearchChoicePosition)c.createSearchChoicePosition=function(a,b){a.unshift(b)};else if("bottom"===c.createSearchChoicePosition)c.createSearchChoicePosition=function(a,b){a.push(b)};else if("function"!=typeof c.createSearchChoicePosition)throw"invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function";return c},monitorSource:function(){var d,c=this.opts.element,e=this;c.on("change.select2",this.bind(function(){this.opts.element.data("select2-change-triggered")!==!0&&this.initSelection()})),this._sync=this.bind(function(){var a=c.prop("disabled");a===b&&(a=!1),this.enable(!a);var d=c.prop("readonly");d===b&&(d=!1),this.readonly(d),this.container&&(D(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.addClass(K(this.opts.containerCssClass,this.opts.element))),this.dropdown&&(D(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(K(this.opts.dropdownCssClass,this.opts.element)))}),c.length&&c[0].attachEvent&&c.each(function(){this.attachEvent("onpropertychange",e._sync)}),d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver,d!==b&&(this.propertyObserver&&(delete this.propertyObserver,this.propertyObserver=null),this.propertyObserver=new d(function(b){a.each(b,e._sync)}),this.propertyObserver.observe(c.get(0),{attributes:!0,subtree:!1}))},triggerSelect:function(b){var c=a.Event("select2-selecting",{val:this.id(b),object:b,choice:b});return this.opts.element.trigger(c),!c.isDefaultPrevented()},triggerChange:function(b){b=b||{},b=a.extend({},b,{type:"change",val:this.val()}),this.opts.element.data("select2-change-triggered",!0),this.opts.element.trigger(b),this.opts.element.data("select2-change-triggered",!1),this.opts.element.click(),this.opts.blurOnChange&&this.opts.element.blur()},isInterfaceEnabled:function(){return this.enabledInterface===!0},enableInterface:function(){var a=this._enabled&&!this._readonly,b=!a;return a===this.enabledInterface?!1:(this.container.toggleClass("select2-container-disabled",b),this.close(),this.enabledInterface=a,!0)},enable:function(a){a===b&&(a=!0),this._enabled!==a&&(this._enabled=a,this.opts.element.prop("disabled",!a),this.enableInterface())},disable:function(){this.enable(!1)},readonly:function(a){a===b&&(a=!1),this._readonly!==a&&(this._readonly=a,this.opts.element.prop("readonly",a),this.enableInterface())},opened:function(){return this.container?this.container.hasClass("select2-dropdown-open"):!1},positionDropdown:function(){var v,w,x,y,z,b=this.dropdown,c=this.container,d=c.offset(),e=c.outerHeight(!1),f=c.outerWidth(!1),g=b.outerHeight(!1),h=a(window),i=h.width(),k=h.height(),l=h.scrollLeft()+i,m=h.scrollTop()+k,n=d.top+e,o=d.left,p=m>=n+g,q=d.top-g>=h.scrollTop(),r=b.outerWidth(!1),s=function(){return l>=o+r},t=function(){return d.left+l+c.outerWidth(!1)>r},u=b.hasClass("select2-drop-above");u?(w=!0,!q&&p&&(x=!0,w=!1)):(w=!1,!p&&q&&(x=!0,w=!0)),x&&(b.hide(),d=this.container.offset(),e=this.container.outerHeight(!1),f=this.container.outerWidth(!1),g=b.outerHeight(!1),l=h.scrollLeft()+i,m=h.scrollTop()+k,n=d.top+e,o=d.left,r=b.outerWidth(!1),b.show(),this.focusSearch()),this.opts.dropdownAutoWidth?(z=a(".select2-results",b)[0],b.addClass("select2-drop-auto-width"),b.css("width",""),r=b.outerWidth(!1)+(z.scrollHeight===z.clientHeight?0:j.width),r>f?f=r:r=f,g=b.outerHeight(!1)):this.container.removeClass("select2-drop-auto-width"),"static"!==this.body.css("position")&&(v=this.body.offset(),n-=v.top,o-=v.left),!s()&&t()&&(o=d.left+this.container.outerWidth(!1)-r),y={left:o,width:f},w?(this.container.addClass("select2-drop-above"),b.addClass("select2-drop-above"),g=b.outerHeight(!1),y.top=d.top-g,y.bottom="auto"):(y.top=n,y.bottom="auto",this.container.removeClass("select2-drop-above"),b.removeClass("select2-drop-above")),y=a.extend(y,K(this.opts.dropdownCss,this.opts.element)),b.css(y)},shouldOpen:function(){var b;return this.opened()?!1:this._enabled===!1||this._readonly===!0?!1:(b=a.Event("select2-opening"),this.opts.element.trigger(b),!b.isDefaultPrevented())},clearDropdownAlignmentPreference:function(){this.container.removeClass("select2-drop-above"),this.dropdown.removeClass("select2-drop-above")},open:function(){return this.shouldOpen()?(this.opening(),i.on("mousemove.select2Event",function(a){h.x=a.pageX,h.y=a.pageY}),!0):!1},opening:function(){var f,b=this.containerEventName,c="scroll."+b,d="resize."+b,e="orientationchange."+b;this.container.addClass("select2-dropdown-open").addClass("select2-container-active"),this.clearDropdownAlignmentPreference(),this.dropdown[0]!==this.body.children().last()[0]&&this.dropdown.detach().appendTo(this.body),f=a("#select2-drop-mask"),0===f.length&&(f=a(document.createElement("div")),f.attr("id","select2-drop-mask").attr("class","select2-drop-mask"),f.hide(),f.appendTo(this.body),f.on("mousedown touchstart click",function(b){n(f);var d,c=a("#select2-drop");c.length>0&&(d=c.data("select2"),d.opts.selectOnBlur&&d.selectHighlighted({noFocus:!0}),d.close(),b.preventDefault(),b.stopPropagation())})),this.dropdown.prev()[0]!==f[0]&&this.dropdown.before(f),a("#select2-drop").removeAttr("id"),this.dropdown.attr("id","select2-drop"),f.show(),this.positionDropdown(),this.dropdown.show(),this.positionDropdown(),this.dropdown.addClass("select2-drop-active");var g=this;this.container.parents().add(window).each(function(){a(this).on(d+" "+c+" "+e,function(){g.opened()&&g.positionDropdown()})})},close:function(){if(this.opened()){var b=this.containerEventName,c="scroll."+b,d="resize."+b,e="orientationchange."+b;this.container.parents().add(window).each(function(){a(this).off(c).off(d).off(e)}),this.clearDropdownAlignmentPreference(),a("#select2-drop-mask").hide(),this.dropdown.removeAttr("id"),this.dropdown.hide(),this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active"),this.results.empty(),i.off("mousemove.select2Event"),this.clearSearch(),this.search.removeClass("select2-active"),this.search.removeAttr("aria-activedescendant"),this.opts.element.trigger(a.Event("select2-close"))}},externalSearch:function(a){this.open(),this.search.val(a),this.updateResults(!1)},clearSearch:function(){},prefillNextSearchTerm:function(){if(""!==this.search.val())return!1;var a=this.opts.nextSearchTerm(this.data(),this.lastSearchTerm);return a!==b?(this.search.val(a),this.search.select(),!0):!1},getMaximumSelectionSize:function(){return K(this.opts.maximumSelectionSize,this.opts.element)},ensureHighlightVisible:function(){var c,d,e,f,g,h,i,j,b=this.results;if(d=this.highlight(),!(0>d)){if(0==d)return b.scrollTop(0),void 0;c=this.findHighlightableChoices().find(".select2-result-label"),e=a(c[d]),j=(e.offset()||{}).top||0,f=j+e.outerHeight(!0),d===c.length-1&&(i=b.find("li.select2-more-results"),i.length>0&&(f=i.offset().top+i.outerHeight(!0))),g=b.offset().top+b.outerHeight(!1),f>g&&b.scrollTop(b.scrollTop()+(f-g)),h=j-b.offset().top,0>h&&"none"!=e.css("display")&&b.scrollTop(b.scrollTop()+h)
-}},findHighlightableChoices:function(){return this.results.find(".select2-result-selectable:not(.select2-disabled):not(.select2-selected)")},moveHighlight:function(b){for(var c=this.findHighlightableChoices(),d=this.highlight();d>-1&&d<c.length;){d+=b;var e=a(c[d]);if(e.hasClass("select2-result-selectable")&&!e.hasClass("select2-disabled")&&!e.hasClass("select2-selected")){this.highlight(d);break}}},highlight:function(b){var d,e,c=this.findHighlightableChoices();return 0===arguments.length?p(c.filter(".select2-highlighted")[0],c.get()):(b>=c.length&&(b=c.length-1),0>b&&(b=0),this.removeHighlight(),d=a(c[b]),d.addClass("select2-highlighted"),this.search.attr("aria-activedescendant",d.find(".select2-result-label").attr("id")),this.ensureHighlightVisible(),this.liveRegion.text(d.text()),e=d.data("select2-data"),e&&this.opts.element.trigger({type:"select2-highlight",val:this.id(e),choice:e}),void 0)},removeHighlight:function(){this.results.find(".select2-highlighted").removeClass("select2-highlighted")},touchMoved:function(){this._touchMoved=!0},clearTouchMoved:function(){this._touchMoved=!1},countSelectableResults:function(){return this.findHighlightableChoices().length},highlightUnderEvent:function(b){var c=a(b.target).closest(".select2-result-selectable");if(c.length>0&&!c.is(".select2-highlighted")){var d=this.findHighlightableChoices();this.highlight(d.index(c))}else 0==c.length&&this.removeHighlight()},loadMoreIfNeeded:function(){var c,a=this.results,b=a.find("li.select2-more-results"),d=this.resultsPage+1,e=this,f=this.search.val(),g=this.context;0!==b.length&&(c=b.offset().top-a.offset().top-a.height(),c<=this.opts.loadMorePadding&&(b.addClass("select2-active"),this.opts.query({element:this.opts.element,term:f,page:d,context:g,matcher:this.opts.matcher,callback:this.bind(function(c){e.opened()&&(e.opts.populateResults.call(this,a,c.results,{term:f,page:d,context:g}),e.postprocessResults(c,!1,!1),c.more===!0?(b.detach().appendTo(a).html(e.opts.escapeMarkup(K(e.opts.formatLoadMore,e.opts.element,d+1))),window.setTimeout(function(){e.loadMoreIfNeeded()},10)):b.remove(),e.positionDropdown(),e.resultsPage=d,e.context=c.context,this.opts.element.trigger({type:"select2-loaded",items:c}))})})))},tokenize:function(){},updateResults:function(c){function m(){d.removeClass("select2-active"),h.positionDropdown(),e.find(".select2-no-results,.select2-selection-limit,.select2-searching").length?h.liveRegion.text(e.text()):h.liveRegion.text(h.opts.formatMatches(e.find('.select2-result-selectable:not(".select2-selected")').length))}function n(a){e.html(a),m()}var g,i,l,d=this.search,e=this.results,f=this.opts,h=this,j=d.val(),k=a.data(this.container,"select2-last-term");if((c===!0||!k||!r(j,k))&&(a.data(this.container,"select2-last-term",j),c===!0||this.showSearchInput!==!1&&this.opened())){l=++this.queryCount;var o=this.getMaximumSelectionSize();if(o>=1&&(g=this.data(),a.isArray(g)&&g.length>=o&&J(f.formatSelectionTooBig,"formatSelectionTooBig")))return n("<li class='select2-selection-limit'>"+K(f.formatSelectionTooBig,f.element,o)+"</li>"),void 0;if(d.val().length<f.minimumInputLength)return J(f.formatInputTooShort,"formatInputTooShort")?n("<li class='select2-no-results'>"+K(f.formatInputTooShort,f.element,d.val(),f.minimumInputLength)+"</li>"):n(""),c&&this.showSearch&&this.showSearch(!0),void 0;if(f.maximumInputLength&&d.val().length>f.maximumInputLength)return J(f.formatInputTooLong,"formatInputTooLong")?n("<li class='select2-no-results'>"+K(f.formatInputTooLong,f.element,d.val(),f.maximumInputLength)+"</li>"):n(""),void 0;f.formatSearching&&0===this.findHighlightableChoices().length&&n("<li class='select2-searching'>"+K(f.formatSearching,f.element)+"</li>"),d.addClass("select2-active"),this.removeHighlight(),i=this.tokenize(),i!=b&&null!=i&&d.val(i),this.resultsPage=1,f.query({element:f.element,term:d.val(),page:this.resultsPage,context:null,matcher:f.matcher,callback:this.bind(function(g){var i;if(l==this.queryCount){if(!this.opened())return this.search.removeClass("select2-active"),void 0;if(g.hasError!==b&&J(f.formatAjaxError,"formatAjaxError"))return n("<li class='select2-ajax-error'>"+K(f.formatAjaxError,f.element,g.jqXHR,g.textStatus,g.errorThrown)+"</li>"),void 0;if(this.context=g.context===b?null:g.context,this.opts.createSearchChoice&&""!==d.val()&&(i=this.opts.createSearchChoice.call(h,d.val(),g.results),i!==b&&null!==i&&h.id(i)!==b&&null!==h.id(i)&&0===a(g.results).filter(function(){return r(h.id(this),h.id(i))}).length&&this.opts.createSearchChoicePosition(g.results,i)),0===g.results.length&&J(f.formatNoMatches,"formatNoMatches"))return n("<li class='select2-no-results'>"+K(f.formatNoMatches,f.element,d.val())+"</li>"),this.showSearch&&this.showSearch(d.val()),void 0;e.empty(),h.opts.populateResults.call(this,e,g.results,{term:d.val(),page:this.resultsPage,context:null}),g.more===!0&&J(f.formatLoadMore,"formatLoadMore")&&(e.append("<li class='select2-more-results'>"+f.escapeMarkup(K(f.formatLoadMore,f.element,this.resultsPage))+"</li>"),window.setTimeout(function(){h.loadMoreIfNeeded()},10)),this.postprocessResults(g,c),m(),this.opts.element.trigger({type:"select2-loaded",items:g})}})})}},cancel:function(){this.close()},blur:function(){this.opts.selectOnBlur&&this.selectHighlighted({noFocus:!0}),this.close(),this.container.removeClass("select2-container-active"),this.search[0]===document.activeElement&&this.search.blur(),this.clearSearch(),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")},focusSearch:function(){y(this.search)},selectHighlighted:function(a){if(this._touchMoved)return this.clearTouchMoved(),void 0;var b=this.highlight(),c=this.results.find(".select2-highlighted"),d=c.closest(".select2-result").data("select2-data");d?(this.highlight(b),this.onSelect(d,a)):a&&a.noFocus&&this.close()},getPlaceholder:function(){var a;return this.opts.element.attr("placeholder")||this.opts.element.attr("data-placeholder")||this.opts.element.data("placeholder")||this.opts.placeholder||((a=this.getPlaceholderOption())!==b?a.text():b)},getPlaceholderOption:function(){if(this.select){var c=this.select.children("option").first();if(this.opts.placeholderOption!==b)return"first"===this.opts.placeholderOption&&c||"function"==typeof this.opts.placeholderOption&&this.opts.placeholderOption(this.select);if(""===a.trim(c.text())&&""===c.val())return c}},initContainerWidth:function(){function b(){var b,c,d,e,f,g;if("off"===this.opts.width)return null;if("element"===this.opts.width)return 0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px";if("copy"===this.opts.width||"resolve"===this.opts.width){if(b=this.opts.element.attr("style"),"string"==typeof b)for(c=b.split(";"),e=0,f=c.length;f>e;e+=1)if(g=c[e].replace(/\s/g,""),d=g.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i),null!==d&&d.length>=1)return d[1];return"resolve"===this.opts.width?(b=this.opts.element.css("width"),b.indexOf("%")>0?b:0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px"):null}return a.isFunction(this.opts.width)?this.opts.width():this.opts.width}var c=b.call(this);null!==c&&this.container.css("width",c)}}),d=O(c,{createContainer:function(){var b=a(document.createElement("div")).attr({"class":"select2-container"}).html(["<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>","   <span class='select2-chosen'>&#160;</span><abbr class='select2-search-choice-close'></abbr>","   <span class='select2-arrow' role='presentation'><b role='presentation'></b></span>","</a>","<label for='' class='select2-offscreen'></label>","<input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' />","<div class='select2-drop select2-display-none'>","   <div class='select2-search'>","       <label for='' class='select2-offscreen'></label>","       <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'","       aria-autocomplete='list' />","   </div>","   <ul class='select2-results' role='listbox'>","   </ul>","</div>"].join(""));return b},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.focusser.prop("disabled",!this.isInterfaceEnabled())},opening:function(){var b,c,d;this.opts.minimumResultsForSearch>=0&&this.showSearch(!0),this.parent.opening.apply(this,arguments),this.showSearchInput!==!1&&this.search.val(this.focusser.val()),this.opts.shouldFocusInput(this)&&(this.search.focus(),b=this.search.get(0),b.createTextRange?(c=b.createTextRange(),c.collapse(!1),c.select()):b.setSelectionRange&&(d=this.search.val().length,b.setSelectionRange(d,d))),this.prefillNextSearchTerm(),this.focusser.prop("disabled",!0).val(""),this.updateResults(!0),this.opts.element.trigger(a.Event("select2-open"))},close:function(){this.opened()&&(this.parent.close.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},focus:function(){this.opened()?this.close():(this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},isFocused:function(){return this.container.hasClass("select2-container-active")},cancel:function(){this.parent.cancel.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus()},destroy:function(){a("label[for='"+this.focusser.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments),N.call(this,"selection","focusser")},initContainer:function(){var b,g,c=this.container,d=this.dropdown,e=f();this.opts.minimumResultsForSearch<0?this.showSearch(!1):this.showSearch(!0),this.selection=b=c.find(".select2-choice"),this.focusser=c.find(".select2-focusser"),b.find(".select2-chosen").attr("id","select2-chosen-"+e),this.focusser.attr("aria-labelledby","select2-chosen-"+e),this.results.attr("id","select2-results-"+e),this.search.attr("aria-owns","select2-results-"+e),this.focusser.attr("id","s2id_autogen"+e),g=a("label[for='"+this.opts.element.attr("id")+"']"),this.opts.element.on("focus.select2",this.bind(function(){this.focus()})),this.focusser.prev().text(g.text()).attr("for",this.focusser.attr("id"));var h=this.opts.element.attr("title");this.opts.element.attr("title",h||g.text()),this.focusser.attr("tabindex",this.elementTabIndex),this.search.attr("id",this.focusser.attr("id")+"_search"),this.search.prev().text(a("label[for='"+this.focusser.attr("id")+"']").text()).attr("for",this.search.attr("id")),this.search.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()&&229!=a.keyCode){if(a.which===k.PAGE_UP||a.which===k.PAGE_DOWN)return A(a),void 0;switch(a.which){case k.UP:case k.DOWN:return this.moveHighlight(a.which===k.UP?-1:1),A(a),void 0;case k.ENTER:return this.selectHighlighted(),A(a),void 0;case k.TAB:return this.selectHighlighted({noFocus:!0}),void 0;case k.ESC:return this.cancel(a),A(a),void 0}}})),this.search.on("blur",this.bind(function(){document.activeElement===this.body.get(0)&&window.setTimeout(this.bind(function(){this.opened()&&this.results&&this.results.length>1&&this.search.focus()}),0)})),this.focusser.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()&&a.which!==k.TAB&&!k.isControl(a)&&!k.isFunctionKey(a)&&a.which!==k.ESC){if(this.opts.openOnEnter===!1&&a.which===k.ENTER)return A(a),void 0;if(a.which==k.DOWN||a.which==k.UP||a.which==k.ENTER&&this.opts.openOnEnter){if(a.altKey||a.ctrlKey||a.shiftKey||a.metaKey)return;return this.open(),A(a),void 0}return a.which==k.DELETE||a.which==k.BACKSPACE?(this.opts.allowClear&&this.clear(),A(a),void 0):void 0}})),u(this.focusser),this.focusser.on("keyup-change input",this.bind(function(a){if(this.opts.minimumResultsForSearch>=0){if(a.stopPropagation(),this.opened())return;this.open()}})),b.on("mousedown touchstart","abbr",this.bind(function(a){this.isInterfaceEnabled()&&(this.clear(),B(a),this.close(),this.selection&&this.selection.focus())})),b.on("mousedown touchstart",this.bind(function(c){n(b),this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.opened()?this.close():this.isInterfaceEnabled()&&this.open(),A(c)})),d.on("mousedown touchstart",this.bind(function(){this.opts.shouldFocusInput(this)&&this.search.focus()})),b.on("focus",this.bind(function(a){A(a)})),this.focusser.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active")})).on("blur",this.bind(function(){this.opened()||(this.container.removeClass("select2-container-active"),this.opts.element.trigger(a.Event("select2-blur")))})),this.search.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active")})),this.initContainerWidth(),this.opts.element.hide(),this.setPlaceholder()},clear:function(b){var c=this.selection.data("select2-data");if(c){var d=a.Event("select2-clearing");if(this.opts.element.trigger(d),d.isDefaultPrevented())return;var e=this.getPlaceholderOption();this.opts.element.val(e?e.val():""),this.selection.find(".select2-chosen").empty(),this.selection.removeData("select2-data"),this.setPlaceholder(),b!==!1&&(this.opts.element.trigger({type:"select2-removed",val:this.id(c),choice:c}),this.triggerChange({removed:c}))}},initSelection:function(){if(this.isPlaceholderOptionSelected())this.updateSelection(null),this.close(),this.setPlaceholder();else{var c=this;this.opts.initSelection.call(null,this.opts.element,function(a){a!==b&&null!==a&&(c.updateSelection(a),c.close(),c.setPlaceholder(),c.lastSearchTerm=c.search.val())})}},isPlaceholderOptionSelected:function(){var a;return this.getPlaceholder()===b?!1:(a=this.getPlaceholderOption())!==b&&a.prop("selected")||""===this.opts.element.val()||this.opts.element.val()===b||null===this.opts.element.val()},prepareOpts:function(){var b=this.parent.prepareOpts.apply(this,arguments),c=this;return"select"===b.element.get(0).tagName.toLowerCase()?b.initSelection=function(a,b){var d=a.find("option").filter(function(){return this.selected&&!this.disabled});b(c.optionToData(d))}:"data"in b&&(b.initSelection=b.initSelection||function(c,d){var e=c.val(),f=null;b.query({matcher:function(a,c,d){var g=r(e,b.id(d));return g&&(f=d),g},callback:a.isFunction(d)?function(){d(f)}:a.noop})}),b},getPlaceholder:function(){return this.select&&this.getPlaceholderOption()===b?b:this.parent.getPlaceholder.apply(this,arguments)},setPlaceholder:function(){var a=this.getPlaceholder();if(this.isPlaceholderOptionSelected()&&a!==b){if(this.select&&this.getPlaceholderOption()===b)return;this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(a)),this.selection.addClass("select2-default"),this.container.removeClass("select2-allowclear")}},postprocessResults:function(a,b,c){var d=0,e=this;if(this.findHighlightableChoices().each2(function(a,b){return r(e.id(b.data("select2-data")),e.opts.element.val())?(d=a,!1):void 0}),c!==!1&&(b===!0&&d>=0?this.highlight(d):this.highlight(0)),b===!0){var g=this.opts.minimumResultsForSearch;g>=0&&this.showSearch(L(a.results)>=g)}},showSearch:function(b){this.showSearchInput!==b&&(this.showSearchInput=b,this.dropdown.find(".select2-search").toggleClass("select2-search-hidden",!b),this.dropdown.find(".select2-search").toggleClass("select2-offscreen",!b),a(this.dropdown,this.container).toggleClass("select2-with-searchbox",b))},onSelect:function(a,b){if(this.triggerSelect(a)){var c=this.opts.element.val(),d=this.data();this.opts.element.val(this.id(a)),this.updateSelection(a),this.opts.element.trigger({type:"select2-selected",val:this.id(a),choice:a}),this.lastSearchTerm=this.search.val(),this.close(),b&&b.noFocus||!this.opts.shouldFocusInput(this)||this.focusser.focus(),r(c,this.id(a))||this.triggerChange({added:a,removed:d})}},updateSelection:function(a){var d,e,c=this.selection.find(".select2-chosen");this.selection.data("select2-data",a),c.empty(),null!==a&&(d=this.opts.formatSelection(a,c,this.opts.escapeMarkup)),d!==b&&c.append(d),e=this.opts.formatSelectionCssClass(a,c),e!==b&&c.addClass(e),this.selection.removeClass("select2-default"),this.opts.allowClear&&this.getPlaceholder()!==b&&this.container.addClass("select2-allowclear")},val:function(){var a,c=!1,d=null,e=this,f=this.data();if(0===arguments.length)return this.opts.element.val();if(a=arguments[0],arguments.length>1&&(c=arguments[1]),this.select)this.select.val(a).find("option").filter(function(){return this.selected}).each2(function(a,b){return d=e.optionToData(b),!1}),this.updateSelection(d),this.setPlaceholder(),c&&this.triggerChange({added:d,removed:f});else{if(!a&&0!==a)return this.clear(c),void 0;if(this.opts.initSelection===b)throw new Error("cannot call val() if initSelection() is not defined");this.opts.element.val(a),this.opts.initSelection(this.opts.element,function(a){e.opts.element.val(a?e.id(a):""),e.updateSelection(a),e.setPlaceholder(),c&&e.triggerChange({added:a,removed:f})})}},clearSearch:function(){this.search.val(""),this.focusser.val("")},data:function(a){var c,d=!1;return 0===arguments.length?(c=this.selection.data("select2-data"),c==b&&(c=null),c):(arguments.length>1&&(d=arguments[1]),a?(c=this.data(),this.opts.element.val(a?this.id(a):""),this.updateSelection(a),d&&this.triggerChange({added:a,removed:c})):this.clear(d),void 0)}}),e=O(c,{createContainer:function(){var b=a(document.createElement("div")).attr({"class":"select2-container select2-container-multi"}).html(["<ul class='select2-choices'>","  <li class='select2-search-field'>","    <label for='' class='select2-offscreen'></label>","    <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>","  </li>","</ul>","<div class='select2-drop select2-drop-multi select2-display-none'>","   <ul class='select2-results'>","   </ul>","</div>"].join(""));return b},prepareOpts:function(){var b=this.parent.prepareOpts.apply(this,arguments),c=this;return"select"===b.element.get(0).tagName.toLowerCase()?b.initSelection=function(a,b){var d=[];a.find("option").filter(function(){return this.selected&&!this.disabled}).each2(function(a,b){d.push(c.optionToData(b))}),b(d)}:"data"in b&&(b.initSelection=b.initSelection||function(c,d){var e=s(c.val(),b.separator,b.transformVal),f=[];b.query({matcher:function(c,d,g){var h=a.grep(e,function(a){return r(a,b.id(g))}).length;return h&&f.push(g),h},callback:a.isFunction(d)?function(){for(var a=[],c=0;c<e.length;c++)for(var g=e[c],h=0;h<f.length;h++){var i=f[h];if(r(g,b.id(i))){a.push(i),f.splice(h,1);break}}d(a)}:a.noop})}),b},selectChoice:function(a){var b=this.container.find(".select2-search-choice-focus");b.length&&a&&a[0]==b[0]||(b.length&&this.opts.element.trigger("choice-deselected",b),b.removeClass("select2-search-choice-focus"),a&&a.length&&(this.close(),a.addClass("select2-search-choice-focus"),this.opts.element.trigger("choice-selected",a)))},destroy:function(){a("label[for='"+this.search.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments),N.call(this,"searchContainer","selection")},initContainer:function(){var c,b=".select2-choices";this.searchContainer=this.container.find(".select2-search-field"),this.selection=c=this.container.find(b);var d=this;this.selection.on("click",".select2-container:not(.select2-container-disabled) .select2-search-choice:not(.select2-locked)",function(){d.search[0].focus(),d.selectChoice(a(this))}),this.search.attr("id","s2id_autogen"+f()),this.search.prev().text(a("label[for='"+this.opts.element.attr("id")+"']").text()).attr("for",this.search.attr("id")),this.opts.element.on("focus.select2",this.bind(function(){this.focus()})),this.search.on("input paste",this.bind(function(){this.search.attr("placeholder")&&0==this.search.val().length||this.isInterfaceEnabled()&&(this.opened()||this.open())})),this.search.attr("tabindex",this.elementTabIndex),this.keydowns=0,this.search.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()){++this.keydowns;var b=c.find(".select2-search-choice-focus"),d=b.prev(".select2-search-choice:not(.select2-locked)"),e=b.next(".select2-search-choice:not(.select2-locked)"),f=z(this.search);if(b.length&&(a.which==k.LEFT||a.which==k.RIGHT||a.which==k.BACKSPACE||a.which==k.DELETE||a.which==k.ENTER)){var g=b;return a.which==k.LEFT&&d.length?g=d:a.which==k.RIGHT?g=e.length?e:null:a.which===k.BACKSPACE?this.unselect(b.first())&&(this.search.width(10),g=d.length?d:e):a.which==k.DELETE?this.unselect(b.first())&&(this.search.width(10),g=e.length?e:null):a.which==k.ENTER&&(g=null),this.selectChoice(g),A(a),g&&g.length||this.open(),void 0}if((a.which===k.BACKSPACE&&1==this.keydowns||a.which==k.LEFT)&&0==f.offset&&!f.length)return this.selectChoice(c.find(".select2-search-choice:not(.select2-locked)").last()),A(a),void 0;if(this.selectChoice(null),this.opened())switch(a.which){case k.UP:case k.DOWN:return this.moveHighlight(a.which===k.UP?-1:1),A(a),void 0;case k.ENTER:return this.selectHighlighted(),A(a),void 0;case k.TAB:return this.selectHighlighted({noFocus:!0}),this.close(),void 0;case k.ESC:return this.cancel(a),A(a),void 0}if(a.which!==k.TAB&&!k.isControl(a)&&!k.isFunctionKey(a)&&a.which!==k.BACKSPACE&&a.which!==k.ESC){if(a.which===k.ENTER){if(this.opts.openOnEnter===!1)return;if(a.altKey||a.ctrlKey||a.shiftKey||a.metaKey)return}this.open(),(a.which===k.PAGE_UP||a.which===k.PAGE_DOWN)&&A(a),a.which===k.ENTER&&A(a)}}})),this.search.on("keyup",this.bind(function(){this.keydowns=0,this.resizeSearch()})),this.search.on("blur",this.bind(function(b){this.container.removeClass("select2-container-active"),this.search.removeClass("select2-focused"),this.selectChoice(null),this.opened()||this.clearSearch(),b.stopImmediatePropagation(),this.opts.element.trigger(a.Event("select2-blur"))})),this.container.on("click",b,this.bind(function(b){this.isInterfaceEnabled()&&(a(b.target).closest(".select2-search-choice").length>0||(this.selectChoice(null),this.clearPlaceholder(),this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.open(),this.focusSearch(),b.preventDefault()))})),this.container.on("focus",b,this.bind(function(){this.isInterfaceEnabled()&&(this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"),this.clearPlaceholder())})),this.initContainerWidth(),this.opts.element.hide(),this.clearSearch()},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.search.prop("disabled",!this.isInterfaceEnabled())},initSelection:function(){if(""===this.opts.element.val()&&""===this.opts.element.text()&&(this.updateSelection([]),this.close(),this.clearSearch()),this.select||""!==this.opts.element.val()){var c=this;this.opts.initSelection.call(null,this.opts.element,function(a){a!==b&&null!==a&&(c.updateSelection(a),c.close(),c.clearSearch())})}},clearSearch:function(){var a=this.getPlaceholder(),c=this.getMaxSearchWidth();a!==b&&0===this.getVal().length&&this.search.hasClass("select2-focused")===!1?(this.search.val(a).addClass("select2-default"),this.search.width(c>0?c:this.container.css("width"))):this.search.val("").width(10)},clearPlaceholder:function(){this.search.hasClass("select2-default")&&this.search.val("").removeClass("select2-default")},opening:function(){this.clearPlaceholder(),this.resizeSearch(),this.parent.opening.apply(this,arguments),this.focusSearch(),this.prefillNextSearchTerm(),this.updateResults(!0),this.opts.shouldFocusInput(this)&&this.search.focus(),this.opts.element.trigger(a.Event("select2-open"))},close:function(){this.opened()&&this.parent.close.apply(this,arguments)},focus:function(){this.close(),this.search.focus()},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(b){var c={},d=[],e=this;a(b).each(function(){e.id(this)in c||(c[e.id(this)]=0,d.push(this))}),this.selection.find(".select2-search-choice").remove(),this.addSelectedChoice(d),e.postprocessResults()},tokenize:function(){var a=this.search.val();a=this.opts.tokenizer.call(this,a,this.data(),this.bind(this.onSelect),this.opts),null!=a&&a!=b&&(this.search.val(a),a.length>0&&this.open())},onSelect:function(a,b){this.triggerSelect(a)&&""!==a.text&&(this.addSelectedChoice(a),this.opts.element.trigger({type:"selected",val:this.id(a),choice:a}),this.lastSearchTerm=this.search.val(),this.clearSearch(),this.updateResults(),(this.select||!this.opts.closeOnSelect)&&this.postprocessResults(a,!1,this.opts.closeOnSelect===!0),this.opts.closeOnSelect?(this.close(),this.search.width(10)):this.countSelectableResults()>0?(this.search.width(10),this.resizeSearch(),this.getMaximumSelectionSize()>0&&this.val().length>=this.getMaximumSelectionSize()?this.updateResults(!0):this.prefillNextSearchTerm()&&this.updateResults(),this.positionDropdown()):(this.close(),this.search.width(10)),this.triggerChange({added:a}),b&&b.noFocus||this.focusSearch())},cancel:function(){this.close(),this.focusSearch()},addSelectedChoice:function(b){var c=this.getVal(),d=this;a(b).each(function(){c.push(d.createChoice(this))}),this.setVal(c)},createChoice:function(c){var i,j,d=!c.locked,e=a("<li class='select2-search-choice'>    <div></div>    <a href='#' class='select2-search-choice-close' tabindex='-1'></a></li>"),f=a("<li class='select2-search-choice select2-locked'><div></div></li>"),g=d?e:f,h=this.id(c);return i=this.opts.formatSelection(c,g.find("div"),this.opts.escapeMarkup),i!=b&&g.find("div").replaceWith(a("<div></div>").html(i)),j=this.opts.formatSelectionCssClass(c,g.find("div")),j!=b&&g.addClass(j),d&&g.find(".select2-search-choice-close").on("mousedown",A).on("click dblclick",this.bind(function(b){this.isInterfaceEnabled()&&(this.unselect(a(b.target)),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"),A(b),this.close(),this.focusSearch())})).on("focus",this.bind(function(){this.isInterfaceEnabled()&&(this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"))})),g.data("select2-data",c),g.insertBefore(this.searchContainer),h},unselect:function(b){var d,e,c=this.getVal();if(b=b.closest(".select2-search-choice"),0===b.length)throw"Invalid argument: "+b+". Must be .select2-search-choice";if(d=b.data("select2-data")){var f=a.Event("select2-removing");if(f.val=this.id(d),f.choice=d,this.opts.element.trigger(f),f.isDefaultPrevented())return!1;for(;(e=p(this.id(d),c))>=0;)c.splice(e,1),this.setVal(c),this.select&&this.postprocessResults();return b.remove(),this.opts.element.trigger({type:"select2-removed",val:this.id(d),choice:d}),this.triggerChange({removed:d}),!0}},postprocessResults:function(a,b,c){var d=this.getVal(),e=this.results.find(".select2-result"),f=this.results.find(".select2-result-with-children"),g=this;e.each2(function(a,b){var c=g.id(b.data("select2-data"));p(c,d)>=0&&(b.addClass("select2-selected"),b.find(".select2-result-selectable").addClass("select2-selected"))}),f.each2(function(a,b){b.is(".select2-result-selectable")||0!==b.find(".select2-result-selectable:not(.select2-selected)").length||b.addClass("select2-selected")}),-1==this.highlight()&&c!==!1&&this.opts.closeOnSelect===!0&&g.highlight(0),!this.opts.createSearchChoice&&!e.filter(".select2-result:not(.select2-selected)").length>0&&(!a||a&&!a.more&&0===this.results.find(".select2-no-results").length)&&J(g.opts.formatNoMatches,"formatNoMatches")&&this.results.append("<li class='select2-no-results'>"+K(g.opts.formatNoMatches,g.opts.element,g.search.val())+"</li>")},getMaxSearchWidth:function(){return this.selection.width()-t(this.search)},resizeSearch:function(){var a,b,c,d,e,f=t(this.search);a=C(this.search)+10,b=this.search.offset().left,c=this.selection.width(),d=this.selection.offset().left,e=c-(b-d)-f,a>e&&(e=c-f),40>e&&(e=c-f),0>=e&&(e=a),this.search.width(Math.floor(e))},getVal:function(){var a;return this.select?(a=this.select.val(),null===a?[]:a):(a=this.opts.element.val(),s(a,this.opts.separator,this.opts.transformVal))},setVal:function(b){if(this.select)this.select.val(b);else{var c=[],d={};a(b).each(function(){this in d||(c.push(this),d[this]=0)}),this.opts.element.val(0===c.length?"":c.join(this.opts.separator))}},buildChangeDetails:function(a,b){for(var b=b.slice(0),a=a.slice(0),c=0;c<b.length;c++)for(var d=0;d<a.length;d++)if(r(this.opts.id(b[c]),this.opts.id(a[d]))){b.splice(c,1),c--,a.splice(d,1);break}return{added:b,removed:a}},val:function(c,d){var e,f=this;if(0===arguments.length)return this.getVal();if(e=this.data(),e.length||(e=[]),!c&&0!==c)return this.opts.element.val(""),this.updateSelection([]),this.clearSearch(),d&&this.triggerChange({added:this.data(),removed:e}),void 0;if(this.setVal(c),this.select)this.opts.initSelection(this.select,this.bind(this.updateSelection)),d&&this.triggerChange(this.buildChangeDetails(e,this.data()));else{if(this.opts.initSelection===b)throw new Error("val() cannot be called if initSelection() is not defined");this.opts.initSelection(this.opts.element,function(b){var c=a.map(b,f.id);f.setVal(c),f.updateSelection(b),f.clearSearch(),d&&f.triggerChange(f.buildChangeDetails(e,f.data()))})}this.clearSearch()},onSortStart:function(){if(this.select)throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");this.search.width(0),this.searchContainer.hide()},onSortEnd:function(){var b=[],c=this;this.searchContainer.show(),this.searchContainer.appendTo(this.searchContainer.parent()),this.resizeSearch(),this.selection.find(".select2-search-choice").each(function(){b.push(c.opts.id(a(this).data("select2-data")))}),this.setVal(b),this.triggerChange()},data:function(b,c){var e,f,d=this;return 0===arguments.length?this.selection.children(".select2-search-choice").map(function(){return a(this).data("select2-data")}).get():(f=this.data(),b||(b=[]),e=a.map(b,function(a){return d.opts.id(a)}),this.setVal(e),this.updateSelection(b),this.clearSearch(),c&&this.triggerChange(this.buildChangeDetails(f,this.data())),void 0)}}),a.fn.select2=function(){var f,g,h,i,j,c=Array.prototype.slice.call(arguments,0),k=["val","destroy","opened","open","close","focus","isFocused","container","dropdown","onSortStart","onSortEnd","enable","disable","readonly","positionDropdown","data","search"],l=["opened","isFocused","container","dropdown"],m=["val","data"],n={search:"externalSearch"};return this.each(function(){if(0===c.length||"object"==typeof c[0])f=0===c.length?{}:a.extend({},c[0]),f.element=a(this),"select"===f.element.get(0).tagName.toLowerCase()?j=f.element.prop("multiple"):(j=f.multiple||!1,"tags"in f&&(f.multiple=j=!0)),g=j?new e:new d,g.init(f);else{if("string"!=typeof c[0])throw"Invalid arguments to select2 plugin: "+c;if(p(c[0],k)<0)throw"Unknown method: "+c[0];if(i=b,g=a(this).data("select2"),g===b)return;if(h=c[0],"container"===h?i=g.container:"dropdown"===h?i=g.dropdown:(n[h]&&(h=n[h]),i=g[h].apply(g,c.slice(1))),p(c[0],l)>=0||p(c[0],m)>=0&&1==c.length)return!1}}),i===b?this:i},a.fn.select2.defaults={width:"copy",loadMorePadding:0,closeOnSelect:!0,openOnEnter:!0,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(a,b,c,d){var e=[];return E(this.text(a),c.term,e,d),e.join("")},transformVal:function(b){return a.trim(b)},formatSelection:function(a,c,d){return a?d(this.text(a)):b},sortResults:function(a){return a},formatResultCssClass:function(a){return a.css},formatSelectionCssClass:function(){return b},minimumResultsForSearch:0,minimumInputLength:0,maximumInputLength:null,maximumSelectionSize:0,id:function(a){return a==b?null:a.id},text:function(b){return b&&this.data&&this.data.text?a.isFunction(this.data.text)?this.data.text(b):b[this.data.text]:b.text
-},matcher:function(a,b){return o(""+b).toUpperCase().indexOf(o(""+a).toUpperCase())>=0},separator:",",tokenSeparators:[],tokenizer:M,escapeMarkup:F,blurOnChange:!1,selectOnBlur:!1,adaptContainerCssClass:function(a){return a},adaptDropdownCssClass:function(){return null},nextSearchTerm:function(){return b},searchInputPlaceholder:"",createSearchChoicePosition:"top",shouldFocusInput:function(a){var b="ontouchstart"in window||navigator.msMaxTouchPoints>0;return b?a.opts.minimumResultsForSearch<0?!1:!0:!0}},a.fn.select2.locales=[],a.fn.select2.locales.en={formatMatches:function(a){return 1===a?"One result is available, press enter to select it.":a+" results are available, use up and down arrow keys to navigate."},formatNoMatches:function(){return"No matches found"},formatAjaxError:function(){return"Loading failed"},formatInputTooShort:function(a,b){var c=b-a.length;return"Please enter "+c+" or more character"+(1==c?"":"s")},formatInputTooLong:function(a,b){var c=a.length-b;return"Please delete "+c+" character"+(1==c?"":"s")},formatSelectionTooBig:function(a){return"You can only select "+a+" item"+(1==a?"":"s")},formatLoadMore:function(){return"Loading more results\u2026"},formatSearching:function(){return"Searching\u2026"}},a.extend(a.fn.select2.defaults,a.fn.select2.locales.en),a.fn.select2.ajaxDefaults={transport:a.ajax,params:{type:"GET",cache:!1,dataType:"json"}}}(jQuery);
\ No newline at end of file
+!function(e){void 0===e.fn.each2&&e.extend(e.fn,{each2:function(t){for(var s=e([0]),i=-1,n=this.length;++i<n&&(s.context=s[0]=this[i])&&t.call(s[0],i,s)!==!1;);return this}})}(jQuery),function(e,t){"use strict";function s(t){var s=e(document.createTextNode(""));t.before(s),s.before(t),s.remove()}function i(e){function t(e){return W[e]||e}return e.replace(/[^\u0000-\u007E]/g,t)}function n(e,t){for(var s=0,i=t.length;i>s;s+=1)if(a(e,t[s]))return s;return-1}function o(){var t=e(z);t.appendTo(document.body);var s={width:t.width()-t[0].clientWidth,height:t.height()-t[0].clientHeight};return t.remove(),s}function a(e,s){return e===s?!0:e===t||s===t?!1:null===e||null===s?!1:e.constructor===String?e+""==s+"":s.constructor===String?s+""==e+"":!1}function r(e,t,s){var i,n,o;if(null===e||e.length<1)return[];for(i=e.split(t),n=0,o=i.length;o>n;n+=1)i[n]=s(i[n]);return i}function c(e){return e.outerWidth(!1)-e.width()}function l(s){var i="keyup-change-value";s.on("keydown",function(){e.data(s,i)===t&&e.data(s,i,s.val())}),s.on("keyup",function(){var n=e.data(s,i);n!==t&&s.val()!==n&&(e.removeData(s,i),s.trigger("keyup-change"))})}function h(s){s.on("mousemove",function(s){var i=U;(i===t||i.x!==s.pageX||i.y!==s.pageY)&&e(s.target).trigger("mousemove-filtered",s)})}function u(e,s,i){i=i||t;var n;return function(){var t=arguments;window.clearTimeout(n),n=window.setTimeout(function(){s.apply(i,t)},e)}}function d(e,t){var s=u(e,function(e){t.trigger("scroll-debounced",e)});t.on("scroll",function(e){n(e.target,t.get())<0||s(e)})}function p(e){e[0]!==document.activeElement&&window.setTimeout(function(){var t,s=e[0],i=e.val().length;e.focus();var n=s.offsetWidth>0||s.offsetHeight>0;n&&s===document.activeElement&&(s.setSelectionRange?s.setSelectionRange(i,i):s.createTextRange&&(t=s.createTextRange(),t.collapse(!1),t.select()))},0)}function f(t){t=e(t)[0];var s=0,i=0;if("selectionStart"in t)s=t.selectionStart,i=t.selectionEnd-s;else if("selection"in document){t.focus();var n=document.selection.createRange();i=document.selection.createRange().text.length,n.moveStart("character",-t.value.length),s=n.text.length-i}return{offset:s,length:i}}function g(e){e.preventDefault(),e.stopPropagation()}function m(e){e.preventDefault(),e.stopImmediatePropagation()}function v(t){if(!L){var s=t[0].currentStyle||window.getComputedStyle(t[0],null);L=e(document.createElement("div")).css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:s.fontSize,fontFamily:s.fontFamily,fontStyle:s.fontStyle,fontWeight:s.fontWeight,letterSpacing:s.letterSpacing,textTransform:s.textTransform,whiteSpace:"nowrap"}),L.attr("class","select2-sizer"),e(document.body).append(L)}return L.text(t.val()),L.width()}function b(t,s,i){var n,o,a=[];n=e.trim(t.attr("class")),n&&(n=""+n,e(n.split(/\s+/)).each2(function(){0===this.indexOf("select2-")&&a.push(this)})),n=e.trim(s.attr("class")),n&&(n=""+n,e(n.split(/\s+/)).each2(function(){0!==this.indexOf("select2-")&&(o=i(this),o&&a.push(o))})),t.attr("class",a.join(" "))}function w(e,s,n,o){var a=i(e.toUpperCase()).indexOf(i(s.toUpperCase())),r=s.length;return 0>a?(n.push(o(e)),t):(n.push(o(e.substring(0,a))),n.push("<span class='select2-match'>"),n.push(o(e.substring(a,a+r))),n.push("</span>"),n.push(o(e.substring(a+r,e.length))),t)}function C(e){var t={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};return(e+"").replace(/[&<>"'\/\\]/g,function(e){return t[e]})}function S(s){var i,n=null,o=s.quietMillis||100,a=s.url,r=this;return function(c){window.clearTimeout(i),i=window.setTimeout(function(){var i=s.data,o=a,l=s.transport||e.fn.select2.ajaxDefaults.transport,h={type:s.type||"GET",cache:s.cache||!1,jsonpCallback:s.jsonpCallback||t,dataType:s.dataType||"json"},u=e.extend({},e.fn.select2.ajaxDefaults.params,h);i=i?i.call(r,c.term,c.page,c.context):null,o="function"==typeof o?o.call(r,c.term,c.page,c.context):o,n&&"function"==typeof n.abort&&n.abort(),s.params&&(e.isFunction(s.params)?e.extend(u,s.params.call(r)):e.extend(u,s.params)),e.extend(u,{url:o,dataType:s.dataType,data:i,success:function(e){var t=s.results(e,c.page,c);c.callback(t)},error:function(e,t,s){var i={hasError:!0,jqXHR:e,textStatus:t,errorThrown:s};c.callback(i)}}),n=l.call(r,u)},o)}}function y(s){var i,n,o=s,a=function(e){return""+e.text};e.isArray(o)&&(n=o,o={results:n}),e.isFunction(o)===!1&&(n=o,o=function(){return n});var r=o();return r.text&&(a=r.text,e.isFunction(a)||(i=r.text,a=function(e){return e[i]})),function(s){var i,n=s.term,r={results:[]};return""===n?(s.callback(o()),t):(i=function(t,o){var r,c;if(t=t[0],t.children){r={};for(c in t)t.hasOwnProperty(c)&&(r[c]=t[c]);r.children=[],e(t.children).each2(function(e,t){i(t,r.children)}),(r.children.length||s.matcher(n,a(r),t))&&o.push(r)}else s.matcher(n,a(t),t)&&o.push(t)},e(o().results).each2(function(e,t){i(t,r.results)}),s.callback(r),t)}}function E(s){var i=e.isFunction(s);return function(n){var o=n.term,a={results:[]},r=i?s(n):s;e.isArray(r)&&(e(r).each(function(){var e=this.text!==t,s=e?this.text:this;(""===o||n.matcher(o,s))&&a.results.push(e?this:{id:this,text:this})}),n.callback(a))}}function x(t,s){if(e.isFunction(t))return!0;if(!t)return!1;if("string"==typeof t)return!0;throw Error(s+" must be a string, function, or falsy value")}function T(t,s){if(e.isFunction(t)){var i=Array.prototype.slice.call(arguments,2);return t.apply(s,i)}return t}function O(t){var s=0;return e.each(t,function(e,t){t.children?s+=O(t.children):s++}),s}function P(e,s,i,n){var o,r,c,l,h,u=e,d=!1;if(!n.createSearchChoice||!n.tokenSeparators||n.tokenSeparators.length<1)return t;for(;;){for(r=-1,c=0,l=n.tokenSeparators.length;l>c&&(h=n.tokenSeparators[c],r=e.indexOf(h),r<0);c++);if(0>r)break;if(o=e.substring(0,r),e=e.substring(r+h.length),o.length>0&&(o=n.createSearchChoice.call(this,o,s),o!==t&&null!==o&&n.id(o)!==t&&null!==n.id(o))){for(d=!1,c=0,l=s.length;l>c;c++)if(a(n.id(o),n.id(s[c]))){d=!0;break}d||i(o)}}return u!==e?e:t}function I(){var t=this;e.each(arguments,function(e,s){t[s].remove(),t[s]=null})}function k(t,s){var i=function(){};return i.prototype=new t,i.prototype.constructor=i,i.prototype.parent=t.prototype,i.prototype=e.extend(i.prototype,s),i}var A,R,D,H,L,N,M,U={x:0,y:0},F={TAB:9,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40,SHIFT:16,CTRL:17,ALT:18,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,BACKSPACE:8,DELETE:46,isArrow:function(e){switch(e=e.which?e.which:e){case F.LEFT:case F.RIGHT:case F.UP:case F.DOWN:return!0}return!1},isControl:function(e){var t=e.which;switch(t){case F.SHIFT:case F.CTRL:case F.ALT:return!0}return e.metaKey?!0:!1},isFunctionKey:function(e){return e=e.which?e.which:e,e>=112&&123>=e}},z="<div class='select2-measure-scrollbar'></div>",W={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};N=e(document),H=function(){var e=1;return function(){return e++}}(),A=k(Object,{bind:function(e){var t=this;return function(){e.apply(t,arguments)}},init:function(s){var i,n,a=".select2-results";this.opts=s=this.prepareOpts(s),this.id=s.id,s.element.data("select2")!==t&&null!==s.element.data("select2")&&s.element.data("select2").destroy(),this.container=this.createContainer(),this.liveRegion=e(".select2-hidden-accessible"),0==this.liveRegion.length&&(this.liveRegion=e("<span>",{role:"status","aria-live":"polite"}).addClass("select2-hidden-accessible").appendTo(document.body)),this.containerId="s2id_"+(s.element.attr("id")||"autogen"+H()),this.containerEventName=this.containerId.replace(/([.])/g,"_").replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g,"\\$1"),this.container.attr("id",this.containerId),this.container.attr("title",s.element.attr("title")),this.body=e(document.body),b(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.attr("style",s.element.attr("style")),this.container.css(T(s.containerCss,this.opts.element)),this.container.addClass(T(s.containerCssClass,this.opts.element)),this.elementTabIndex=this.opts.element.attr("tabindex"),this.opts.element.data("select2",this).attr("tabindex","-1").before(this.container).on("click.select2",g),this.container.data("select2",this),this.dropdown=this.container.find(".select2-drop"),b(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(T(s.dropdownCssClass,this.opts.element)),this.dropdown.data("select2",this),this.dropdown.on("click",g),this.results=i=this.container.find(a),this.search=n=this.container.find("input.select2-input"),this.queryCount=0,this.resultsPage=0,this.context=null,this.initContainer(),this.container.on("click",g),h(this.results),this.dropdown.on("mousemove-filtered",a,this.bind(this.highlightUnderEvent)),this.dropdown.on("touchstart touchmove touchend",a,this.bind(function(e){this._touchEvent=!0,this.highlightUnderEvent(e)})),this.dropdown.on("touchmove",a,this.bind(this.touchMoved)),this.dropdown.on("touchstart touchend",a,this.bind(this.clearTouchMoved)),this.dropdown.on("click",this.bind(function(){this._touchEvent&&(this._touchEvent=!1,this.selectHighlighted())})),d(80,this.results),this.dropdown.on("scroll-debounced",a,this.bind(this.loadMoreIfNeeded)),e(this.container).on("change",".select2-input",function(e){e.stopPropagation()}),e(this.dropdown).on("change",".select2-input",function(e){e.stopPropagation()}),e.fn.mousewheel&&i.mousewheel(function(e,t,s,n){var o=i.scrollTop();n>0&&0>=o-n?(i.scrollTop(0),g(e)):0>n&&i.get(0).scrollHeight-i.scrollTop()+n<=i.height()&&(i.scrollTop(i.get(0).scrollHeight-i.height()),g(e))}),l(n),n.on("keyup-change input paste",this.bind(this.updateResults)),n.on("focus",function(){n.addClass("select2-focused")}),n.on("blur",function(){n.removeClass("select2-focused")}),this.dropdown.on("mouseup",a,this.bind(function(t){e(t.target).closest(".select2-result-selectable").length>0&&(this.highlightUnderEvent(t),this.selectHighlighted(t))})),this.dropdown.on("click mouseup mousedown touchstart touchend focusin",function(e){e.stopPropagation()}),this.lastSearchTerm=t,e.isFunction(this.opts.initSelection)&&(this.initSelection(),this.monitorSource()),null!==s.maximumInputLength&&this.search.attr("maxlength",s.maximumInputLength);var r=s.element.prop("disabled");r===t&&(r=!1),this.enable(!r);var c=s.element.prop("readonly");c===t&&(c=!1),this.readonly(c),M=M||o(),this.autofocus=s.element.prop("autofocus"),s.element.prop("autofocus",!1),this.autofocus&&this.focus(),this.search.attr("placeholder",s.searchInputPlaceholder)},destroy:function(){var e=this.opts.element,s=e.data("select2"),i=this;this.close(),e.length&&e[0].detachEvent&&i._sync&&e.each(function(){i._sync&&this.detachEvent("onpropertychange",i._sync)}),this.propertyObserver&&(this.propertyObserver.disconnect(),this.propertyObserver=null),this._sync=null,s!==t&&(s.container.remove(),s.liveRegion.remove(),s.dropdown.remove(),e.removeData("select2").off(".select2"),e.is("input[type='hidden']")?e.css("display",""):(e.show().prop("autofocus",this.autofocus||!1),this.elementTabIndex?e.attr({tabindex:this.elementTabIndex}):e.removeAttr("tabindex"),e.show())),I.call(this,"container","liveRegion","dropdown","results","search")},optionToData:function(e){return e.is("option")?{id:e.prop("value"),text:e.text(),element:e.get(),css:e.attr("class"),disabled:e.prop("disabled"),locked:a(e.attr("locked"),"locked")||a(e.data("locked"),!0)}:e.is("optgroup")?{text:e.attr("label"),children:[],element:e.get(),css:e.attr("class")}:t},prepareOpts:function(s){var i,n,o,c,l=this;if(i=s.element,"select"===i.get(0).tagName.toLowerCase()&&(this.select=n=s.element),n&&e.each(["id","multiple","ajax","query","createSearchChoice","initSelection","data","tags"],function(){if(this in s)throw Error("Option '"+this+"' is not allowed for Select2 when attached to a <select> element.")}),s=e.extend({},{populateResults:function(i,n,o){var a,r=this.opts.id,c=this.liveRegion;(a=function(i,n,h){var u,d,p,f,g,m,v,b,w,C;i=s.sortResults(i,n,o);var S=[];for(u=0,d=i.length;d>u;u+=1)p=i[u],g=p.disabled===!0,f=!g&&r(p)!==t,m=p.children&&p.children.length>0,v=e("<li></li>"),v.addClass("select2-results-dept-"+h),v.addClass("select2-result"),v.addClass(f?"select2-result-selectable":"select2-result-unselectable"),g&&v.addClass("select2-disabled"),m&&v.addClass("select2-result-with-children"),v.addClass(l.opts.formatResultCssClass(p)),v.attr("role","presentation"),b=e(document.createElement("div")),b.addClass("select2-result-label"),b.attr("id","select2-result-label-"+H()),b.attr("role","option"),C=s.formatResult(p,b,o,l.opts.escapeMarkup),C!==t&&(b.html(C),v.append(b)),m&&(w=e("<ul></ul>"),w.addClass("select2-result-sub"),a(p.children,w,h+1),v.append(w)),v.data("select2-data",p),S.push(v[0]);n.append(S),c.text(s.formatMatches(i.length))})(n,i,0)}},e.fn.select2.defaults,s),"function"!=typeof s.id&&(o=s.id,s.id=function(e){return e[o]}),e.isArray(s.element.data("select2Tags"))){if("tags"in s)throw"tags specified as both an attribute 'data-select2-tags' and in options of Select2 "+s.element.attr("id");s.tags=s.element.data("select2Tags")}if(n?(s.query=this.bind(function(e){var s,n,o,a={results:[],more:!1},r=e.term;o=function(t,s){var i;t.is("option")?e.matcher(r,t.text(),t)&&s.push(l.optionToData(t)):t.is("optgroup")&&(i=l.optionToData(t),t.children().each2(function(e,t){o(t,i.children)}),i.children.length>0&&s.push(i))},s=i.children(),this.getPlaceholder()!==t&&s.length>0&&(n=this.getPlaceholderOption(),n&&(s=s.not(n))),s.each2(function(e,t){o(t,a.results)}),e.callback(a)}),s.id=function(e){return e.id}):"query"in s||("ajax"in s?(c=s.element.data("ajax-url"),c&&c.length>0&&(s.ajax.url=c),s.query=S.call(s.element,s.ajax)):"data"in s?s.query=y(s.data):"tags"in s&&(s.query=E(s.tags),s.createSearchChoice===t&&(s.createSearchChoice=function(t){return{id:e.trim(t),text:e.trim(t)}}),s.initSelection===t&&(s.initSelection=function(i,n){var o=[];e(r(i.val(),s.separator,s.transformVal)).each(function(){var i={id:this,text:this},n=s.tags;e.isFunction(n)&&(n=n()),e(n).each(function(){return a(this.id,i.id)?(i=this,!1):t}),o.push(i)}),n(o)}))),"function"!=typeof s.query)throw"query function not defined for Select2 "+s.element.attr("id");if("top"===s.createSearchChoicePosition)s.createSearchChoicePosition=function(e,t){e.unshift(t)};else if("bottom"===s.createSearchChoicePosition)s.createSearchChoicePosition=function(e,t){e.push(t)};else if("function"!=typeof s.createSearchChoicePosition)throw"invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function";return s},monitorSource:function(){var s,i=this.opts.element,n=this;i.on("change.select2",this.bind(function(){this.opts.element.data("select2-change-triggered")!==!0&&this.initSelection()})),this._sync=this.bind(function(){var e=i.prop("disabled");e===t&&(e=!1),this.enable(!e);var s=i.prop("readonly");s===t&&(s=!1),this.readonly(s),this.container&&(b(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.addClass(T(this.opts.containerCssClass,this.opts.element))),this.dropdown&&(b(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(T(this.opts.dropdownCssClass,this.opts.element)))}),i.length&&i[0].attachEvent&&i.each(function(){this.attachEvent("onpropertychange",n._sync)}),s=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver,s!==t&&(this.propertyObserver&&(delete this.propertyObserver,this.propertyObserver=null),this.propertyObserver=new s(function(t){e.each(t,n._sync)}),this.propertyObserver.observe(i.get(0),{attributes:!0,subtree:!1}))},triggerSelect:function(t){var s=e.Event("select2-selecting",{val:this.id(t),object:t,choice:t});return this.opts.element.trigger(s),!s.isDefaultPrevented()},triggerChange:function(t){t=t||{},t=e.extend({},t,{type:"change",val:this.val()}),this.opts.element.data("select2-change-triggered",!0),this.opts.element.trigger(t),this.opts.element.data("select2-change-triggered",!1),this.opts.element.click(),this.opts.blurOnChange&&this.opts.element.blur()},isInterfaceEnabled:function(){return this.enabledInterface===!0},enableInterface:function(){var e=this._enabled&&!this._readonly,t=!e;return e===this.enabledInterface?!1:(this.container.toggleClass("select2-container-disabled",t),this.close(),this.enabledInterface=e,!0)},enable:function(e){e===t&&(e=!0),this._enabled!==e&&(this._enabled=e,this.opts.element.prop("disabled",!e),this.enableInterface())},disable:function(){this.enable(!1)},readonly:function(e){e===t&&(e=!1),this._readonly!==e&&(this._readonly=e,this.opts.element.prop("readonly",e),this.enableInterface())},opened:function(){return this.container?this.container.hasClass("select2-dropdown-open"):!1},positionDropdown:function(){var t,s,i,n,o,a=this.dropdown,r=this.container,c=r.offset(),l=r.outerHeight(!1),h=r.outerWidth(!1),u=a.outerHeight(!1),d=e(window),p=d.width(),f=d.height(),g=d.scrollLeft()+p,m=d.scrollTop()+f,v=c.top+l,b=c.left,w=m>=v+u,C=c.top-u>=d.scrollTop(),S=a.outerWidth(!1),y=function(){return g>=b+S},E=function(){return c.left+g+r.outerWidth(!1)>S},x=a.hasClass("select2-drop-above");x?(s=!0,!C&&w&&(i=!0,s=!1)):(s=!1,!w&&C&&(i=!0,s=!0)),i&&(a.hide(),c=this.container.offset(),l=this.container.outerHeight(!1),h=this.container.outerWidth(!1),u=a.outerHeight(!1),g=d.scrollLeft()+p,m=d.scrollTop()+f,v=c.top+l,b=c.left,S=a.outerWidth(!1),a.show(),this.focusSearch()),this.opts.dropdownAutoWidth?(o=e(".select2-results",a)[0],a.addClass("select2-drop-auto-width"),a.css("width",""),S=a.outerWidth(!1)+(o.scrollHeight===o.clientHeight?0:M.width),S>h?h=S:S=h,u=a.outerHeight(!1)):this.container.removeClass("select2-drop-auto-width"),"static"!==this.body.css("position")&&(t=this.body.offset(),v-=t.top,b-=t.left),!y()&&E()&&(b=c.left+this.container.outerWidth(!1)-S),n={left:b,width:h},s?(this.container.addClass("select2-drop-above"),a.addClass("select2-drop-above"),u=a.outerHeight(!1),n.top=c.top-u,n.bottom="auto"):(n.top=v,n.bottom="auto",this.container.removeClass("select2-drop-above"),a.removeClass("select2-drop-above")),n=e.extend(n,T(this.opts.dropdownCss,this.opts.element)),a.css(n)},shouldOpen:function(){var t;return this.opened()?!1:this._enabled===!1||this._readonly===!0?!1:(t=e.Event("select2-opening"),this.opts.element.trigger(t),!t.isDefaultPrevented())},clearDropdownAlignmentPreference:function(){this.container.removeClass("select2-drop-above"),this.dropdown.removeClass("select2-drop-above")},open:function(){return this.shouldOpen()?(this.opening(),N.on("mousemove.select2Event",function(e){U.x=e.pageX,U.y=e.pageY}),!0):!1},opening:function(){var t,i=this.containerEventName,n="scroll."+i,o="resize."+i,a="orientationchange."+i;this.container.addClass("select2-dropdown-open").addClass("select2-container-active"),this.clearDropdownAlignmentPreference(),this.dropdown[0]!==this.body.children().last()[0]&&this.dropdown.detach().appendTo(this.body),t=e("#select2-drop-mask"),0===t.length&&(t=e(document.createElement("div")),t.attr("id","select2-drop-mask").attr("class","select2-drop-mask"),t.hide(),t.appendTo(this.body),t.on("mousedown touchstart click",function(i){s(t);var n,o=e("#select2-drop");o.length>0&&(n=o.data("select2"),n.opts.selectOnBlur&&n.selectHighlighted({noFocus:!0}),n.close(),i.preventDefault(),i.stopPropagation())})),this.dropdown.prev()[0]!==t[0]&&this.dropdown.before(t),e("#select2-drop").removeAttr("id"),this.dropdown.attr("id","select2-drop"),t.show(),this.positionDropdown(),this.dropdown.show(),this.positionDropdown(),this.dropdown.addClass("select2-drop-active");var r=this;this.container.parents().add(window).each(function(){e(this).on(o+" "+n+" "+a,function(){r.opened()&&r.positionDropdown()})})},close:function(){if(this.opened()){var t=this.containerEventName,s="scroll."+t,i="resize."+t,n="orientationchange."+t;this.container.parents().add(window).each(function(){e(this).off(s).off(i).off(n)}),this.clearDropdownAlignmentPreference(),e("#select2-drop-mask").hide(),this.dropdown.removeAttr("id"),this.dropdown.hide(),this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active"),this.results.empty(),N.off("mousemove.select2Event"),this.clearSearch(),this.search.removeClass("select2-active"),this.search.removeAttr("aria-activedescendant"),this.opts.element.trigger(e.Event("select2-close"))}},externalSearch:function(e){this.open(),this.search.val(e),this.updateResults(!1)},clearSearch:function(){},prefillNextSearchTerm:function(){if(""!==this.search.val())return!1;var e=this.opts.nextSearchTerm(this.data(),this.lastSearchTerm);return e!==t?(this.search.val(e),this.search.select(),!0):!1},getMaximumSelectionSize:function(){return T(this.opts.maximumSelectionSize,this.opts.element)},ensureHighlightVisible:function(){var s,i,n,o,a,r,c,l,h=this.results;if(i=this.highlight(),i>=0){if(0==i)return h.scrollTop(0),t;s=this.findHighlightableChoices().find(".select2-result-label"),n=e(s[i]),l=(n.offset()||{}).top||0,o=l+n.outerHeight(!0),i===s.length-1&&(c=h.find("li.select2-more-results"),c.length>0&&(o=c.offset().top+c.outerHeight(!0))),a=h.offset().top+h.outerHeight(!1),o>a&&h.scrollTop(h.scrollTop()+(o-a)),r=l-h.offset().top,0>r&&"none"!=n.css("display")&&h.scrollTop(h.scrollTop()+r)}},findHighlightableChoices:function(){return this.results.find(".select2-result-selectable:not(.select2-disabled):not(.select2-selected)")},moveHighlight:function(t){for(var s=this.findHighlightableChoices(),i=this.highlight();i>-1&&i<s.length;){i+=t;var n=e(s[i]);if(n.hasClass("select2-result-selectable")&&!n.hasClass("select2-disabled")&&!n.hasClass("select2-selected")){this.highlight(i);break}}},highlight:function(s){var i,o,a=this.findHighlightableChoices();return 0===arguments.length?n(a.filter(".select2-highlighted")[0],a.get()):(s<a.length||(s=a.length-1),0>s&&(s=0),this.removeHighlight(),i=e(a[s]),i.addClass("select2-highlighted"),this.search.attr("aria-activedescendant",i.find(".select2-result-label").attr("id")),this.ensureHighlightVisible(),this.liveRegion.text(i.text()),o=i.data("select2-data"),o&&this.opts.element.trigger({type:"select2-highlight",val:this.id(o),choice:o}),t)},removeHighlight:function(){this.results.find(".select2-highlighted").removeClass("select2-highlighted")},touchMoved:function(){this._touchMoved=!0},clearTouchMoved:function(){this._touchMoved=!1},countSelectableResults:function(){return this.findHighlightableChoices().length},highlightUnderEvent:function(t){var s=e(t.target).closest(".select2-result-selectable");if(s.length>0&&!s.is(".select2-highlighted")){var i=this.findHighlightableChoices();this.highlight(i.index(s))}else 0==s.length&&this.removeHighlight()},loadMoreIfNeeded:function(){var e,t=this.results,s=t.find("li.select2-more-results"),i=this.resultsPage+1,n=this,o=this.search.val(),a=this.context;0!==s.length&&(e=s.offset().top-t.offset().top-t.height(),e>this.opts.loadMorePadding||(s.addClass("select2-active"),this.opts.query({element:this.opts.element,term:o,page:i,context:a,matcher:this.opts.matcher,callback:this.bind(function(e){n.opened()&&(n.opts.populateResults.call(this,t,e.results,{term:o,page:i,context:a}),n.postprocessResults(e,!1,!1),e.more===!0?(s.detach().appendTo(t).html(n.opts.escapeMarkup(T(n.opts.formatLoadMore,n.opts.element,i+1))),window.setTimeout(function(){n.loadMoreIfNeeded()},10)):s.remove(),n.positionDropdown(),n.resultsPage=i,n.context=e.context,this.opts.element.trigger({type:"select2-loaded",items:e}))})})))},tokenize:function(){},updateResults:function(s){function i(){l.removeClass("select2-active"),d.positionDropdown(),d.liveRegion.text(h.find(".select2-no-results,.select2-selection-limit,.select2-searching").length?h.text():d.opts.formatMatches(h.find('.select2-result-selectable:not(".select2-selected")').length))}function n(e){h.html(e),i()}var o,r,c,l=this.search,h=this.results,u=this.opts,d=this,p=l.val(),f=e.data(this.container,"select2-last-term");if((s===!0||!f||!a(p,f))&&(e.data(this.container,"select2-last-term",p),s===!0||this.showSearchInput!==!1&&this.opened())){c=++this.queryCount;var g=this.getMaximumSelectionSize();if(g>=1&&(o=this.data(),e.isArray(o)&&o.length>=g&&x(u.formatSelectionTooBig,"formatSelectionTooBig")))return n("<li class='select2-selection-limit'>"+T(u.formatSelectionTooBig,u.element,g)+"</li>"),t;if(l.val().length<u.minimumInputLength)return n(x(u.formatInputTooShort,"formatInputTooShort")?"<li class='select2-no-results'>"+T(u.formatInputTooShort,u.element,l.val(),u.minimumInputLength)+"</li>":""),s&&this.showSearch&&this.showSearch(!0),t;if(u.maximumInputLength&&l.val().length>u.maximumInputLength)return n(x(u.formatInputTooLong,"formatInputTooLong")?"<li class='select2-no-results'>"+T(u.formatInputTooLong,u.element,l.val(),u.maximumInputLength)+"</li>":""),t;u.formatSearching&&0===this.findHighlightableChoices().length&&n("<li class='select2-searching'>"+T(u.formatSearching,u.element)+"</li>"),l.addClass("select2-active"),this.removeHighlight(),r=this.tokenize(),r!=t&&null!=r&&l.val(r),this.resultsPage=1,u.query({element:u.element,term:l.val(),page:this.resultsPage,context:null,matcher:u.matcher,callback:this.bind(function(o){var r;if(c==this.queryCount){if(!this.opened())return this.search.removeClass("select2-active"),t;if(o.hasError!==t&&x(u.formatAjaxError,"formatAjaxError"))return n("<li class='select2-ajax-error'>"+T(u.formatAjaxError,u.element,o.jqXHR,o.textStatus,o.errorThrown)+"</li>"),t;
+if(this.context=o.context===t?null:o.context,this.opts.createSearchChoice&&""!==l.val()&&(r=this.opts.createSearchChoice.call(d,l.val(),o.results),r!==t&&null!==r&&d.id(r)!==t&&null!==d.id(r)&&0===e(o.results).filter(function(){return a(d.id(this),d.id(r))}).length&&this.opts.createSearchChoicePosition(o.results,r)),0===o.results.length&&x(u.formatNoMatches,"formatNoMatches"))return n("<li class='select2-no-results'>"+T(u.formatNoMatches,u.element,l.val())+"</li>"),this.showSearch&&this.showSearch(l.val()),t;h.empty(),d.opts.populateResults.call(this,h,o.results,{term:l.val(),page:this.resultsPage,context:null}),o.more===!0&&x(u.formatLoadMore,"formatLoadMore")&&(h.append("<li class='select2-more-results'>"+u.escapeMarkup(T(u.formatLoadMore,u.element,this.resultsPage))+"</li>"),window.setTimeout(function(){d.loadMoreIfNeeded()},10)),this.postprocessResults(o,s),i(),this.opts.element.trigger({type:"select2-loaded",items:o})}})})}},cancel:function(){this.close()},blur:function(){this.opts.selectOnBlur&&this.selectHighlighted({noFocus:!0}),this.close(),this.container.removeClass("select2-container-active"),this.search[0]===document.activeElement&&this.search.blur(),this.clearSearch(),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")},focusSearch:function(){p(this.search)},selectHighlighted:function(e){if(this._touchMoved)return this.clearTouchMoved(),t;var s=this.highlight(),i=this.results.find(".select2-highlighted"),n=i.closest(".select2-result").data("select2-data");n?(this.highlight(s),this.onSelect(n,e)):e&&e.noFocus&&this.close()},getPlaceholder:function(){var e;return this.opts.element.attr("placeholder")||this.opts.element.attr("data-placeholder")||this.opts.element.data("placeholder")||this.opts.placeholder||((e=this.getPlaceholderOption())!==t?e.text():t)},getPlaceholderOption:function(){if(this.select){var s=this.select.children("option").first();if(this.opts.placeholderOption!==t)return"first"===this.opts.placeholderOption&&s||"function"==typeof this.opts.placeholderOption&&this.opts.placeholderOption(this.select);if(""===e.trim(s.text())&&""===s.val())return s}},initContainerWidth:function(){function t(){var t,s,i,n,o,a;if("off"===this.opts.width)return null;if("element"===this.opts.width)return 0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px";if("copy"===this.opts.width||"resolve"===this.opts.width){if(t=this.opts.element.attr("style"),"string"==typeof t)for(s=t.split(";"),n=0,o=s.length;o>n;n+=1)if(a=s[n].replace(/\s/g,""),i=a.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i),null!==i&&i.length>=1)return i[1];return"resolve"===this.opts.width?(t=this.opts.element.css("width"),t.indexOf("%")>0?t:0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px"):null}return e.isFunction(this.opts.width)?this.opts.width():this.opts.width}var s=t.call(this);null!==s&&this.container.css("width",s)}}),R=k(A,{createContainer:function(){var t=e(document.createElement("div")).attr({"class":"select2-container"}).html("<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>   <span class='select2-chosen'>&#160;</span><abbr class='select2-search-choice-close'></abbr>   <span class='select2-arrow' role='presentation'><b role='presentation'></b></span></a><label for='' class='select2-offscreen'></label><input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' /><div class='select2-drop select2-display-none'>   <div class='select2-search'>       <label for='' class='select2-offscreen'></label>       <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'       aria-autocomplete='list' />   </div>   <ul class='select2-results' role='listbox'>   </ul></div>");return t},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.focusser.prop("disabled",!this.isInterfaceEnabled())},opening:function(){var t,s,i;this.opts.minimumResultsForSearch<0||this.showSearch(!0),this.parent.opening.apply(this,arguments),this.showSearchInput!==!1&&this.search.val(this.focusser.val()),this.opts.shouldFocusInput(this)&&(this.search.focus(),t=this.search.get(0),t.createTextRange?(s=t.createTextRange(),s.collapse(!1),s.select()):t.setSelectionRange&&(i=this.search.val().length,t.setSelectionRange(i,i))),this.prefillNextSearchTerm(),this.focusser.prop("disabled",!0).val(""),this.updateResults(!0),this.opts.element.trigger(e.Event("select2-open"))},close:function(){this.opened()&&(this.parent.close.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},focus:function(){this.opened()?this.close():(this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},isFocused:function(){return this.container.hasClass("select2-container-active")},cancel:function(){this.parent.cancel.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus()},destroy:function(){e("label[for='"+this.focusser.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments),I.call(this,"selection","focusser")},initContainer:function(){var i,n,o=this.container,a=this.dropdown,r=H();this.showSearch(this.opts.minimumResultsForSearch<0?!1:!0),this.selection=i=o.find(".select2-choice"),this.focusser=o.find(".select2-focusser"),i.find(".select2-chosen").attr("id","select2-chosen-"+r),this.focusser.attr("aria-labelledby","select2-chosen-"+r),this.results.attr("id","select2-results-"+r),this.search.attr("aria-owns","select2-results-"+r),this.focusser.attr("id","s2id_autogen"+r),n=e("label[for='"+this.opts.element.attr("id")+"']"),this.opts.element.on("focus.select2",this.bind(function(){this.focus()})),this.focusser.prev().text(n.text()).attr("for",this.focusser.attr("id"));var c=this.opts.element.attr("title");this.opts.element.attr("title",c||n.text()),this.focusser.attr("tabindex",this.elementTabIndex),this.search.attr("id",this.focusser.attr("id")+"_search"),this.search.prev().text(e("label[for='"+this.focusser.attr("id")+"']").text()).attr("for",this.search.attr("id")),this.search.on("keydown",this.bind(function(e){if(this.isInterfaceEnabled()&&229!=e.keyCode){if(e.which===F.PAGE_UP||e.which===F.PAGE_DOWN)return g(e),t;switch(e.which){case F.UP:case F.DOWN:return this.moveHighlight(e.which===F.UP?-1:1),g(e),t;case F.ENTER:return this.selectHighlighted(),g(e),t;case F.TAB:return this.selectHighlighted({noFocus:!0}),t;case F.ESC:return this.cancel(e),g(e),t}}})),this.search.on("blur",this.bind(function(){document.activeElement===this.body.get(0)&&window.setTimeout(this.bind(function(){this.opened()&&this.results&&this.results.length>1&&this.search.focus()}),0)})),this.focusser.on("keydown",this.bind(function(e){if(this.isInterfaceEnabled()&&e.which!==F.TAB&&!F.isControl(e)&&!F.isFunctionKey(e)&&e.which!==F.ESC){if(this.opts.openOnEnter===!1&&e.which===F.ENTER)return g(e),t;if(e.which==F.DOWN||e.which==F.UP||e.which==F.ENTER&&this.opts.openOnEnter){if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey)return;return this.open(),g(e),t}return e.which==F.DELETE||e.which==F.BACKSPACE?(this.opts.allowClear&&this.clear(),g(e),t):t}})),l(this.focusser),this.focusser.on("keyup-change input",this.bind(function(e){if(this.opts.minimumResultsForSearch>=0){if(e.stopPropagation(),this.opened())return;this.open()}})),i.on("mousedown touchstart","abbr",this.bind(function(e){this.isInterfaceEnabled()&&(this.clear(),m(e),this.close(),this.selection&&this.selection.focus())})),i.on("mousedown touchstart",this.bind(function(t){s(i),this.container.hasClass("select2-container-active")||this.opts.element.trigger(e.Event("select2-focus")),this.opened()?this.close():this.isInterfaceEnabled()&&this.open(),g(t)})),a.on("mousedown touchstart",this.bind(function(){this.opts.shouldFocusInput(this)&&this.search.focus()})),i.on("focus",this.bind(function(e){g(e)})),this.focusser.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(e.Event("select2-focus")),this.container.addClass("select2-container-active")})).on("blur",this.bind(function(){this.opened()||(this.container.removeClass("select2-container-active"),this.opts.element.trigger(e.Event("select2-blur")))})),this.search.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(e.Event("select2-focus")),this.container.addClass("select2-container-active")})),this.initContainerWidth(),this.opts.element.hide(),this.setPlaceholder()},clear:function(t){var s=this.selection.data("select2-data");if(s){var i=e.Event("select2-clearing");if(this.opts.element.trigger(i),i.isDefaultPrevented())return;var n=this.getPlaceholderOption();this.opts.element.val(n?n.val():""),this.selection.find(".select2-chosen").empty(),this.selection.removeData("select2-data"),this.setPlaceholder(),t!==!1&&(this.opts.element.trigger({type:"select2-removed",val:this.id(s),choice:s}),this.triggerChange({removed:s}))}},initSelection:function(){if(this.isPlaceholderOptionSelected())this.updateSelection(null),this.close(),this.setPlaceholder();else{var e=this;this.opts.initSelection.call(null,this.opts.element,function(s){s!==t&&null!==s&&(e.updateSelection(s),e.close(),e.setPlaceholder(),e.lastSearchTerm=e.search.val())})}},isPlaceholderOptionSelected:function(){var e;return this.getPlaceholder()===t?!1:(e=this.getPlaceholderOption())!==t&&e.prop("selected")||""===this.opts.element.val()||this.opts.element.val()===t||null===this.opts.element.val()},prepareOpts:function(){var t=this.parent.prepareOpts.apply(this,arguments),s=this;return"select"===t.element.get(0).tagName.toLowerCase()?t.initSelection=function(e,t){var i=e.find("option").filter(function(){return this.selected&&!this.disabled});t(s.optionToData(i))}:"data"in t&&(t.initSelection=t.initSelection||function(s,i){var n=s.val(),o=null;t.query({matcher:function(e,s,i){var r=a(n,t.id(i));return r&&(o=i),r},callback:e.isFunction(i)?function(){i(o)}:e.noop})}),t},getPlaceholder:function(){return this.select&&this.getPlaceholderOption()===t?t:this.parent.getPlaceholder.apply(this,arguments)},setPlaceholder:function(){var e=this.getPlaceholder();if(this.isPlaceholderOptionSelected()&&e!==t){if(this.select&&this.getPlaceholderOption()===t)return;this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(e)),this.selection.addClass("select2-default"),this.container.removeClass("select2-allowclear")}},postprocessResults:function(s,i,n){var o=0,r=this;if(this.findHighlightableChoices().each2(function(e,s){return a(r.id(s.data("select2-data")),r.opts.element.val())?(o=e,!1):t}),n!==!1&&this.highlight(i!==!0||0>o?0:o),i===!0){var c=0,l=this.opts.minimumResultsForSearch;c=e(this.opts.element).is("select")?e("option",this.opts.element).length:O(s.results),0>l||this.showSearch(c>=l)}},showSearch:function(t){this.showSearchInput!==t&&(this.showSearchInput=t,this.dropdown.find(".select2-search").toggleClass("select2-search-hidden",!t),this.dropdown.find(".select2-search").toggleClass("select2-offscreen",!t),e(this.dropdown,this.container).toggleClass("select2-with-searchbox",t))},onSelect:function(e,t){if(this.triggerSelect(e)){var s=this.opts.element.val(),i=this.data();this.opts.element.val(this.id(e)),this.updateSelection(e),this.opts.element.trigger({type:"select2-selected",val:this.id(e),choice:e}),this.lastSearchTerm=this.search.val(),this.close(),t&&t.noFocus||!this.opts.shouldFocusInput(this)||this.focusser.focus(),a(s,this.id(e))||this.triggerChange({added:e,removed:i})}},updateSelection:function(e){var s,i,n=this.selection.find(".select2-chosen");this.selection.data("select2-data",e),n.empty(),null!==e&&(s=this.opts.formatSelection(e,n,this.opts.escapeMarkup)),s!==t&&n.append(s),i=this.opts.formatSelectionCssClass(e,n),i!==t&&n.addClass(i),this.selection.removeClass("select2-default"),this.opts.allowClear&&this.getPlaceholder()!==t&&this.container.addClass("select2-allowclear")},val:function(){var e,s=!1,i=null,n=this,o=this.data();if(0===arguments.length)return this.opts.element.val();if(e=arguments[0],arguments.length>1&&(s=arguments[1]),this.select)this.select.val(e).find("option").filter(function(){return this.selected}).each2(function(e,t){return i=n.optionToData(t),!1}),this.updateSelection(i),this.setPlaceholder(),s&&this.triggerChange({added:i,removed:o});else{if(!e&&0!==e)return this.clear(s),t;if(this.opts.initSelection===t)throw Error("cannot call val() if initSelection() is not defined");this.opts.element.val(e),this.opts.initSelection(this.opts.element,function(e){n.opts.element.val(e?n.id(e):""),n.updateSelection(e),n.setPlaceholder(),s&&n.triggerChange({added:e,removed:o})})}},clearSearch:function(){this.search.val(""),this.focusser.val("")},data:function(e){var s,i=!1;return 0===arguments.length?(s=this.selection.data("select2-data"),s==t&&(s=null),s):(arguments.length>1&&(i=arguments[1]),e?(s=this.data(),this.opts.element.val(e?this.id(e):""),this.updateSelection(e),i&&this.triggerChange({added:e,removed:s})):this.clear(i),t)}}),D=k(A,{createContainer:function(){var t=e(document.createElement("div")).attr({"class":"select2-container select2-container-multi"}).html("<ul class='select2-choices'>  <li class='select2-search-field'>    <label for='' class='select2-offscreen'></label>    <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>  </li></ul><div class='select2-drop select2-drop-multi select2-display-none'>   <ul class='select2-results'>   </ul></div>");return t},prepareOpts:function(){var t=this.parent.prepareOpts.apply(this,arguments),s=this;return"select"===t.element.get(0).tagName.toLowerCase()?t.initSelection=function(e,t){var i=[];e.find("option").filter(function(){return this.selected&&!this.disabled}).each2(function(e,t){i.push(s.optionToData(t))}),t(i)}:"data"in t&&(t.initSelection=t.initSelection||function(s,i){var n=r(s.val(),t.separator,t.transformVal),o=[];t.query({matcher:function(s,i,r){var c=e.grep(n,function(e){return a(e,t.id(r))}).length;return c&&o.push(r),c},callback:e.isFunction(i)?function(){for(var e=[],s=0;s<n.length;s++)for(var r=n[s],c=0;c<o.length;c++){var l=o[c];if(a(r,t.id(l))){e.push(l),o.splice(c,1);break}}i(e)}:e.noop})}),t},selectChoice:function(e){var t=this.container.find(".select2-search-choice-focus");t.length&&e&&e[0]==t[0]||(t.length&&this.opts.element.trigger("choice-deselected",t),t.removeClass("select2-search-choice-focus"),e&&e.length&&(this.close(),e.addClass("select2-search-choice-focus"),this.opts.element.trigger("choice-selected",e)))},destroy:function(){e("label[for='"+this.search.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments),I.call(this,"searchContainer","selection")},initContainer:function(){var s,i=".select2-choices";this.searchContainer=this.container.find(".select2-search-field"),this.selection=s=this.container.find(i);var n=this;this.selection.on("click",".select2-container:not(.select2-container-disabled) .select2-search-choice:not(.select2-locked)",function(){n.search[0].focus(),n.selectChoice(e(this))}),this.search.attr("id","s2id_autogen"+H()),this.search.prev().text(e("label[for='"+this.opts.element.attr("id")+"']").text()).attr("for",this.search.attr("id")),this.opts.element.on("focus.select2",this.bind(function(){this.focus()})),this.search.on("input paste",this.bind(function(){this.search.attr("placeholder")&&0==this.search.val().length||this.isInterfaceEnabled()&&(this.opened()||this.open())})),this.search.attr("tabindex",this.elementTabIndex),this.keydowns=0,this.search.on("keydown",this.bind(function(e){if(this.isInterfaceEnabled()){++this.keydowns;var i=s.find(".select2-search-choice-focus"),n=i.prev(".select2-search-choice:not(.select2-locked)"),o=i.next(".select2-search-choice:not(.select2-locked)"),a=f(this.search);if(i.length&&(e.which==F.LEFT||e.which==F.RIGHT||e.which==F.BACKSPACE||e.which==F.DELETE||e.which==F.ENTER)){var r=i;return e.which==F.LEFT&&n.length?r=n:e.which==F.RIGHT?r=o.length?o:null:e.which===F.BACKSPACE?this.unselect(i.first())&&(this.search.width(10),r=n.length?n:o):e.which==F.DELETE?this.unselect(i.first())&&(this.search.width(10),r=o.length?o:null):e.which==F.ENTER&&(r=null),this.selectChoice(r),g(e),r&&r.length||this.open(),t}if((e.which===F.BACKSPACE&&1==this.keydowns||e.which==F.LEFT)&&0==a.offset&&!a.length)return this.selectChoice(s.find(".select2-search-choice:not(.select2-locked)").last()),g(e),t;if(this.selectChoice(null),this.opened())switch(e.which){case F.UP:case F.DOWN:return this.moveHighlight(e.which===F.UP?-1:1),g(e),t;case F.ENTER:return this.selectHighlighted(),g(e),t;case F.TAB:return this.selectHighlighted({noFocus:!0}),this.close(),t;case F.ESC:return this.cancel(e),g(e),t}if(e.which!==F.TAB&&!F.isControl(e)&&!F.isFunctionKey(e)&&e.which!==F.BACKSPACE&&e.which!==F.ESC){if(e.which===F.ENTER){if(this.opts.openOnEnter===!1)return;if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey)return}this.open(),(e.which===F.PAGE_UP||e.which===F.PAGE_DOWN)&&g(e),e.which===F.ENTER&&g(e)}}})),this.search.on("keyup",this.bind(function(){this.keydowns=0,this.resizeSearch()})),this.search.on("blur",this.bind(function(t){this.container.removeClass("select2-container-active"),this.search.removeClass("select2-focused"),this.selectChoice(null),this.opened()||this.clearSearch(),t.stopImmediatePropagation(),this.opts.element.trigger(e.Event("select2-blur"))})),this.container.on("click",i,this.bind(function(t){this.isInterfaceEnabled()&&(e(t.target).closest(".select2-search-choice").length>0||(this.selectChoice(null),this.clearPlaceholder(),this.container.hasClass("select2-container-active")||this.opts.element.trigger(e.Event("select2-focus")),this.open(),this.focusSearch(),t.preventDefault()))})),this.container.on("focus",i,this.bind(function(){this.isInterfaceEnabled()&&(this.container.hasClass("select2-container-active")||this.opts.element.trigger(e.Event("select2-focus")),this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"),this.clearPlaceholder())})),this.initContainerWidth(),this.opts.element.hide(),this.clearSearch()},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.search.prop("disabled",!this.isInterfaceEnabled())},initSelection:function(){if(""===this.opts.element.val()&&""===this.opts.element.text()&&(this.updateSelection([]),this.close(),this.clearSearch()),this.select||""!==this.opts.element.val()){var e=this;this.opts.initSelection.call(null,this.opts.element,function(s){s!==t&&null!==s&&(e.updateSelection(s),e.close(),e.clearSearch())})}},clearSearch:function(){var e=this.getPlaceholder(),s=this.getMaxSearchWidth();e!==t&&0===this.getVal().length&&this.search.hasClass("select2-focused")===!1?(this.search.val(e).addClass("select2-default"),this.search.width(s>0?s:this.container.css("width"))):this.search.val("").width(10)},clearPlaceholder:function(){this.search.hasClass("select2-default")&&this.search.val("").removeClass("select2-default")},opening:function(){this.clearPlaceholder(),this.resizeSearch(),this.parent.opening.apply(this,arguments),this.focusSearch(),this.prefillNextSearchTerm(),this.updateResults(!0),this.opts.shouldFocusInput(this)&&this.search.focus(),this.opts.element.trigger(e.Event("select2-open"))},close:function(){this.opened()&&this.parent.close.apply(this,arguments)},focus:function(){this.close(),this.search.focus()},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(t){var s={},i=[],n=this;e(t).each(function(){n.id(this)in s||(s[n.id(this)]=0,i.push(this))}),this.selection.find(".select2-search-choice").remove(),this.addSelectedChoice(i),n.postprocessResults()},tokenize:function(){var e=this.search.val();e=this.opts.tokenizer.call(this,e,this.data(),this.bind(this.onSelect),this.opts),null!=e&&e!=t&&(this.search.val(e),e.length>0&&this.open())},onSelect:function(e,t){this.triggerSelect(e)&&""!==e.text&&(this.addSelectedChoice(e),this.opts.element.trigger({type:"selected",val:this.id(e),choice:e}),this.lastSearchTerm=this.search.val(),this.clearSearch(),this.updateResults(),(this.select||!this.opts.closeOnSelect)&&this.postprocessResults(e,!1,this.opts.closeOnSelect===!0),this.opts.closeOnSelect?(this.close(),this.search.width(10)):this.countSelectableResults()>0?(this.search.width(10),this.resizeSearch(),this.getMaximumSelectionSize()>0&&this.val().length>=this.getMaximumSelectionSize()?this.updateResults(!0):this.prefillNextSearchTerm()&&this.updateResults(),this.positionDropdown()):(this.close(),this.search.width(10)),this.triggerChange({added:e}),t&&t.noFocus||this.focusSearch())},cancel:function(){this.close(),this.focusSearch()},addSelectedChoice:function(t){var s=this.getVal(),i=this;e(t).each(function(){s.push(i.createChoice(this))}),this.setVal(s)},createChoice:function(s){var i,n,o=!s.locked,a=e("<li class='select2-search-choice'>    <div></div>    <a href='#' class='select2-search-choice-close' tabindex='-1'></a></li>"),r=e("<li class='select2-search-choice select2-locked'><div></div></li>"),c=o?a:r,l=this.id(s);return i=this.opts.formatSelection(s,c.find("div"),this.opts.escapeMarkup),i!=t&&c.find("div").replaceWith(e("<div></div>").html(i)),n=this.opts.formatSelectionCssClass(s,c.find("div")),n!=t&&c.addClass(n),o&&c.find(".select2-search-choice-close").on("mousedown",g).on("click dblclick",this.bind(function(t){this.isInterfaceEnabled()&&(this.unselect(e(t.target)),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"),g(t),this.close(),this.focusSearch())})).on("focus",this.bind(function(){this.isInterfaceEnabled()&&(this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"))})),c.data("select2-data",s),c.insertBefore(this.searchContainer),l},unselect:function(t){var s,i,o=this.getVal();if(t=t.closest(".select2-search-choice"),0===t.length)throw"Invalid argument: "+t+". Must be .select2-search-choice";if(s=t.data("select2-data")){var a=e.Event("select2-removing");if(a.val=this.id(s),a.choice=s,this.opts.element.trigger(a),a.isDefaultPrevented())return!1;for(;(i=n(this.id(s),o))>=0;)o.splice(i,1),this.setVal(o),this.select&&this.postprocessResults();return t.remove(),this.opts.element.trigger({type:"select2-removed",val:this.id(s),choice:s}),this.triggerChange({removed:s}),!0}},postprocessResults:function(e,t,s){var i=this.getVal(),o=this.results.find(".select2-result"),a=this.results.find(".select2-result-with-children"),r=this;o.each2(function(e,t){var s=r.id(t.data("select2-data"));n(s,i)<0||(t.addClass("select2-selected"),t.find(".select2-result-selectable").addClass("select2-selected"))}),a.each2(function(e,t){t.is(".select2-result-selectable")||0!==t.find(".select2-result-selectable:not(.select2-selected)").length||t.addClass("select2-selected")}),-1==this.highlight()&&s!==!1&&this.opts.closeOnSelect===!0&&r.highlight(0),!this.opts.createSearchChoice&&!o.filter(".select2-result:not(.select2-selected)").length>0&&(!e||e&&!e.more&&0===this.results.find(".select2-no-results").length)&&x(r.opts.formatNoMatches,"formatNoMatches")&&this.results.append("<li class='select2-no-results'>"+T(r.opts.formatNoMatches,r.opts.element,r.search.val())+"</li>")},getMaxSearchWidth:function(){return this.selection.width()-c(this.search)},resizeSearch:function(){var e,t,s,i,n,o=c(this.search);e=v(this.search)+10,t=this.search.offset().left,s=this.selection.width(),i=this.selection.offset().left,n=s-(t-i)-o,e>n&&(n=s-o),40>n&&(n=s-o),n>0||(n=e),this.search.width(Math.floor(n))},getVal:function(){var e;return this.select?(e=this.select.val(),null===e?[]:e):(e=this.opts.element.val(),r(e,this.opts.separator,this.opts.transformVal))},setVal:function(t){if(this.select)this.select.val(t);else{var s=[],i={};e(t).each(function(){this in i||(s.push(this),i[this]=0)}),this.opts.element.val(0===s.length?"":s.join(this.opts.separator))}},buildChangeDetails:function(e,t){for(var t=t.slice(0),e=e.slice(0),s=0;s<t.length;s++)for(var i=0;i<e.length;i++)if(a(this.opts.id(t[s]),this.opts.id(e[i]))){t.splice(s,1),s--,e.splice(i,1);break}return{added:t,removed:e}},val:function(s,i){var n,o=this;if(0===arguments.length)return this.getVal();if(n=this.data(),n.length||(n=[]),!s&&0!==s)return this.opts.element.val(""),this.updateSelection([]),this.clearSearch(),i&&this.triggerChange({added:this.data(),removed:n}),t;if(this.setVal(s),this.select)this.opts.initSelection(this.select,this.bind(this.updateSelection)),i&&this.triggerChange(this.buildChangeDetails(n,this.data()));else{if(this.opts.initSelection===t)throw Error("val() cannot be called if initSelection() is not defined");this.opts.initSelection(this.opts.element,function(t){var s=e.map(t,o.id);o.setVal(s),o.updateSelection(t),o.clearSearch(),i&&o.triggerChange(o.buildChangeDetails(n,o.data()))})}this.clearSearch()},onSortStart:function(){if(this.select)throw Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");this.search.width(0),this.searchContainer.hide()},onSortEnd:function(){var t=[],s=this;this.searchContainer.show(),this.searchContainer.appendTo(this.searchContainer.parent()),this.resizeSearch(),this.selection.find(".select2-search-choice").each(function(){t.push(s.opts.id(e(this).data("select2-data")))}),this.setVal(t),this.triggerChange()},data:function(s,i){var n,o,a=this;return 0===arguments.length?this.selection.children(".select2-search-choice").map(function(){return e(this).data("select2-data")}).get():(o=this.data(),s||(s=[]),n=e.map(s,function(e){return a.opts.id(e)}),this.setVal(n),this.updateSelection(s),this.clearSearch(),i&&this.triggerChange(this.buildChangeDetails(o,this.data())),t)}}),e.fn.select2=function(){var s,i,o,a,r,c=Array.prototype.slice.call(arguments,0),l=["val","destroy","opened","open","close","focus","isFocused","container","dropdown","onSortStart","onSortEnd","enable","disable","readonly","positionDropdown","data","search"],h=["opened","isFocused","container","dropdown"],u=["val","data"],d={search:"externalSearch"};return this.each(function(){if(0===c.length||"object"==typeof c[0])s=0===c.length?{}:e.extend({},c[0]),s.element=e(this),"select"===s.element.get(0).tagName.toLowerCase()?r=s.element.prop("multiple"):(r=s.multiple||!1,"tags"in s&&(s.multiple=r=!0)),i=r?new D:new R,i.init(s);else{if("string"!=typeof c[0])throw"Invalid arguments to select2 plugin: "+c;if(n(c[0],l)<0)throw"Unknown method: "+c[0];if(a=t,i=e(this).data("select2"),i===t)return;if(o=c[0],"container"===o?a=i.container:"dropdown"===o?a=i.dropdown:(d[o]&&(o=d[o]),a=i[o].apply(i,c.slice(1))),n(c[0],h)>=0||n(c[0],u)>=0&&1==c.length)return!1}}),a===t?this:a},e.fn.select2.defaults={width:"copy",loadMorePadding:0,closeOnSelect:!0,openOnEnter:!0,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(e,t,s,i){var n=[];return w(this.text(e),s.term,n,i),n.join("")},transformVal:function(t){return e.trim(t)},formatSelection:function(e,s,i){return e?i(this.text(e)):t},sortResults:function(e){return e},formatResultCssClass:function(e){return e.css},formatSelectionCssClass:function(){return t},minimumResultsForSearch:0,minimumInputLength:0,maximumInputLength:null,maximumSelectionSize:0,id:function(e){return e==t?null:e.id},text:function(t){return t&&this.data&&this.data.text?e.isFunction(this.data.text)?this.data.text(t):t[this.data.text]:t.text},matcher:function(e,t){return i(""+t).toUpperCase().indexOf(i(""+e).toUpperCase())>=0},separator:",",tokenSeparators:[],tokenizer:P,escapeMarkup:C,blurOnChange:!1,selectOnBlur:!1,adaptContainerCssClass:function(e){return e},adaptDropdownCssClass:function(){return null},nextSearchTerm:function(){return t},searchInputPlaceholder:"",createSearchChoicePosition:"top",shouldFocusInput:function(e){var t="ontouchstart"in window||navigator.msMaxTouchPoints>0;return t&&e.opts.minimumResultsForSearch<0?!1:!0}},e.fn.select2.locales=[],e.fn.select2.locales.en={formatMatches:function(e){return 1===e?"One result is available, press enter to select it.":e+" results are available, use up and down arrow keys to navigate."},formatNoMatches:function(){return"No matches found"},formatAjaxError:function(){return"Loading failed"},formatInputTooShort:function(e,t){var s=t-e.length;return"Please enter "+s+" or more character"+(1==s?"":"s")},formatInputTooLong:function(e,t){var s=e.length-t;return"Please delete "+s+" character"+(1==s?"":"s")},formatSelectionTooBig:function(e){return"You can only select "+e+" item"+(1==e?"":"s")},formatLoadMore:function(){return"Loading more results…"},formatSearching:function(){return"Searching…"}},e.extend(e.fn.select2.defaults,e.fn.select2.locales.en),e.fn.select2.ajaxDefaults={transport:e.ajax,params:{type:"GET",cache:!1,dataType:"json"}}}(jQuery);
\ No newline at end of file
diff --git a/civicrm/civicrm-version.php b/civicrm/civicrm-version.php
index ff23b6923151bb60bd6f53f0d1ce7d85ee2b84e8..8fd88bb45a39ea5ac36a6e2b64d49210f1ccb1fd 100644
--- a/civicrm/civicrm-version.php
+++ b/civicrm/civicrm-version.php
@@ -1,7 +1,7 @@
 <?php
 function civicrmVersion( ) {
-  return array( 'version'  => '4.7.14',
+  return array( 'version'  => '4.7.15',
                 'cms'      => 'Wordpress',
-                'revision' => 'c58f2846ec' );
+                'revision' => 'cac5581ec7' );
 }
 
diff --git a/civicrm/composer.json b/civicrm/composer.json
index 64f2503d5ac45243daf757843a27796a385023a1..7351739d882a5f4cb546b230f9a260a09f7fe2f3 100644
--- a/civicrm/composer.json
+++ b/civicrm/composer.json
@@ -18,11 +18,11 @@
     "symfony/finder": "~2.5.0",
     "tecnickcom/tcpdf" : "6.2.*",
     "totten/ca-config": "~13.02",
-    "civicrm/civicrm-cxn-rpc": "~0.15.12.04",
     "zetacomponents/base": "1.7.*",
     "zetacomponents/mail": "dev-1.7-civi",
     "phpoffice/phpword": "^0.13.0",
-    "pear/Validate_Finance_CreditCard": "dev-master"
+    "pear/Validate_Finance_CreditCard": "dev-master",
+    "civicrm/civicrm-cxn-rpc": "~0.16.12.05"
   },
   "repositories": [
     {
diff --git a/civicrm/composer.lock b/civicrm/composer.lock
index d03ab98656fb480d5b5446423180718faf51ecf1..d24253a1efb2dc7b16218099aff3693883cf0178 100644
--- a/civicrm/composer.lock
+++ b/civicrm/composer.lock
@@ -4,25 +4,25 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "189ae04cf5b1ca1ee00d56a629a273c3",
-    "content-hash": "c2aba74bbb5b474831736b3e3bcbcb20",
+    "hash": "94c7ae299e411a3b9013da64e1232669",
+    "content-hash": "36ffd76fc5e7344ac6e587d11779ceeb",
     "packages": [
         {
             "name": "civicrm/civicrm-cxn-rpc",
-            "version": "v0.15.12.04",
+            "version": "v0.16.12.05",
             "source": {
                 "type": "git",
                 "url": "https://github.com/civicrm/civicrm-cxn-rpc.git",
-                "reference": "6e3a0f956860908a240758ab8c80a020549a6f03"
+                "reference": "e88e78dc491b7e8739a40231f46c2d4459347b12"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/civicrm/civicrm-cxn-rpc/zipball/6e3a0f956860908a240758ab8c80a020549a6f03",
-                "reference": "6e3a0f956860908a240758ab8c80a020549a6f03",
+                "url": "https://api.github.com/repos/civicrm/civicrm-cxn-rpc/zipball/e88e78dc491b7e8739a40231f46c2d4459347b12",
+                "reference": "e88e78dc491b7e8739a40231f46c2d4459347b12",
                 "shasum": ""
             },
             "require": {
-                "phpseclib/phpseclib": "0.3.*",
+                "phpseclib/phpseclib": "1.0.*",
                 "psr/log": "1.0.0"
             },
             "require-dev": {
@@ -45,7 +45,7 @@
                 }
             ],
             "description": "RPC library for CiviConnect",
-            "time": "2015-12-05 04:41:02"
+            "time": "2016-12-06 04:32:51"
         },
         {
             "name": "dompdf/dompdf",
@@ -469,16 +469,16 @@
         },
         {
             "name": "phpseclib/phpseclib",
-            "version": "0.3.10",
+            "version": "1.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpseclib/phpseclib.git",
-                "reference": "d15bba1edcc7c89e09cc74c5d961317a8b947bf4"
+                "reference": "38fa7332e96bcc546ce6eb5cbaa1168c96839393"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d15bba1edcc7c89e09cc74c5d961317a8b947bf4",
-                "reference": "d15bba1edcc7c89e09cc74c5d961317a8b947bf4",
+                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/38fa7332e96bcc546ce6eb5cbaa1168c96839393",
+                "reference": "38fa7332e96bcc546ce6eb5cbaa1168c96839393",
                 "shasum": ""
             },
             "require": {
@@ -488,19 +488,14 @@
                 "phing/phing": "~2.7",
                 "phpunit/phpunit": "~4.0",
                 "sami/sami": "~2.0",
-                "squizlabs/php_codesniffer": "~1.5"
+                "squizlabs/php_codesniffer": "~2.0"
             },
             "suggest": {
                 "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
                 "ext-mcrypt": "Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.",
-                "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 4.3.3."
+                "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 5.0.0."
             },
             "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "0.3-dev"
-                }
-            },
             "autoload": {
                 "psr-0": {
                     "Crypt": "phpseclib/",
@@ -510,6 +505,7 @@
                     "System": "phpseclib/"
                 },
                 "files": [
+                    "phpseclib/bootstrap.php",
                     "phpseclib/Crypt/Random.php"
                 ]
             },
@@ -540,6 +536,11 @@
                     "name": "Hans-Jürgen Petrich",
                     "email": "petrich@tronic-media.com",
                     "role": "Developer"
+                },
+                {
+                    "name": "Graham Campbell",
+                    "email": "graham@alt-three.com",
+                    "role": "Developer"
                 }
             ],
             "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
@@ -563,7 +564,7 @@
                 "x.509",
                 "x509"
             ],
-            "time": "2015-01-28 21:50:33"
+            "time": "2016-10-22 17:53:16"
         },
         {
             "name": "psr/log",
@@ -610,12 +611,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/config.git",
-                "reference": "d93bb29acfa5cff771cb4aa0fb4a97454ddb41e4"
+                "reference": "c7309e33b719433d5cf3845d0b5b9608609d8c8e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/config/zipball/d93bb29acfa5cff771cb4aa0fb4a97454ddb41e4",
-                "reference": "d93bb29acfa5cff771cb4aa0fb4a97454ddb41e4",
+                "url": "https://api.github.com/repos/symfony/config/zipball/c7309e33b719433d5cf3845d0b5b9608609d8c8e",
+                "reference": "c7309e33b719433d5cf3845d0b5b9608609d8c8e",
                 "shasum": ""
             },
             "require": {
diff --git a/civicrm/install/civicrm.php b/civicrm/install/civicrm.php
index c23bf6020b4d364aef7ed6c7f6145dc5a964829a..1e6c0b2cdd497f3f4cfd31d9a7571b9835eddf00 100644
--- a/civicrm/install/civicrm.php
+++ b/civicrm/install/civicrm.php
@@ -147,6 +147,13 @@ function civicrm_source($dsn, $fileName, $lineMode = FALSE) {
 
   require_once "$crmPath/packages/DB.php";
 
+  // CRM-19699 See also CRM_Core_DAO for PHP7 mysqli compatiblity.
+  // Duplicated here because this is not using CRM_Core_DAO directly
+  // and this function may be called directly from Drush.
+  if (!defined('DB_DSN_MODE')) {
+    define('DB_DSN_MODE', 'auto');
+  }
+
   $db = DB::connect($dsn);
   if (PEAR::isError($db)) {
     die("Cannot open $dsn: " . $db->getMessage());
diff --git a/civicrm/js/Common.js b/civicrm/js/Common.js
index 5969aa270ed8565f5603512b6484487aeccc3523..b2d7d461c053214eee04b600f403a31857124b69 100644
--- a/civicrm/js/Common.js
+++ b/civicrm/js/Common.js
@@ -237,6 +237,20 @@ if (!CRM.vars) CRM.vars = {};
     }
   };
 
+  var scriptsLoaded = {};
+  CRM.loadScript = function(url) {
+    if (!scriptsLoaded[url]) {
+      var script = document.createElement('script');
+      scriptsLoaded[url] = $.Deferred();
+      script.onload = function () {
+        scriptsLoaded[url].resolve();
+      };
+      script.src = url;
+      document.getElementsByTagName("head")[0].appendChild(script);
+    }
+    return scriptsLoaded[url];
+  };
+
   /**
    * Populate a select list, overwriting the existing options except for the placeholder.
    * @param select jquery selector - 1 or more select elements
@@ -443,6 +457,7 @@ if (!CRM.vars) CRM.vars = {};
         // Use select2 ajax helper instead of CRM.api3 because it provides more value
         ajax: {
           url: CRM.url('civicrm/ajax/rest'),
+          quietMillis: 300,
           data: function (input, page_num) {
             var params = getEntityRefApiParams($el);
             params.input = input;
diff --git a/civicrm/js/wysiwyg/crm.ckeditor.js b/civicrm/js/wysiwyg/crm.ckeditor.js
index 422ee5711aee0da603b4436815b73e3a3da95175..21446ee482c9a99a175ba1456c0b28890958875e 100644
--- a/civicrm/js/wysiwyg/crm.ckeditor.js
+++ b/civicrm/js/wysiwyg/crm.ckeditor.js
@@ -1,6 +1,5 @@
 // https://civicrm.org/licensing
 (function($, _) {
-  var scriptLoaded = false;
 
   function getInstance(item) {
     var name = $(item).attr("name"),
@@ -13,18 +12,9 @@
     }
   }
 
-  function loadScript(url) {
-    var deferred = $.Deferred(),
-      script = document.createElement('script');
-    script.onload = function() {deferred.resolve();};
-    script.src = url;
-    document.getElementsByTagName("head")[0].appendChild(script);
-    return deferred;
-  }
-
   CRM.wysiwyg.supportsFileUploads =  true;
 
-  CRM.wysiwyg.create = function(item) {
+  CRM.wysiwyg._create = function(item) {
     var deferred = $.Deferred();
 
     function onReady() {
@@ -94,10 +84,7 @@
       if (window.CKEDITOR) {
         initialize();
       } else {
-        if (scriptLoaded === false) {
-          scriptLoaded = loadScript(CRM.config.resourceBase + 'bower_components/ckeditor/ckeditor.js');
-        }
-        scriptLoaded.done(initialize);
+        CRM.loadScript(CRM.config.resourceBase + 'bower_components/ckeditor/ckeditor.js').done(initialize);
       }
     } else {
       deferred.reject();
diff --git a/civicrm/js/wysiwyg/crm.wysiwyg.js b/civicrm/js/wysiwyg/crm.wysiwyg.js
index 54c86e81454c1e0a633413fcf5931f8ac6ba7278..d61bcdea82e44f93356c89aaf42e594a624de7c7 100644
--- a/civicrm/js/wysiwyg/crm.wysiwyg.js
+++ b/civicrm/js/wysiwyg/crm.wysiwyg.js
@@ -3,9 +3,20 @@
   // This defines an interface which by default only handles plain textareas
   // A wysiwyg implementation can extend this by overriding as many of these functions as needed
   CRM.wysiwyg = {
-    supportsFileUploads: false,
-    create: function() {
-      return $.Deferred().resolve();
+    supportsFileUploads: !!CRM.config.wysisygScriptLocation,
+    create: function(item) {
+      var ret = $.Deferred();
+      // Lazy-load the wysiwyg js
+      if (CRM.config.wysisygScriptLocation) {
+        CRM.loadScript(CRM.config.wysisygScriptLocation).done(function() {
+          CRM.wysiwyg._create(item).done(function() {
+            ret.resolve();
+          });
+        });
+      } else {
+        ret.resolve();
+      }
+      return ret;
     },
     destroy: _.noop,
     updateElement: _.noop,
diff --git a/civicrm/packages/jquery/plugins/jquery.FormNavigate.js b/civicrm/packages/jquery/plugins/jquery.FormNavigate.js
deleted file mode 100644
index 056814c9d64dcf1b4dbd308ff5528c74fb21be0a..0000000000000000000000000000000000000000
--- a/civicrm/packages/jquery/plugins/jquery.FormNavigate.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * jQuery.FormNavigate.js
- * jQuery Form onChange Navigate Confirmation plugin
- * Browser Compatibility : IE 6.0, 7.0, 8.0; Firefox 2.0+;  Safari 3+; Opera 9+; Chrome 1+;
- *
- * Copyright (c) 2009 Law Ding Yong
- * 
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/mit-license.php
- *
- * See the file license.txt for copying permission.
- */
- 
- /**
-  * Documentation :
-  * ==================
-  *
-  * How to Use:
-  * $("YourForm").FormNavigate("YourMessage");
-  *  -- "YourForm" as Your Form ID $("#form") or any method to grab your form
-  *  -- "YourMessage" as Your onBeforeUnload Prompt Message Here
-  *
-  * This plugin handles onchange of input type of text, textarea, password, radio, checkbox, select and file to toggle on and off of window.onbeforeunload event.
-  * Users are able to configure the custom onBeforeUnload message.
-  */
-var global_formNavigate = true;		// Js Global Variable for onChange Flag
-(function($){
-    $.fn.FormNavigate = function(message) {
-        window.onbeforeunload = confirmExit;  
-        function confirmExit( event ) {  
-            if (global_formNavigate == true) {  event.cancelBubble = true;  }  else  { return message;  }
-        }
-        $(":input[type=text], :input[type='textarea'], :input[type='password'], :input[type='radio'], :input[type='checkbox'], :input[type='file'], select", this).change(function(){
-            global_formNavigate = false;
-        });
-        //to handle back button
-        $(":input[type='textarea']", this).keyup(function(){ 
-          global_formNavigate = false; 
-        }); 
-        $(":submit", this).click(function(){
-            global_formNavigate = true;
-        });
-        $(".token-input-list-facebook").bind( "DOMNodeRemoved DOMNodeInserted", function(){ 
-            global_formNavigate = false; 
-        });
-    }
-})(jQuery);
diff --git a/civicrm/packages/jquery/plugins/jquery.FormNavigate.min.js b/civicrm/packages/jquery/plugins/jquery.FormNavigate.min.js
deleted file mode 100644
index e5fb78dbd4b22d50dfc6574d682fe31caa57919e..0000000000000000000000000000000000000000
--- a/civicrm/packages/jquery/plugins/jquery.FormNavigate.min.js
+++ /dev/null
@@ -1 +0,0 @@
-var global_formNavigate=true;(function(e){e.fn.FormNavigate=function(t){function n(e){if(global_formNavigate==true){e.cancelBubble=true}else{return t}}window.onbeforeunload=n;e(":input[type=text], :input[type='textarea'], :input[type='password'], :input[type='radio'], :input[type='checkbox'], :input[type='file'], select",this).change(function(){global_formNavigate=false});e(":input[type='textarea']",this).keyup(function(){global_formNavigate=false});e(":submit",this).click(function(){global_formNavigate=true});e(".token-input-list-facebook").bind("DOMNodeRemoved DOMNodeInserted",function(){global_formNavigate=false})}})(jQuery)
diff --git a/civicrm/packages/jquery/plugins/jquery.civicrm-validate.js b/civicrm/packages/jquery/plugins/jquery.civicrm-validate.js
deleted file mode 100644
index bd770c20d58f4d70d3dbd4b9d3ddddc821952cc2..0000000000000000000000000000000000000000
--- a/civicrm/packages/jquery/plugins/jquery.civicrm-validate.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- *  Additional methods to extend jQuery Validation Plugin 1.8.0
- *  You can add validation methods here based on classes prefixed with crm_
- *  Example: class='crm_phone' is assigned to phone number fields
- *  To define phone validation for your site:
- *  jQuery.validator.addMethod("crm_phone", function(phone_number, element) { validation logic here }
- */
-
diff --git a/civicrm/packages/jquery/plugins/jquery.fixedPosition.js b/civicrm/packages/jquery/plugins/jquery.fixedPosition.js
deleted file mode 100644
index aa7d0102beffcadfacc128071a4e68bc4059a186..0000000000000000000000000000000000000000
--- a/civicrm/packages/jquery/plugins/jquery.fixedPosition.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- *  jQuery Fixed Position Plugin
- *  @requires jQuery v1.3
- *  http://www.socialembedded.com/labs
- *
- *  Copyright (c)  Hernan Amiune (hernan.amiune.com)
- *  Dual licensed under the MIT and GPL licenses:
- *  http://www.opensource.org/licenses/mit-license.php
- *  http://www.gnu.org/licenses/gpl.html
- * 
- *  Version: 1.0
- */
- 
-(function($){ $.fn.fixedPosition = function(options){
-
-    var defaults = {
-	  vpos: null,    // posible values: "top", "middle", "bottom". if it is null the original position is taken
-	  hpos: null     // posible values: "left", "center", "right". if it is null the original position is taken
-	};
-	
-    var options = $.extend(defaults, options);
-	
-	return this.each(function(index) {
-		
-		
-		var $this = $(this);
-		$this.css("position","absolute");
-		
-		if(options.vpos === "top"){
-		    $this.css("top","0");
-		}
-		else if(options.vpos === "middle"){
-		    $this.css("top",((parseInt($(window).height())/2)-($(this).height()/2))+"px");
-		}
-		else if(options.vpos === "bottom"){
-		    $this.css("bottom","0");
-		}
-		
-		if(options.hpos === "left"){
-		    $this.css("left","0");
-		}
-		else if(options.hpos === "center"){
-		    $this.css("left",((parseInt($(window).width())/2)-($(this).width()/2))+"px");
-		}
-		else if(options.hpos === "right"){
-		    $this.css("right","0");
-		}
-		
-		var top = parseInt($this.offset().top);
-		var left = parseInt($this.offset().left);
-		$(window).scroll(function () {
-			$this.css("top",top+$(document).scrollTop()).css("left",left+$(document).scrollLeft());
-		});
-	});
-
-  
-}})(jQuery);
\ No newline at end of file
diff --git a/civicrm/packages/jquery/plugins/jquery.tableHeader.js b/civicrm/packages/jquery/plugins/jquery.tableHeader.js
index 09f9dae1378b5b514f6139da09c72871f535a45c..fa63076ae203dccd15645a066f3764da384cbf44 100644
--- a/civicrm/packages/jquery/plugins/jquery.tableHeader.js
+++ b/civicrm/packages/jquery/plugins/jquery.tableHeader.js
@@ -1,26 +1,4 @@
-// +--------------------------------------------------------------------+
-// | CiviCRM version 4.7                                                |
-// +--------------------------------------------------------------------+
-// | Copyright CiviCRM LLC (c) 2004-2016                                |
-// +--------------------------------------------------------------------+
-// | This file is a part of CiviCRM.                                    |
-// |                                                                    |
-// | CiviCRM is free software; you can copy, modify, and distribute it  |
-// | under the terms of the GNU Affero General Public License           |
-// | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
-// |                                                                    |
-// | CiviCRM 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 Affero General Public License for more details.        |
-// |                                                                    |
-// | You should have received a copy of the GNU Affero General Public   |
-// | License and the CiviCRM Licensing Exception along                  |
-// | with this program; if not, contact CiviCRM LLC                     |
-// | at info[AT]civicrm[DOT]org. If you have questions about the        |
-// | GNU Affero General Public License or the licensing of CiviCRM,     |
-// | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
-// +--------------------------------------------------------------------+
+// https://civicrm.org/licensing
 (function($) {
 
 // Keep track of all header cells.
diff --git a/civicrm/release-notes.md b/civicrm/release-notes.md
index dfa0250315b12aaa3ef30ad1ea206aad2a5931da..31fb325c9147476263f1fc9f28719719e1a4c889 100644
--- a/civicrm/release-notes.md
+++ b/civicrm/release-notes.md
@@ -14,6 +14,14 @@ Other resources for identifying changes are:
     * https://github.com/civicrm/civicrm-joomla
     * https://github.com/civicrm/civicrm-wordpress
 
+## CiviCRM 4.7.15
+
+Released January 4, 2017
+
+- **[Features](release-notes/4.7.15.md#features)**
+- **[Bugs resolved](release-notes/4.7.15.md#bugs)**
+- **[Credits](release-notes/4.7.15.md#credits)**
+
 ## CiviCRM 4.7.14
 
 Released December 7, 2016
diff --git a/civicrm/release-notes/4.7.15.md b/civicrm/release-notes/4.7.15.md
new file mode 100644
index 0000000000000000000000000000000000000000..52e86aa73358df460d4b0014b0075d519068e472
--- /dev/null
+++ b/civicrm/release-notes/4.7.15.md
@@ -0,0 +1,338 @@
+# CiviCRM 4.7.15
+
+Released January 4, 2017
+
+- **[Features](#features)**
+- **[Bugs resolved](#bugs)**
+- **[Credits](#credits)**
+
+## <a name="features"></a>Features
+
+### Core CiviCRM
+
+- **[CRM-17410](https://issues.civicrm.org/jira/browse/CRM-17410) Using xml on
+  upgrade (not installation) of extension to create/append new optionvalues
+  ([9480](https://github.com/civicrm/civicrm-core/pull/9480))**
+
+  Extensions that specify option values in XML for installation can now add
+  options during an upgrade using XML.
+
+- **[CRM-19688](https://issues.civicrm.org/jira/browse/CRM-19688) State/province
+  API ([9454](https://github.com/civicrm/civicrm-core/pull/9454))**
+
+  An API for creating, modifying, and deleting states/provinces is now
+  available.
+
+- **[CRM-19755](https://issues.civicrm.org/jira/browse/CRM-19755) reverse order
+  of html and text on CRM/Mailing/Page/Component.php
+  ([9531](https://github.com/civicrm/civicrm-core/pull/9531))**
+
+  The mail template interface is now more consistent in placing the HTML version
+  before the plain-text version.
+
+- **[CRM-19686](https://issues.civicrm.org/jira/browse/CRM-19686) Dedupe
+  Exceptions Should Link to Contacts
+  ([9455](https://github.com/civicrm/civicrm-core/pull/9455))**
+
+  The list of dedupe exceptions now links to the contacts.
+
+### CiviContribute
+
+- **[CRM-19325](https://issues.civicrm.org/jira/browse/CRM-19325) Search
+  contributions that are not in any batch
+  ([9492](https://github.com/civicrm/civicrm-core/pull/9492))**
+
+  Contribution search now allows filtering by contributions that are not in any
+  batch of financial transactions.
+
+- **[CRM-18460](https://issues.civicrm.org/jira/browse/CRM-18460) Add relative
+  date filters for Aggregate Contribution custom search
+  ([9493](https://github.com/civicrm/civicrm-core/pull/9493))**
+
+  The Aggregate Contribution custom search now uses the standard relative date
+  filters.
+
+### CiviEvent
+
+- **[CRM-19626](https://issues.civicrm.org/jira/browse/CRM-19626) Event
+  Registration page allows registration even if no number (or the number 0) has
+  been entered in any ticket quantity boxes
+  ([9517](https://github.com/civicrm/civicrm-core/pull/9517))**
+
+  Price sets now have a "Minimum Amount" field to accommodate situations where
+  any one of several fields may be filled but a certain price threshold must be
+  reached.
+
+## <a name="bugs"></a>Bugs resolved
+
+### Core CiviCRM
+
+- **[CRM-19591](https://issues.civicrm.org/jira/browse/CRM-19591) Creating a
+  pledge with only one installment will cause pledge payment to have a null
+  status (and cannot record a payment)
+  ([9557](https://github.com/civicrm/civicrm-core/pull/9557))**
+
+- **[CRM-19772](https://issues.civicrm.org/jira/browse/CRM-19772) Add
+  $entity,$action to "possibly mandatory" exception message
+  ([9543](https://github.com/civicrm/civicrm-core/pull/9543))**
+
+  The API exception message is clearer in some cases with a database constraint
+  violation.
+
+- **[CRM-19333](https://issues.civicrm.org/jira/browse/CRM-19333) Advanced
+  Search issue when searching using Group Type(s)
+  ([9534](https://github.com/civicrm/civicrm-core/pull/9534))**
+
+  Searching for contacts in groups of a specific group type no longer results in
+  a database syntax error.
+
+- **[CRM-19764](https://issues.civicrm.org/jira/browse/CRM-19764) Context
+  ignored when fetching custom field options
+  ([9540](https://github.com/civicrm/civicrm-core/pull/9540))**
+
+  The getoptions API method now accurately returns or suppresses disabled
+  options for custom fields when the `context` parameter is set.
+
+- **[CRM-19662](https://issues.civicrm.org/jira/browse/CRM-19662) Send test
+  mailing failing because of "only_full_group_by" setting
+  ([9428](https://github.com/civicrm/civicrm-core/pull/9428))**
+
+  Various queries having `GROUP BY` set, but with non-aggregated columns besides
+  those that are grouped, have been resolved to be compatible with MySQL
+  installations where the `sql_mode` contains `only_full_group_by`.  Some have
+  removed columns from the `SELECT`, while others have added to the `GROUP BY`
+  clause.
+
+- **[CRM-19698](https://issues.civicrm.org/jira/browse/CRM-19698) Wrong search
+  results when combining smart and non-smart groups in a single search
+  ([9506](https://github.com/civicrm/civicrm-core/pull/9506))**
+
+  Searching for a smart group alongside other groups now accurately displays
+  contacts who are in any of the groups, rather than just the smart group.
+
+- **[CRM-19743](https://issues.civicrm.org/jira/browse/CRM-19743) API Utils
+  _civicrm_api3_get_options_from_params doesn't handle sort as an array properly
+  ([9525](https://github.com/civicrm/civicrm-core/pull/9525))**
+
+- **[CRM-19226](https://issues.civicrm.org/jira/browse/CRM-19226) $loginUrl
+  token not populating in Drupal 7
+  ([9479](https://github.com/civicrm/civicrm-core/pull/9479))**
+
+  This fixes a broken or missing login URL link token on Drupal sites.
+
+- **[CRM-19490](https://issues.civicrm.org/jira/browse/CRM-19490) Profile date
+  fields don't respect localization on the Contribution Page confirmation screen
+  ([9529](https://github.com/civicrm/civicrm-core/pull/9529) and
+  [9530](https://github.com/civicrm/civicrm-core/pull/9530)) [completes previous
+  work]**
+
+  Short date form fields now have the proper labeling and display for
+  internationalization.
+
+- **Correct code docs for CRM_Core_Menu::get()
+  ([9514](https://github.com/civicrm/civicrm-core/pull/9514))**
+
+- **[CRM-18248](https://issues.civicrm.org/jira/browse/CRM-18248) Performance -
+  select2 based contact autocomplete spams the DB server with potentially long
+  running queries ([9502](https://github.com/civicrm/civicrm-core/pull/9502))**
+
+  Entity reference autocomplete fields now wait 300 milliseconds (up from 100)
+  before sending queries as users type.
+
+- **JS Optimizations
+  ([9505](https://github.com/civicrm/civicrm-core/pull/9505))**
+
+  Improves the loading of WYSIWYG Javascript and only loads table headers for
+  users with "Access CiviCRM" permission.
+
+- **[CRM-19656](https://issues.civicrm.org/jira/browse/CRM-19656) Link for users
+  to update their subscription billing info generates error
+  ([9401](https://github.com/civicrm/civicrm-core/pull/9401))**
+
+- **[CRM-19721](https://issues.civicrm.org/jira/browse/CRM-19721)
+  CiviCRM-cxn-rpc needs to be updated to work with PHP 7
+  ([9500](https://github.com/civicrm/civicrm-core/pull/9500))**
+
+- **[CRM-19720](https://issues.civicrm.org/jira/browse/CRM-19720) Typographic
+  fixes ([9501](https://github.com/civicrm/civicrm-core/pull/9501))**
+
+- **[CRM-19711](https://issues.civicrm.org/jira/browse/CRM-19711) Bookkeeping
+  report displays pay later items twice
+  ([9490](https://github.com/civicrm/civicrm-core/pull/9490))**
+
+  The bookkeeping report no longer shows duplicate row for pay-later items: once
+  for the pending payment, and once for the completion.
+
+- **CRM_Utils_HttpClientTest - Use special purpose hostnames
+  ([9485](https://github.com/civicrm/civicrm-core/pull/9485))**
+
+  Improves testing of HTTP and HTTPS connections by using hosts that have been
+  prepared specifically for this purpose.
+
+- **[CRM-19699](https://issues.civicrm.org/jira/browse/CRM-19699) PHP7: cannot
+  install using Drush
+  ([9472](https://github.com/civicrm/civicrm-core/pull/9472))**
+
+  `DB_DSN_MODE` is set on installation for PHP 7 compatibility.
+
+- **[CRM-19679](https://issues.civicrm.org/jira/browse/CRM-19679) multi custom
+  data: file field errors on new record save
+  ([9436](https://github.com/civicrm/civicrm-core/pull/9436))**
+
+  Saving data in a file custom field in a multi-record custom data group no
+  longer results in a database error.
+
+- **[CRM-19681](https://issues.civicrm.org/jira/browse/CRM-19681) date fields
+  not respected when passed through url for report
+  ([9437](https://github.com/civicrm/civicrm-core/pull/9437))**
+
+  Reports now accurately accept fixed date filter parameters in the URL.
+
+- **js cleanup ([175](https://github.com/civicrm/civicrm-packages/pull/175))**
+
+  This removes some unnecessary Javascript files and shortens or minifies
+  others.
+
+- **[CRM-19048](https://issues.civicrm.org/jira/browse/CRM-19048) FullText -
+  Search by email, blank
+  ([9537](https://github.com/civicrm/civicrm-core/pull/9537) and
+  [9374](https://github.com/civicrm/civicrm-core/pull/9374)) [completes previous
+  work]**
+
+  Searches with unnecessary wildcard operators no longer result in empty
+  results.
+
+- **[CRM-19534](https://issues.civicrm.org/jira/browse/CRM-19534) Saving report
+  with dashlet enabled for non admin users can cause a backtrace
+  ([9456](https://github.com/civicrm/civicrm-core/pull/9456))**
+
+  When saving a report with a dashlet, the system now prevents the dashlet from
+  being added a second time for contacts who already have it enabled.
+
+- **[CRM-19683](https://issues.civicrm.org/jira/browse/CRM-19683) Changing word
+  replacement strings does not work if you have more than one set in
+  civicrm_domain ([9446](https://github.com/civicrm/civicrm-core/pull/9446))**
+
+  Saving word replacements now applies to the currently-used language.
+
+- **[CRM-19685](https://issues.civicrm.org/jira/browse/CRM-19685) Contacts
+  preferred_mail_format can't be NULL
+  ([9463](https://github.com/civicrm/civicrm-core/pull/9463))**
+
+  Upgrading sites will have all contacts with a null value for
+  `preferred_mail_format` set to `Both`.
+
+### CiviContribute
+
+- **[CRM-19263](https://issues.civicrm.org/jira/browse/CRM-19263) Online Pay Now
+  functionality ([9532](https://github.com/civicrm/civicrm-core/pull/9532))
+  [completes previous work]**
+
+  Payments made retain the original financial type instead of picking up the
+  contribution page's financial type.
+
+- **[CRM-19722](https://issues.civicrm.org/jira/browse/CRM-19722) Fatal Error:
+  Unknown column 'contribution_source' in 'order clause'
+  ([9516](https://github.com/civicrm/civicrm-core/pull/9516))**
+
+  Tasks from the Actions drop-down on contribution searches no longer cause
+  database errors if the search results are sorted by certain columns.
+
+- **[CRM-19549](https://issues.civicrm.org/jira/browse/CRM-19549) New pledge
+  data entry page shows hard coded $ for installments
+  ([9475](https://github.com/civicrm/civicrm-core/pull/9475))**
+
+  The currency symbol for pledges now changes dynamically according to the
+  currency of the contribution amount.
+
+- **[CRM-19660](https://issues.civicrm.org/jira/browse/CRM-19660) Financial
+  Transaction stores wrong transaction date if the contribution is cancelled
+  ([9405](https://github.com/civicrm/civicrm-core/pull/9405))**
+
+- **[CRM-19294](https://issues.civicrm.org/jira/browse/CRM-19294) Unable to
+  upload files via a contribution page
+  ([9518](https://github.com/civicrm/civicrm-core/pull/9518))**
+
+  If a file custom field is required in a profile on a contribution page, a
+  regression caused the confirmation page to fail validation and prevent
+  completing the contribution.  This has been resolved.
+
+### CiviEvent
+
+- **[CRM-19717](https://issues.civicrm.org/jira/browse/CRM-19717) Event
+  registration impossible with "Pending from pay later" status being "positive"
+  ([9523](https://github.com/civicrm/civicrm-core/pull/9523))**
+
+  The Class attribute of reserved participant statuses can no longer be edited.
+
+- **[CRM-19680](https://issues.civicrm.org/jira/browse/CRM-19680)
+  Participant.get API generates invalid query when searching for role_id IS
+  NULL. ([9453](https://github.com/civicrm/civicrm-core/pull/9453))**
+
+### CiviMember
+
+- **[CRM-19736](https://issues.civicrm.org/jira/browse/CRM-19736) Error thrown
+  when printing labels for members
+  ([9538](https://github.com/civicrm/civicrm-core/pull/9538))**
+
+- **[CRM-19298](https://issues.civicrm.org/jira/browse/CRM-19298) Membership fee
+  amount doubled in receipt when 'separate membership payment' is configured
+  ([9438](https://github.com/civicrm/civicrm-core/pull/9438)) [completes
+  previous work]**
+
+  Test coverage was added for this issue.
+
+- **[CRM-19600](https://issues.civicrm.org/jira/browse/CRM-19600) Membership
+  Renewal activity not created through online contribution page
+  ([9357](https://github.com/civicrm/civicrm-core/pull/9357))**
+
+- **[CRM-19678](https://issues.civicrm.org/jira/browse/CRM-19678) No Membership
+  Renewal Activity is created when a Pay Later is set to Completed
+  ([9447](https://github.com/civicrm/civicrm-core/pull/9447))**
+
+### CiviMail
+
+- **[CRM-19649](https://issues.civicrm.org/jira/browse/CRM-19649) ckeditor
+  includes html/head/body tags
+  ([9425](https://github.com/civicrm/civicrm-core/pull/9425)) [completes
+  previous work]**
+
+  CKEditor configuration defaults are improved.
+
+### Drupal integration
+
+- **[CRM-19303](https://issues.civicrm.org/jira/browse/CRM-19303) CKEditor
+  configuration can't be edited on a Drupal multisite installation
+  ([9424](https://github.com/civicrm/civicrm-core/pull/9424)) [continues
+  previous work]**
+
+  The check for the proper Drupal multisite folder is improved.
+
+## <a name="credits"></a>Credits
+
+This release was developed by the following code authors:
+
+Australian Greens - Seamus Lee; CiviCRM - Jitendra Purohit, Monish Deb, Coleman
+Watts, Tim Otten, Yashodha Chaku; Coop SymbioTIC - Mathieu Lutfy; Denver DataMan -
+Steve Kessler; Fuzion - Chris Burgess, Eileen McNaughton; JMA Consulting - Joe
+Murray, Pradeep Nayak; Johan Vervloet; John Kingsnorth; Jon Goldberg;
+Progressive Technology Project - Jamie McClelland; Sharique Ahmed Farooqui
+
+Most authors also reviewed code for this release; in addition, the following
+reviewers contributed their comments:
+
+Agileware - Agileware Team; Andrew Cormick-Dockery; Australian Greens - Seamus
+Lee; Barbara Miller; Blackfly Solutions - Alan Dixon; Bob Silvern; British
+Humanist Association - William Gordon, Andrew West; Circle Interactive - Dave
+Jenkins; CiviCRM - Monish Deb, Jitendra Purohit, Yashodha Chaku, Tim Otten,
+Coleman Watts, Josh Gowans, Dave Greenberg; CiviDesk - Nicolas Ganivet, Sunil
+Pawar; Coop SymbioTIC - Mathieu Lutfy; Daniel Martinez; Dennis Gray; Denver
+DataMan - Steve Kessler; E-Dynamics - Franky Van Liedekerke; Francesc Bassas i
+Bullich; Freeform Solutions - Lola Slade; Fuzion - Eileen McNaughton, Peter
+Davis, Chris Burgess; Gareth Small; GMCVO Databases - Jon-man Cheung; iXiam -
+Vangelis Pantazis; JMA Consulting - Pradeep Nayak; joemurray; johanv; John
+Kingsnorth; Joinery - Allen Shaw; Kacper Warda; Korlon - Stuart Gaston;
+Lighthouse Design and Consulting - Brian Shaughnessy; Lutz Frommberger; Milton
+Zurita; Nubay Services - David Tarrant; Progressive Technology Project - Jamie
+McClelland; Richard van Oosterhout; Sharique Ahmed Farooqui; Thomas Nilefalk;
+Vakees K; Veda Consulting - Kajakaran Balakrishnan
diff --git a/civicrm/settings/Localization.setting.php b/civicrm/settings/Localization.setting.php
index 1035bc9764e02fed8fca84352d1e68b3141ac140..9736b0627e80356f3534d845fa11f7c60b3b429c 100644
--- a/civicrm/settings/Localization.setting.php
+++ b/civicrm/settings/Localization.setting.php
@@ -361,7 +361,7 @@ return array(
       'maxlength' => '60',
     ),
     'default' => '%m/%d/%Y',
-    'title' => 'Date Format: Short date Day Month Year',
+    'title' => 'Date Format: Short date Month Day Year',
     'description' => '',
   ),
   'dateInputFormat' => array(
diff --git a/civicrm/sql/civicrm.mysql b/civicrm/sql/civicrm.mysql
index 17bbc0ad51f3b14cb8059126b1f774cba072437d..215a15f36d95cc97186501e8e9e3b38c5203e2a1 100644
--- a/civicrm/sql/civicrm.mysql
+++ b/civicrm/sql/civicrm.mysql
@@ -3656,7 +3656,8 @@ CREATE TABLE `civicrm_price_set` (
      `extends` varchar(255) NOT NULL   COMMENT 'What components are using this price set?',
      `financial_type_id` int unsigned   DEFAULT NULL COMMENT 'FK to Financial Type(for membership price sets only).',
      `is_quick_config` tinyint   DEFAULT 0 COMMENT 'Is set if edited on Contribution or Event Page rather than through Manage Price Sets',
-     `is_reserved` tinyint   DEFAULT 0 COMMENT 'Is this a predefined system price set  (i.e. it can not be deleted, edited)?' 
+     `is_reserved` tinyint   DEFAULT 0 COMMENT 'Is this a predefined system price set  (i.e. it can not be deleted, edited)?',
+     `min_amount` int unsigned   DEFAULT 0 COMMENT 'Minimum Amount required for this set.' 
 ,
     PRIMARY KEY ( `id` )
  
diff --git a/civicrm/sql/civicrm_data.mysql b/civicrm/sql/civicrm_data.mysql
index 2a58c39d955caed051a1d7950d14b17f8d220891..b3c5d319d88b284aa638add67102f32bb7f2637e 100644
--- a/civicrm/sql/civicrm_data.mysql
+++ b/civicrm/sql/civicrm_data.mysql
@@ -23854,4 +23854,4 @@ INSERT INTO `civicrm_report_instance`
 VALUES
     (  @domainID, 'Survey Details', 'survey/detail', 'Detailed report for canvassing, phone-banking, walk lists or other surveys.', 'access CiviReport', 'a:39:{s:6:"fields";a:2:{s:9:"sort_name";s:1:"1";s:6:"result";s:1:"1";}s:22:"assignee_contact_id_op";s:2:"eq";s:25:"assignee_contact_id_value";s:0:"";s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:17:"street_number_min";s:0:"";s:17:"street_number_max";s:0:"";s:16:"street_number_op";s:3:"lte";s:19:"street_number_value";s:0:"";s:14:"street_name_op";s:3:"has";s:17:"street_name_value";s:0:"";s:15:"postal_code_min";s:0:"";s:15:"postal_code_max";s:0:"";s:14:"postal_code_op";s:3:"lte";s:17:"postal_code_value";s:0:"";s:7:"city_op";s:3:"has";s:10:"city_value";s:0:"";s:20:"state_province_id_op";s:2:"in";s:23:"state_province_id_value";a:0:{}s:13:"country_id_op";s:2:"in";s:16:"country_id_value";a:0:{}s:12:"survey_id_op";s:2:"in";s:15:"survey_id_value";a:0:{}s:12:"status_id_op";s:2:"eq";s:15:"status_id_value";s:1:"1";s:11:"custom_1_op";s:2:"in";s:14:"custom_1_value";a:0:{}s:11:"custom_2_op";s:2:"in";s:14:"custom_2_value";a:0:{}s:17:"custom_3_relative";s:1:"0";s:13:"custom_3_from";s:0:"";s:11:"custom_3_to";s:0:"";s:11:"description";s:75:"Detailed report for canvassing, phone-banking, walk lists or other surveys.";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:17:"access CiviReport";s:6:"groups";s:0:"";s:9:"domain_id";i:1;}');
 
-UPDATE civicrm_domain SET version = '4.7.14';
+UPDATE civicrm_domain SET version = '4.7.15';
diff --git a/civicrm/sql/civicrm_generated.mysql b/civicrm/sql/civicrm_generated.mysql
index 9acb0cc42fea438e368b1adfa91637fef3c517b7..8153a861ca033eb696df53c6dd1bcc7eccfce8b3 100644
--- a/civicrm/sql/civicrm_generated.mysql
+++ b/civicrm/sql/civicrm_generated.mysql
@@ -399,7 +399,7 @@ UNLOCK TABLES;
 
 LOCK TABLES `civicrm_domain` WRITE;
 /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */;
-INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'4.7.14',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
+INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'4.7.15',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
 /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */;
 UNLOCK TABLES;
 
diff --git a/civicrm/templates/CRM/Admin/Page/ParticipantStatusType.tpl b/civicrm/templates/CRM/Admin/Page/ParticipantStatusType.tpl
index 378ee9c8b2c3a4b41cc35027e1dac4e65fcf00ca..26e61c0e5f6b2fdc4a11fda7914b3f3eec77a017 100644
--- a/civicrm/templates/CRM/Admin/Page/ParticipantStatusType.tpl
+++ b/civicrm/templates/CRM/Admin/Page/ParticipantStatusType.tpl
@@ -48,7 +48,7 @@
        <tr id="participant_status_type-{$row.id}" class="crm-entity crm-participant_{$row.id} {cycle values="odd-row,even-row"} {$row.class}{if NOT $row.is_active} disabled{/if}">
           <td class="crmf-label crm-editable" data-field="label">{$row.label}</td>
           <td class="crmf-name">{$row.name} ({$row.id})</td>
-          <td class="crmf-class crm-editable" data-type="select">{$row.class}</td>
+          <td class="crmf-class {if !$row.is_reserved} crm-editable {/if}" data-type="select">{$row.class}</td>
           <td class="center crmf-is_reserved">{if $row.is_reserved}<img src="{$config->resourceBase}i/check.gif" alt="{ts}Reserved{/ts}" />{/if}</td>
         <td id="row_{$row.id}_status" class="crmf-is_active">{if $row.is_active eq 1} {ts}Yes{/ts} {else} {ts}No{/ts} {/if}</td>
           <td class="center crmf-is_counted">{if $row.is_counted} <img src="{$config->resourceBase}i/check.gif" alt="{ts}Counted{/ts}" />{/if}</td>
diff --git a/civicrm/templates/CRM/Contact/Form/Search/Custom/ContributionAggregate.tpl b/civicrm/templates/CRM/Contact/Form/Search/Custom/ContributionAggregate.tpl
index db6d66d9475c3992b6d96ce8617b06472949f14f..c985e2e381ba246fc4cfb709f9a58a5dff0092b4 100644
--- a/civicrm/templates/CRM/Contact/Form/Search/Custom/ContributionAggregate.tpl
+++ b/civicrm/templates/CRM/Contact/Form/Search/Custom/ContributionAggregate.tpl
@@ -35,15 +35,13 @@
             {foreach from=$elements item=element}
                 <tr class="crm-contact-custom-search-form-row-{$element}">
                     <td class="label">{$form.$element.label}</td>
-                    {if $element eq 'start_date'}
-                        <td>{include file="CRM/common/jcalendar.tpl" elementName=start_date}</td>
-                    {elseif $element eq 'end_date'}
-                        <td>{include file="CRM/common/jcalendar.tpl" elementName=end_date}</td>
-                    {else}
-                        <td>{$form.$element.html}</td>
-                    {/if}
+                    <td>{$form.$element.html}</td>
                 </tr>
             {/foreach}
+            <tr class="crm-contact-custom-search-contributionDetails-form-block-receive_date">
+              <td class="label">{ts}Contribution Dates{/ts}</td>
+              {include file="CRM/Core/DateRange.tpl" fieldName="contribution_date" from='_low' to='_high'}
+            </tr>
             <tr class="crm-contact-custom-search-contributionDetails-form-block-financial_type">
                 <td class="label">{ts}Financial Type{/ts}</td>
                 <td>{$form.financial_type_id.html|crmAddClass:twenty}</td>
diff --git a/civicrm/templates/CRM/Contact/Page/DedupeException.tpl b/civicrm/templates/CRM/Contact/Page/DedupeException.tpl
index 8ef52954603841dbb10c462cbd1cd094e8d3e86e..6214675a6f2d2847c230ea60612e0f445fa62b85 100644
--- a/civicrm/templates/CRM/Contact/Page/DedupeException.tpl
+++ b/civicrm/templates/CRM/Contact/Page/DedupeException.tpl
@@ -51,8 +51,8 @@
   <tbody>
     {foreach from=$dedupeExceptions item=exception key=id}
       <tr id="dupeRow_{$id}" class="{cycle values="odd-row,even-row"}">
-        <td>{$exception.main.name}</td>
-        <td>{$exception.other.name}</td>
+        <td><a href ={crmURL p='civicrm/contact/view' q="reset=1&cid=`$exception.main.id`"}>{$exception.main.name}</a></td>
+        <td><a href ={crmURL p='civicrm/contact/view' q="reset=1&cid=`$exception.other.id`"}>{$exception.other.name}</a></td>
         <td><a id='duplicateContacts' href="#" title={ts}Remove Exception{/ts} onClick="processDupes( {$exception.main.id}, {$exception.other.id}, 'nondupe-dupe', 'dedupe-exception' );return false;">&raquo; {ts}Remove Exception{/ts}</a></td>
       </tr>
     {/foreach}
diff --git a/civicrm/templates/CRM/Custom/Form/ContactReference.tpl b/civicrm/templates/CRM/Custom/Form/ContactReference.tpl
index 82f6cfa79496fa83fc8a32c424adf1c6ce4fa5d5..3a09cdbfc6d80d47c92f0877c54eed11afccd4da 100644
--- a/civicrm/templates/CRM/Custom/Form/ContactReference.tpl
+++ b/civicrm/templates/CRM/Custom/Form/ContactReference.tpl
@@ -35,6 +35,7 @@
       minimumInputLength: 1,
       ajax: {
         url: {/literal}"{$customUrls.$element_name}"{literal},
+        quietMillis: 300,
         data: function(term) {
           return {term: term};
         },
diff --git a/civicrm/templates/CRM/Mailing/Form/Component.tpl b/civicrm/templates/CRM/Mailing/Form/Component.tpl
index 2c50632b071d62b8c86948b1458c640b83101384..2191c7aac4d3ff849952a3ae6f82a0a8accdf49c 100644
--- a/civicrm/templates/CRM/Mailing/Form/Component.tpl
+++ b/civicrm/templates/CRM/Mailing/Form/Component.tpl
@@ -30,8 +30,8 @@
     <tr class="crm-mailing-component-form-block-name"><td class="label">{$form.name.label}</td><td>{$form.name.html}</td>
     <tr class="crm-mailing-component-form-block-component_type"><td class="label">{$form.component_type.label}</td><td>{$form.component_type.html}</td>
     <tr class="crm-mailing-component-form-block-subject"><td class="label">{$form.subject.label}</td><td>{$form.subject.html}</td>
-    <tr class="crm-mailing-component-form-block-body_text"><td class="label">{$form.body_text.label}</td><td>{$form.body_text.html}</td>
     <tr class="crm-mailing-component-form-block-body_html"><td class="label">{$form.body_html.label}</td><td>{$form.body_html.html}</td>
+    <tr class="crm-mailing-component-form-block-body_text"><td class="label">{$form.body_text.label}</td><td>{$form.body_text.html}</td>
     <tr class="crm-mailing-component-form-block-is_default"><td class="label">{$form.is_default.label}</td><td>{$form.is_default.html}</td>
     <tr class="crm-mailing-component-form-block-is_active"><td class="label">{$form.is_active.label}</td><td>{$form.is_active.html}</td>
   </table>
diff --git a/civicrm/templates/CRM/Mailing/Page/Component.tpl b/civicrm/templates/CRM/Mailing/Page/Component.tpl
index 490c761c8424a47d70b0729271d2e416dab86d9e..7dd796ec85d6a4ca4266887ed2286ff5da8c6e75 100644
--- a/civicrm/templates/CRM/Mailing/Page/Component.tpl
+++ b/civicrm/templates/CRM/Mailing/Page/Component.tpl
@@ -38,8 +38,8 @@
         <th>{ts}Name{/ts}</th>
         <th>{ts}Type{/ts}</th>
         <th>{ts}Subject{/ts}</th>
-        <th>{ts}Body Text{/ts}</th>
         <th>{ts}Body HTML{/ts}</th>
+        <th>{ts}Body Text{/ts}</th>
         <th>{ts}Default?{/ts}</th>
         <th>{ts}Enabled?{/ts}</th>
         <th></th>
@@ -49,8 +49,8 @@
            <td class="crm-editable" data-field="name">{$row.name}</td>
            <td>{$row.component_type}</td>
            <td>{$row.subject}</td>
-           <td>{$row.body_text|escape}</td>
            <td>{$row.body_html|escape}</td>
+           <td>{$row.body_text|escape}</td>
            <td>{if $row.is_default eq 1}<img src="{$config->resourceBase}i/check.gif" alt="{ts}Default{/ts}" />{/if}&nbsp;</td>
      <td id="row_{$row.id}_status">{if $row.is_active eq 1} {ts}Yes{/ts} {else} {ts}No{/ts} {/if}</td>
            <td>{$row.action|replace:'xx':$row.id}</td>
diff --git a/civicrm/templates/CRM/Pledge/Form/Pledge.tpl b/civicrm/templates/CRM/Pledge/Form/Pledge.tpl
index 0e343ebaedb2d79ca69766054e1df8cc9cf84e3b..9b55afb89d337202ac9448fcaa78a45b4a0b20c8 100644
--- a/civicrm/templates/CRM/Pledge/Form/Pledge.tpl
+++ b/civicrm/templates/CRM/Pledge/Form/Pledge.tpl
@@ -70,7 +70,14 @@
   </tr>
         <tr class="crm-pledge-form-block-installments">
       <td class="label">{$form.installments.label}</td>
-      <td>{$form.installments.html} {ts}installments of{/ts} {if $action eq 1 or $isPending}{$form.eachPaymentAmount.html|crmMoney:$currency}{elseif $action eq 2 and !$isPending}{$eachPaymentAmount|crmMoney:$currency}{/if}&nbsp;{ts}every{/ts}&nbsp;{$form.frequency_interval.html}&nbsp;{$form.frequency_unit.html}</td></tr>
+      <td>{$form.installments.html} {ts}installments of{/ts}
+        <span class='currency-symbol'>
+          {if $action eq 1 or $isPending}
+            {$form.eachPaymentAmount.html|crmMoney:$currency}
+          {elseif $action eq 2 and !$isPending}
+            {$eachPaymentAmount|crmMoney:$currency}
+          {/if}
+        </span>&nbsp;{ts}every{/ts}&nbsp;{$form.frequency_interval.html}&nbsp;{$form.frequency_unit.html}</td></tr>
         <tr class="crm-pledge-form-block-frequency_day">
       <td class="label nowrap">{$form.frequency_day.label}</td>
       <td>{$form.frequency_day.html} {ts}day of the period{/ts}<br />
@@ -141,33 +148,47 @@
        </table>
 {literal}
 <script type="text/javascript">
-// bind first click of accordion header to load crm-accordion-body with snippet
-// everything else taken care of by cj().crm-accordions()
-cj(document).ready( function() {
-    cj('.crm-ajax-accordion .crm-accordion-header').one('click', function() {
-      loadPanes(cj(this).attr('id'));
+  // bind first click of accordion header to load crm-accordion-body with snippet
+  // everything else taken care of by $().crm-accordions()
+  CRM.$(function($) {
+    $('.crm-ajax-accordion .crm-accordion-header').one('click', function() {
+      loadPanes($(this).attr('id'));
     });
-    cj('.crm-ajax-accordion:not(.collapsed) .crm-accordion-header').each(function(index) {
-      loadPanes(cj(this).attr('id'));
-      });
-});
-// load panes function calls for snippet based on id of crm-accordion-header
-function loadPanes( id ) {
-    var url = "{/literal}{crmURL p='civicrm/contact/view/pledge' q='snippet=4&formType=' h=0}{literal}" + id;
-    {/literal}
+    $('#currency').on('change', function() {
+      replaceCurrency($('#currency option:selected').text());
+    });
+    $('.crm-ajax-accordion:not(.collapsed) .crm-accordion-header').each(function(index) {
+      loadPanes($(this).attr('id'));
+    });
+
+    function replaceCurrency(val) {
+      var symbol = '';
+      var eachPaymentAmout = $('#eachPaymentAmount');
+      var pos = val.indexOf("(") + 1;
+      if (pos) {
+        symbol = val.slice(pos, val.lastIndexOf(")"));
+      }
+      $('.currency-symbol').text(symbol).append("&nbsp;").append(eachPaymentAmout);
+    }
+
+    // load panes function calls for snippet based on id of crm-accordion-header
+    function loadPanes( id ) {
+      var url = "{/literal}{crmURL p='civicrm/contact/view/pledge' q='snippet=4&formType=' h=0}{literal}" + id;
+      {/literal}
         {if $contributionMode}
-            url = url + "&mode={$contributionMode}";
+          url = url + "&mode={$contributionMode}";
         {/if}
-    {literal}
-   if ( ! cj('div.'+id).html() ) {
-      var loading = '<img src="{/literal}{$config->resourceBase}i/loading.gif{literal}" alt="{/literal}{ts escape='js'}loading{/ts}{literal}" />&nbsp;{/literal}{ts escape='js'}Loading{/ts}{literal}...';
-      cj('div.'+id).html(loading);
-      cj.ajax({
+      {literal}
+      if ( ! $('div.'+id).html() ) {
+        var loading = '<img src="{/literal}{$config->resourceBase}i/loading.gif{literal}" alt="{/literal}{ts escape='js'}loading{/ts}{literal}" />&nbsp;{/literal}{ts escape='js'}Loading{/ts}{literal}...';
+        $('div.'+id).html(loading);
+        $.ajax({
           url    : url,
-          success: function(data) { cj('div.'+id).html(data).trigger('crmLoad'); }
-          });
+            success: function(data) { $('div.'+id).html(data).trigger('crmLoad'); }
+        });
       }
-  }
+    }
+  });
 </script>
 {/literal}
 
diff --git a/civicrm/templates/CRM/Price/Form/Set.tpl b/civicrm/templates/CRM/Price/Form/Set.tpl
index a85bc2dd685becd1eba583b1cdb313a0c3d0611a..b72398f7ca7089b4837d8c7d7a8bc0a059c23c04 100644
--- a/civicrm/templates/CRM/Price/Form/Set.tpl
+++ b/civicrm/templates/CRM/Price/Form/Set.tpl
@@ -52,8 +52,12 @@
           {/if}
           </td>
         </tr>
-  <tr id="financial_type_id_row" class="crm-price-set-form-block-contribution_type_id crm-price-set-form-block-financial_type_id">
-     <td class="label">{$form.financial_type_id.label}</td>
+        <tr id="min_amount" class="crm-price-set-form-block-min_amount">
+           <td class="label">{$form.min_amount.label}</td>
+           <td>{$form.min_amount.html}</td>
+        </tr>
+        <tr id="financial_type_id_row" class="crm-price-set-form-block-contribution_type_id crm-price-set-form-block-financial_type_id">
+          <td class="label">{$form.financial_type_id.label}</td>
            <td>{$form.financial_type_id.html}</td>
            <td>&nbsp;</td>
         </tr>
diff --git a/civicrm/templates/CRM/Profile/Page/MultipleRecordFieldsListing.tpl b/civicrm/templates/CRM/Profile/Page/MultipleRecordFieldsListing.tpl
index a9f04333a3f9c7f21f3d6fe69c750679004ed5d0..9992233745e51af878589e3aaea653a2c9f0c68f 100644
--- a/civicrm/templates/CRM/Profile/Page/MultipleRecordFieldsListing.tpl
+++ b/civicrm/templates/CRM/Profile/Page/MultipleRecordFieldsListing.tpl
@@ -117,7 +117,7 @@
   {if !$reachedMax}
     <div class="action-link">
       {if $pageViewType eq 'customDataView'}
-        <br/><a accesskey="N" title="{ts 1=$customGroupTitle}Add %1 Record{/ts}" href="{crmURL p='civicrm/contact/view/cd/edit' q="reset=1&type=$ctype&groupID=$customGroupId&entityID=$contactId&cgcount=$cgcount&multiRecordDisplay=single&mode=add"}"
+        <br/><a accesskey="N" title="{ts 1=$customGroupTitle}Add %1 Record{/ts}" href="{crmURL p='civicrm/contact/view/cd/edit' q="reset=1&type=$ctype&groupID=$customGroupId&entityID=$contactId&cgcount=$newCgCount&multiRecordDisplay=single&mode=add"}"
          class="button action-item"><span><i class="crm-i fa-plus-circle"></i> {ts 1=$customGroupTitle}Add %1 Record{/ts}</span></a>
       {else}
         <a accesskey="N" href="{crmURL p='civicrm/profile/edit' q="reset=1&id=`$contactId`&multiRecord=add&gid=`$gid`&context=multiProfileDialog&onPopupClose=`$onPopupClose`"}"
diff --git a/civicrm/templates/CRM/UF/Form/Block.tpl b/civicrm/templates/CRM/UF/Form/Block.tpl
index 692557d9c0c609f18de64a597e44f3edc95958da..a6c4013fd46d9841bed3d44373bdb96c66872b3e 100644
--- a/civicrm/templates/CRM/UF/Form/Block.tpl
+++ b/civicrm/templates/CRM/UF/Form/Block.tpl
@@ -124,8 +124,12 @@
               ( $form.formName neq 'Confirm' )  AND
               ( $form.formName neq 'ThankYou' ) }
                 {include file="CRM/common/jcalendar.tpl" elementName=$n}
-              {elseif ( $n|substr:-5:5 eq '_date' )}
-                {$form.$n.value|date_format:"%Y-%m-%d"|crmDate:$config->dateformatshortdate}
+              {elseif ( $n|substr:-5:5 eq '_date' ) }
+                {assign var="date_value" value=$form.$n.value}
+                <span class="crm-frozen-field">
+                  {$date_value|date_format:"%Y-%m-%d"|crmDate:$config->dateformatshortdate}
+                  <input type="hidden" name="{$form.$n.name}" value="{$form.$n.value}" id="{$form.$n.name}">
+                </span>
               {elseif $n|substr:0:5 eq 'phone'}
                 {assign var="phone_ext_field" value=$n|replace:'phone':'phone_ext'}
                 {if $prefix}{$form.$prefix.$n.html}{else}{$form.$n.html}{/if}
diff --git a/civicrm/templates/CRM/common/version.tpl b/civicrm/templates/CRM/common/version.tpl
index 46168f83c39be808fec3a11dc5e1a5f5efa15188..6f25ac6537d4ed99208169183b2d739427e5ba8b 100644
--- a/civicrm/templates/CRM/common/version.tpl
+++ b/civicrm/templates/CRM/common/version.tpl
@@ -1 +1 @@
-4.7.14
\ No newline at end of file
+4.7.15
\ No newline at end of file
diff --git a/civicrm/vendor/autoload.php b/civicrm/vendor/autoload.php
index f00b5e0a01221197d190a37a09462a3c08b7e7cd..83d5f372019dfeee0f5796396a2b16ac89fa94e0 100644
--- a/civicrm/vendor/autoload.php
+++ b/civicrm/vendor/autoload.php
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer' . '/autoload_real.php';
 
-return ComposerAutoloaderInit5bc83fd699231b4dac8e0c5bdfac547c::getLoader();
+return ComposerAutoloaderInit0442173a8c86b38277f669363ecfb032::getLoader();
diff --git a/civicrm/vendor/civicrm/civicrm-cxn-rpc/composer.json b/civicrm/vendor/civicrm/civicrm-cxn-rpc/composer.json
index 608c1211cedcb3b7b99e6d923b745ec9f5ca6814..bbd746c45bce2fb1f35285c9eba46d6f67065665 100644
--- a/civicrm/vendor/civicrm/civicrm-cxn-rpc/composer.json
+++ b/civicrm/vendor/civicrm/civicrm-cxn-rpc/composer.json
@@ -3,7 +3,7 @@
     "description": "RPC library for CiviConnect",
     "require": {
         "psr/log": "1.0.0",
-        "phpseclib/phpseclib": "0.3.*"
+        "phpseclib/phpseclib": "1.0.*"
     },
     "require-dev": {
         "phpunit/phpunit": "3.7.*"
diff --git a/civicrm/vendor/civicrm/civicrm-cxn-rpc/composer.lock b/civicrm/vendor/civicrm/civicrm-cxn-rpc/composer.lock
index 7dd4218b36d3052a6d4326712fb540b27e1391f4..5933d5d2dfb8748a396bbd9a465c951d3540fe04 100644
--- a/civicrm/vendor/civicrm/civicrm-cxn-rpc/composer.lock
+++ b/civicrm/vendor/civicrm/civicrm-cxn-rpc/composer.lock
@@ -1,23 +1,24 @@
 {
     "_readme": [
         "This file locks the dependencies of your project to a known state",
-        "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "f3500cded54b935f8702bd7e5fdcd617",
+    "hash": "cb43ce04189e62f04d6704fa4e5a335f",
+    "content-hash": "e3c0e29f372787306642ec03fbf19987",
     "packages": [
         {
             "name": "phpseclib/phpseclib",
-            "version": "0.3.10",
+            "version": "1.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpseclib/phpseclib.git",
-                "reference": "d15bba1edcc7c89e09cc74c5d961317a8b947bf4"
+                "reference": "38fa7332e96bcc546ce6eb5cbaa1168c96839393"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d15bba1edcc7c89e09cc74c5d961317a8b947bf4",
-                "reference": "d15bba1edcc7c89e09cc74c5d961317a8b947bf4",
+                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/38fa7332e96bcc546ce6eb5cbaa1168c96839393",
+                "reference": "38fa7332e96bcc546ce6eb5cbaa1168c96839393",
                 "shasum": ""
             },
             "require": {
@@ -27,19 +28,14 @@
                 "phing/phing": "~2.7",
                 "phpunit/phpunit": "~4.0",
                 "sami/sami": "~2.0",
-                "squizlabs/php_codesniffer": "~1.5"
+                "squizlabs/php_codesniffer": "~2.0"
             },
             "suggest": {
                 "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
                 "ext-mcrypt": "Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.",
-                "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 4.3.3."
+                "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 5.0.0."
             },
             "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "0.3-dev"
-                }
-            },
             "autoload": {
                 "psr-0": {
                     "Crypt": "phpseclib/",
@@ -49,6 +45,7 @@
                     "System": "phpseclib/"
                 },
                 "files": [
+                    "phpseclib/bootstrap.php",
                     "phpseclib/Crypt/Random.php"
                 ]
             },
@@ -79,6 +76,11 @@
                     "name": "Hans-Jürgen Petrich",
                     "email": "petrich@tronic-media.com",
                     "role": "Developer"
+                },
+                {
+                    "name": "Graham Campbell",
+                    "email": "graham@alt-three.com",
+                    "role": "Developer"
                 }
             ],
             "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
@@ -102,7 +104,7 @@
                 "x.509",
                 "x509"
             ],
-            "time": "2015-01-28 21:50:33"
+            "time": "2016-10-22 17:53:16"
         },
         {
             "name": "psr/log",
@@ -207,31 +209,33 @@
         },
         {
             "name": "phpunit/php-file-iterator",
-            "version": "1.3.4",
+            "version": "1.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-                "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
+                "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
-                "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
+                "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.4.x-dev"
+                }
+            },
             "autoload": {
                 "classmap": [
-                    "File/"
+                    "src/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
-            "include-path": [
-                ""
-            ],
             "license": [
                 "BSD-3-Clause"
             ],
@@ -248,20 +252,20 @@
                 "filesystem",
                 "iterator"
             ],
-            "time": "2013-10-10 15:34:57"
+            "time": "2016-10-03 07:40:28"
         },
         {
             "name": "phpunit/php-text-template",
-            "version": "1.2.0",
+            "version": "1.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-text-template.git",
-                "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
+                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
-                "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
                 "shasum": ""
             },
             "require": {
@@ -270,20 +274,17 @@
             "type": "library",
             "autoload": {
                 "classmap": [
-                    "Text/"
+                    "src/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
-            "include-path": [
-                ""
-            ],
             "license": [
                 "BSD-3-Clause"
             ],
             "authors": [
                 {
                     "name": "Sebastian Bergmann",
-                    "email": "sb@sebastian-bergmann.de",
+                    "email": "sebastian@phpunit.de",
                     "role": "lead"
                 }
             ],
@@ -292,35 +293,35 @@
             "keywords": [
                 "template"
             ],
-            "time": "2014-01-30 17:20:04"
+            "time": "2015-06-21 13:50:34"
         },
         {
             "name": "phpunit/php-timer",
-            "version": "1.0.5",
+            "version": "1.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-timer.git",
-                "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
+                "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
-                "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
+                "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
+            "require-dev": {
+                "phpunit/phpunit": "~4|~5"
+            },
             "type": "library",
             "autoload": {
                 "classmap": [
-                    "PHP/"
+                    "src/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
-            "include-path": [
-                ""
-            ],
             "license": [
                 "BSD-3-Clause"
             ],
@@ -336,7 +337,7 @@
             "keywords": [
                 "timer"
             ],
-            "time": "2013-08-02 07:42:54"
+            "time": "2016-05-12 18:03:57"
         },
         {
             "name": "phpunit/php-token-stream",
@@ -512,53 +513,52 @@
         },
         {
             "name": "symfony/yaml",
-            "version": "v2.6.5",
-            "target-dir": "Symfony/Component/Yaml",
+            "version": "v2.8.14",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/Yaml.git",
-                "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d"
+                "url": "https://github.com/symfony/yaml.git",
+                "reference": "befb26a3713c97af90d25dd12e75621ef14d91ff"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Yaml/zipball/0cd8e72071e46e15fc072270ae39ea1b66b10a9d",
-                "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/befb26a3713c97af90d25dd12e75621ef14d91ff",
+                "reference": "befb26a3713c97af90d25dd12e75621ef14d91ff",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3"
-            },
-            "require-dev": {
-                "symfony/phpunit-bridge": "~2.7"
+                "php": ">=5.3.9"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.6-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
-                "psr-0": {
+                "psr-4": {
                     "Symfony\\Component\\Yaml\\": ""
-                }
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
             "authors": [
-                {
-                    "name": "Symfony Community",
-                    "homepage": "http://symfony.com/contributors"
-                },
                 {
                     "name": "Fabien Potencier",
                     "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
                 }
             ],
             "description": "Symfony Yaml Component",
-            "homepage": "http://symfony.com",
-            "time": "2015-03-12 10:28:44"
+            "homepage": "https://symfony.com",
+            "time": "2016-11-14 16:15:57"
         }
     ],
     "aliases": [],
diff --git a/civicrm/vendor/composer/autoload_files.php b/civicrm/vendor/composer/autoload_files.php
index fa62cb73a76b6a886edb6847e5570041cb34e55e..3fbb325ef7af6ef86a8296e31a331eb4e269a51c 100644
--- a/civicrm/vendor/composer/autoload_files.php
+++ b/civicrm/vendor/composer/autoload_files.php
@@ -6,5 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
 $baseDir = dirname($vendorDir);
 
 return array(
+    $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
     $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php',
 );
diff --git a/civicrm/vendor/composer/autoload_real.php b/civicrm/vendor/composer/autoload_real.php
index aa21ba9e3066b2b5fe4c177ce08c5f6c9ced9564..b594f5bce4723d793b5a478de4c3e0c6233b509e 100644
--- a/civicrm/vendor/composer/autoload_real.php
+++ b/civicrm/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInit5bc83fd699231b4dac8e0c5bdfac547c
+class ComposerAutoloaderInit0442173a8c86b38277f669363ecfb032
 {
     private static $loader;
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit5bc83fd699231b4dac8e0c5bdfac547c
             return self::$loader;
         }
 
-        spl_autoload_register(array('ComposerAutoloaderInit5bc83fd699231b4dac8e0c5bdfac547c', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderInit0442173a8c86b38277f669363ecfb032', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        spl_autoload_unregister(array('ComposerAutoloaderInit5bc83fd699231b4dac8e0c5bdfac547c', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInit0442173a8c86b38277f669363ecfb032', 'loadClassLoader'));
 
         $includePaths = require __DIR__ . '/include_paths.php';
         array_push($includePaths, get_include_path());
@@ -46,14 +46,14 @@ class ComposerAutoloaderInit5bc83fd699231b4dac8e0c5bdfac547c
 
         $includeFiles = require __DIR__ . '/autoload_files.php';
         foreach ($includeFiles as $file) {
-            composerRequire5bc83fd699231b4dac8e0c5bdfac547c($file);
+            composerRequire0442173a8c86b38277f669363ecfb032($file);
         }
 
         return $loader;
     }
 }
 
-function composerRequire5bc83fd699231b4dac8e0c5bdfac547c($file)
+function composerRequire0442173a8c86b38277f669363ecfb032($file)
 {
     require $file;
 }
diff --git a/civicrm/vendor/composer/installed.json b/civicrm/vendor/composer/installed.json
index d151b095fb108c41c95611b0009b6677719caffd..5f592651f4713574ac3787d09a7217e85817ff2e 100644
--- a/civicrm/vendor/composer/installed.json
+++ b/civicrm/vendor/composer/installed.json
@@ -41,17 +41,17 @@
     },
     {
         "name": "phpseclib/phpseclib",
-        "version": "0.3.10",
-        "version_normalized": "0.3.10.0",
+        "version": "1.0.5",
+        "version_normalized": "1.0.5.0",
         "source": {
             "type": "git",
             "url": "https://github.com/phpseclib/phpseclib.git",
-            "reference": "d15bba1edcc7c89e09cc74c5d961317a8b947bf4"
+            "reference": "38fa7332e96bcc546ce6eb5cbaa1168c96839393"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d15bba1edcc7c89e09cc74c5d961317a8b947bf4",
-            "reference": "d15bba1edcc7c89e09cc74c5d961317a8b947bf4",
+            "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/38fa7332e96bcc546ce6eb5cbaa1168c96839393",
+            "reference": "38fa7332e96bcc546ce6eb5cbaa1168c96839393",
             "shasum": ""
         },
         "require": {
@@ -61,20 +61,15 @@
             "phing/phing": "~2.7",
             "phpunit/phpunit": "~4.0",
             "sami/sami": "~2.0",
-            "squizlabs/php_codesniffer": "~1.5"
+            "squizlabs/php_codesniffer": "~2.0"
         },
         "suggest": {
             "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
             "ext-mcrypt": "Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.",
-            "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 4.3.3."
+            "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 5.0.0."
         },
-        "time": "2015-01-28 21:50:33",
+        "time": "2016-10-22 17:53:16",
         "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "0.3-dev"
-            }
-        },
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
@@ -85,6 +80,7 @@
                 "System": "phpseclib/"
             },
             "files": [
+                "phpseclib/bootstrap.php",
                 "phpseclib/Crypt/Random.php"
             ]
         },
@@ -115,6 +111,11 @@
                 "name": "Hans-Jürgen Petrich",
                 "email": "petrich@tronic-media.com",
                 "role": "Developer"
+            },
+            {
+                "name": "Graham Campbell",
+                "email": "graham@alt-three.com",
+                "role": "Developer"
             }
         ],
         "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
@@ -141,27 +142,27 @@
     },
     {
         "name": "civicrm/civicrm-cxn-rpc",
-        "version": "v0.15.12.04",
-        "version_normalized": "0.15.12.04",
+        "version": "v0.16.12.05",
+        "version_normalized": "0.16.12.05",
         "source": {
             "type": "git",
             "url": "https://github.com/civicrm/civicrm-cxn-rpc.git",
-            "reference": "6e3a0f956860908a240758ab8c80a020549a6f03"
+            "reference": "e88e78dc491b7e8739a40231f46c2d4459347b12"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/civicrm/civicrm-cxn-rpc/zipball/6e3a0f956860908a240758ab8c80a020549a6f03",
-            "reference": "6e3a0f956860908a240758ab8c80a020549a6f03",
+            "url": "https://api.github.com/repos/civicrm/civicrm-cxn-rpc/zipball/e88e78dc491b7e8739a40231f46c2d4459347b12",
+            "reference": "e88e78dc491b7e8739a40231f46c2d4459347b12",
             "shasum": ""
         },
         "require": {
-            "phpseclib/phpseclib": "0.3.*",
+            "phpseclib/phpseclib": "1.0.*",
             "psr/log": "1.0.0"
         },
         "require-dev": {
             "phpunit/phpunit": "3.7.*"
         },
-        "time": "2015-12-05 04:41:02",
+        "time": "2016-12-06 04:32:51",
         "type": "library",
         "installation-source": "dist",
         "autoload": {
@@ -845,12 +846,12 @@
         "source": {
             "type": "git",
             "url": "https://github.com/symfony/config.git",
-            "reference": "d93bb29acfa5cff771cb4aa0fb4a97454ddb41e4"
+            "reference": "c7309e33b719433d5cf3845d0b5b9608609d8c8e"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/config/zipball/d93bb29acfa5cff771cb4aa0fb4a97454ddb41e4",
-            "reference": "d93bb29acfa5cff771cb4aa0fb4a97454ddb41e4",
+            "url": "https://api.github.com/repos/symfony/config/zipball/c7309e33b719433d5cf3845d0b5b9608609d8c8e",
+            "reference": "c7309e33b719433d5cf3845d0b5b9608609d8c8e",
             "shasum": ""
         },
         "require": {
diff --git a/civicrm/vendor/phpseclib/phpseclib/.gitattributes b/civicrm/vendor/phpseclib/phpseclib/.gitattributes
deleted file mode 100644
index 176a458f94e0ea5272ce67c36bf30b6be9caf623..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-* text=auto
diff --git a/civicrm/vendor/phpseclib/phpseclib/.gitignore b/civicrm/vendor/phpseclib/phpseclib/.gitignore
deleted file mode 100644
index 1469fe601cb84aae1d373c6659e6d7aad4df24eb..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/vendor
-/composer.phar
diff --git a/civicrm/vendor/phpseclib/phpseclib/.scrutinizer.yml b/civicrm/vendor/phpseclib/phpseclib/.scrutinizer.yml
deleted file mode 100644
index 17c1ef32a11a9831ccdcc39358e0fa278c499083..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/.scrutinizer.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-imports:
-    - php
-
-tools:
-    external_code_coverage:
-        runs: 5 # No Code Coverage on PHP 5.2 and HHVM
-        timeout: 2700 # 45 minutes
diff --git a/civicrm/vendor/phpseclib/phpseclib/.travis.yml b/civicrm/vendor/phpseclib/phpseclib/.travis.yml
deleted file mode 100644
index e19f009c8bde2065427d37e4b2d5a3c257e6f03d..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/.travis.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-language: php
-
-# When adding environments here, the number of runs specified in .scrutinizer.yml
-# may have to be adjusted.
-php:
-  - 5.2
-  - 5.3.3
-  - 5.3
-  - 5.4
-  - 5.5
-  - 5.6
-  - hhvm
-
-env:
-  global:
-    # Defines CODE_COVERAGE_PASSPHRASE which is the passphrase for unlocking
-    # the travis/code_coverage_id_rsa RSA private key.
-    - secure: "jtQTZKQBnzUlp/jz7NlM6470ZDnLGVAs53sgvIm4tcYqf9TWSXSXjIYvFsrS\nKPR2eyZaAevYysUkIGRFTUXTlG6tC36YngMp9+6FPxASl8mnGXsTbKcm613B\n59vD3242pgIgqhhmgFQ0c8gbvnE8PuF2aS4/hluP3r+AxhWN56E="
-
-before_install: true
-
-install:
-  - sudo apt-get install parallel
-  - eval `ssh-agent -s`
-  - travis/setup-secure-shell.sh
-  - sh -c "if [ '$TRAVIS_PHP_VERSION' != 'hhvm' ]; then travis/install-php-extensions.sh; fi"
-  - sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' ]; then travis/setup-composer.sh; fi"
-
-script:
-  - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.5' ]; then vendor/bin/phing -f build/build.xml sniff; fi"
-  - travis/run-phpunit.sh
-
-after_success:
-  - sh -c "if $TRAVIS_SECURE_ENV_VARS; then travis/upload-code-coverage-html.sh; fi"
-  - sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' -a '$TRAVIS_PHP_VERSION' != 'hhvm' ]; then travis/upload-code-coverage-scrutinizer.sh; fi"
diff --git a/civicrm/vendor/phpseclib/phpseclib/AUTHORS b/civicrm/vendor/phpseclib/phpseclib/AUTHORS
index e175f9f22c24f94604ae254212e42b07565921a9..a08b3099c06c5dba585fef78519bc6337e37dcba 100644
--- a/civicrm/vendor/phpseclib/phpseclib/AUTHORS
+++ b/civicrm/vendor/phpseclib/phpseclib/AUTHORS
@@ -3,3 +3,4 @@ phpseclib Lead Developer:  TerraFrost (Jim Wigginton)
 phpseclib Developers:      monnerat (Patrick Monnerat)
                            bantu (Andreas Fischer)
                            petrich (Hans-Jürgen Petrich)
+                           GrahamCampbell (Graham Campbell)
diff --git a/civicrm/vendor/phpseclib/phpseclib/CHANGELOG.md b/civicrm/vendor/phpseclib/phpseclib/CHANGELOG.md
deleted file mode 100644
index 0fd3ca091a6a1c9590175134bfcb555bbc647bf4..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/CHANGELOG.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Changelog
-
-## 0.3.9 - 2014-11-09
-
-- PHP 5.6 improvements ([#482](https://github.com/phpseclib/phpseclib/pull/482), [#491](https://github.com/phpseclib/phpseclib/issues/491))
-
-## 0.3.8 - 2014-09-12
-
-- improve support for indef lengths in File_ASN1
-- add hmac-sha2-256 support to Net_SSH2
-- make it so negotiated algorithms can be seen before Net_SSH2 login
-- add sha256-96 and sha512-96 to Crypt_Hash
-- window size handling adjustments in Net_SSH2
-
-## 0.3.7 - 2014-07-05
-
-- auto-detect public vs private keys
-- add file_exists, is_dir, is_file, readlink and symlink to Net_SFTP
-- add support for recursive nlist and rawlist
-- make it so nlist and rawlist can return pre-sorted output
-- make it so callback functions can make exec() return early
-- add signSPKAC and saveSPKAC methods to File_X509
-- add support for PKCS8 keys in Crypt_RSA
-- add pbkdf1 support to setPassword() in Crypt_Base
-- add getWindowColumns, getWindowRows, setWindowColumns, setWindowRows to Net_SSH2
-- add support for filenames with spaces in them to Net_SCP
-
-## 0.3.6 - 2014-02-23
-
-- add preliminary support for custom SSH subsystems
-- add ssh-agent support
-
-## 0.3.5 - 2013-07-11
-
-- numerous SFTP changes:
- - chown
- - chgrp
- - truncate
- - improved file type detection
- - put() can write to te middle of a file
- - mkdir accepts the same paramters that PHP's mkdir does
- - the ability to upload/download 2GB files
-- across-the-board speedups for the various encryption algorithms
-- multi-factor authentication support for Net_SSH2
-- a $callback parameter for Net_SSH2::exec
-- new classes:
- - Net_SFTP_StreamWrapper
- - Net_SCP
- - Crypt_Twofish
- - Crypt_Blowfish
-
-## 0.3.1 - 2012-11-20
-
-- add Net_SSH2::enableQuietMode() for suppressing stderr
-- add Crypt_RSA::__toString() and Crypt_RSA::getSize()
-- fix problems with File_X509::validateDate(), File_X509::sign() and Crypt_RSA::verify()
-- use OpenSSL to speed up modular exponention in Math_BigInteger
-- improved timeout functionality in Net_SSH2
-- add support for SFTPv2
-- add support for CRLs in File_X509
-- SSH-2.0-SSH doesn't implement hmac-*-96 correctly
-
-## 0.3.0 - 2012-07-08
-
-- add support for reuming Net_SFTP::put()
-- add support for recursive deletes and recursive chmods to Net_SFTP
-- add setTimeout() to Net_SSH2
-- add support for PBKDF2 to the various Crypt_* classes via setPassword()
-- add File_X509 and File_ASN1
-- add the ability to decode various formats in Crypt_RSA
-- make Net_SSH2::getServerPublicHostKey() return a printer-friendly version of the public key
-
-## 0.2.2 - 2011-05-09
-
-- CFB and OFB modes were added to all block ciphers
-- support for interactive mode was added to Net_SSH2
-- Net_SSH2 now has limited keyboard_interactive authentication support
-- support was added for PuTTY formatted RSA private keys and XML formatted RSA private keys
-- Crypt_RSA::loadKey() will now try all key types automatically
-= add support for AES-128-CBC and DES-EDE3-CFB encrypted RSA private keys
-- add Net_SFTP::stat(), Net_SFTP::lstat() and Net_SFTP::rawlist()
-- logging was added to Net_SSH1
-- the license was changed to the less restrictive MIT license
\ No newline at end of file
diff --git a/civicrm/vendor/phpseclib/phpseclib/LICENSE b/civicrm/vendor/phpseclib/phpseclib/LICENSE
index 75f6b2045c5b50843f38c4338bf25881f38ebbef..a8ec8ebd4062ee1d6866d823385258d6ccfed48b 100644
--- a/civicrm/vendor/phpseclib/phpseclib/LICENSE
+++ b/civicrm/vendor/phpseclib/phpseclib/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2007-2013 TerraFrost and other contributors
+Copyright 2007-2016 TerraFrost and other contributors
 http://phpseclib.sourceforge.net/
 
 Permission is hereby granted, free of charge, to any person obtaining
diff --git a/civicrm/vendor/phpseclib/phpseclib/README.md b/civicrm/vendor/phpseclib/phpseclib/README.md
index cad56570fe90034709bd8450bbf673b4345346cc..75089a0110f6580247cc6aef3e1c89b23afbf244 100644
--- a/civicrm/vendor/phpseclib/phpseclib/README.md
+++ b/civicrm/vendor/phpseclib/phpseclib/README.md
@@ -1,14 +1,14 @@
 # phpseclib - PHP Secure Communications Library
 
-[![Build Status](https://secure.travis-ci.org/phpseclib/phpseclib.png?branch=master)](http://travis-ci.org/phpseclib/phpseclib)
+[![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=1.0)](https://travis-ci.org/phpseclib/phpseclib)
 
 MIT-licensed pure-PHP implementations of an arbitrary-precision integer
 arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael,
 AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
 
-* [Download (0.3.9)](http://sourceforge.net/projects/phpseclib/files/phpseclib0.3.9.zip/download)
+* [Download (1.0.5)](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.5.zip/download)
 * [Browse Git](https://github.com/phpseclib/phpseclib)
-* [Code Coverage Report](http://phpseclib.bantux.org/code_coverage/master/latest/)
+* [Code Coverage Report](http://phpseclib.bantux.org/code_coverage/1.0/latest/)
 
 <img src="http://phpseclib.sourceforge.net/pear-icon.png" alt="PEAR Channel" width="16" height="16">
 PEAR Channel: [phpseclib.sourceforge.net](http://phpseclib.sourceforge.net/pear.htm)
@@ -16,7 +16,7 @@ PEAR Channel: [phpseclib.sourceforge.net](http://phpseclib.sourceforge.net/pear.
 ## Documentation
 
 * [Documentation / Manual](http://phpseclib.sourceforge.net/)
-* [API Documentation](http://phpseclib.bantux.org/api/master/) (generated by Sami)
+* [API Documentation](http://phpseclib.bantux.org/api/1.0/) (generated by Sami)
 
 ## Support
 
@@ -40,7 +40,7 @@ Dependencies are managed via Composer.
 2. Install Dependencies
 
     ``` sh
-    php composer.phar install --dev
+    php composer.phar install
     ```
 
 ## Contributing
diff --git a/civicrm/vendor/phpseclib/phpseclib/build/build.xml b/civicrm/vendor/phpseclib/phpseclib/build/build.xml
deleted file mode 100644
index 92d3923f4da71740b90215e0f9442d3d5ceaa89c..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/build/build.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="phpseclib"
-         description="PHP Secure Communications Library"
-         default="all"
->
-
-  <target name="all" depends="sniff,api" />
-
-  <!-- Code Sniffer -->
-  <target name="sniff" depends="sniff-php-code,sniff-php-tests" />
-  <target name="sniff-php-code">
-    <exec command="vendor/bin/phpcs -s
-        --extensions=php
-        --standard=build/code-sniffer-ruleset.xml
-        phpseclib/"
-      dir=".." checkreturn="true" passthru="true" />
-  </target>
-  <target name="sniff-php-tests">
-    <exec command="vendor/bin/phpcs -s
-        --extensions=php
-        --standard=build/code-sniffer-ruleset-tests.xml
-        tests/"
-      dir=".." checkreturn="true" passthru="true" />
-  </target>
-
-  <!-- API Generation -->
-  <target name="api">
-    <exec command="vendor/bin/sami.php update build/sami.conf.php"
-      dir=".." passthru="true" />
-  </target>
-
-</project>
diff --git a/civicrm/vendor/phpseclib/phpseclib/build/code-sniffer-ruleset-tests.xml b/civicrm/vendor/phpseclib/phpseclib/build/code-sniffer-ruleset-tests.xml
deleted file mode 100644
index c3694258e61b979a81018a65528886b5c0ec14de..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/build/code-sniffer-ruleset-tests.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0"?>
-<ruleset name="phpseclib Test Standard">
-
- <description>phpseclib coding standard for tests</description>
-
- <!-- In general rules that apply to library code also apply to tests. -->
- <rule ref="./code-sniffer-ruleset.xml">
-   <!-- Exceptions to the library coding standard follow. -->
-
-   <!-- We do not care too much about method, class and file documentation,
-        but having @author, @copyright and @license tags would be nice.
-        The following configuration does not check for these tags, but
-        complains if the file doc block is missing completely. -->
-   <exclude name="PEAR.Commenting.ClassComment" />
-   <exclude name="PEAR.Commenting.FunctionComment" />
-   <exclude name="PEAR.Commenting.FileComment.MissingTag" />
-   <exclude name="PEAR.Commenting.FileComment.MissingVersion" />
-   <exclude name="PEAR.Commenting.FileComment.SpacingBeforeTags" />
- </rule>
-
-</ruleset>
diff --git a/civicrm/vendor/phpseclib/phpseclib/build/code-sniffer-ruleset.xml b/civicrm/vendor/phpseclib/phpseclib/build/code-sniffer-ruleset.xml
deleted file mode 100644
index a0a5fc8a41e31901e03f3c0b316ada389ae544ed..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/build/code-sniffer-ruleset.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0"?>
-<ruleset name="phpseclib Standard">
-
- <description>phpseclib coding standard</description>
-
- <!-- We are using the PEAR standard as a base -->
- <rule ref="PEAR">
-   <!-- Temporary exceptions to the PEAR standard follow -->
-   <exclude name="Generic.ControlStructures.InlineControlStructure.Discouraged" />
-   <exclude name="Generic.Files.LineLength.TooLong" />
-   <exclude name="PEAR.NamingConventions.ValidFunctionName.FunctionNoCapital" />
-   <exclude name="PEAR.NamingConventions.ValidFunctionName.NotCamelCaps" />
-   <exclude name="PEAR.Commenting.ClassComment.InvalidVersion" />
-   <exclude name="PEAR.Commenting.ClassComment.MissingTag" />
-   <exclude name="PEAR.Commenting.FileComment.EmptyCopyright" />
-   <exclude name="PEAR.Commenting.FileComment.InvalidVersion" />
-   <exclude name="PEAR.Commenting.FunctionComment.ExtraParamComment" />
-   <exclude name="PEAR.Commenting.FunctionComment.MissingReturn" />
-   <exclude name="PEAR.Commenting.FunctionComment.MissingParamComment" />
-   <exclude name="PEAR.Commenting.FunctionComment.MissingParamName" />
-   <exclude name="PEAR.Commenting.FunctionComment.MissingParamTag" />
-   <exclude name="PEAR.Commenting.FunctionComment.ParameterCommentsNotAligned" />
-   <exclude name="PEAR.Commenting.FunctionComment.ParameterNamesNotAligned" />
-   <exclude name="PEAR.Commenting.FunctionComment.ParamNameNoMatch" />
-   <exclude name="PEAR.Commenting.FunctionComment.SpacingAfterParams" />
-   <exclude name="PEAR.Commenting.FunctionComment.SpacingBeforeParams" />
-   <exclude name="PEAR.Commenting.FunctionComment.SpacingBeforeTags" />
-   <exclude name="PEAR.Functions.FunctionCallSignature.ContentAfterOpenBracket" />
-   <exclude name="PEAR.Functions.FunctionCallSignature.CloseBracketLine" />
-   <exclude name="PEAR.Functions.FunctionCallSignature.SpaceAfterOpenBracket" />
-   <exclude name="PEAR.WhiteSpace.ScopeClosingBrace.BreakIdent" />
-   <exclude name="PEAR.WhiteSpace.ScopeClosingBrace.Indent" />
-   <exclude name="PEAR.WhiteSpace.ScopeClosingBrace.Line" />
-   <exclude name="PEAR.WhiteSpace.ScopeIndent.Incorrect" />
- </rule>
-
- <!-- Useful additional rules follow -->
-
- <!-- "for (; bar; )" should be "while (bar)" instead -->
- <rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop" />
-
- <!-- A method MUST not only call its parent -->
- <rule ref="Generic.CodeAnalysis.UselessOverridingMethod" />
-
- <!-- All code files MUST use only UTF-8 without BOM. -->
- <rule ref="Generic.Files.ByteOrderMark" />
-
- <!-- Each file MUST end with exactly one newline character -->
- <rule ref="PSR2.Files.EndFileNewline" />
-
- <!-- In the argument list, there MUST NOT be a space before each comma,
-      and there MUST be one space after each comma. -->
- <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing">
-  <properties>
-   <property name="equalsSpacing" value="1"/>
-  </properties>
- </rule>
- <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint" />
-
- <!-- There MUST NOT be trailing whitespace at the end of lines. -->
- <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace" />
-
- <!-- There MUST NOT be whitespace before the first content of a file -->
- <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.StartFile" />
-
- <!-- There MUST NOT be whitespace after the last content of a file -->
- <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EndFile" />
-
- <!-- Functions MUST NOT contain multiple empty lines in a row -->
- <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines" />
-
- <!-- The ?> closing tag MUST be omitted from files containing only PHP. -->
- <rule ref="Zend.Files.ClosingTag" />
-
-</ruleset>
diff --git a/civicrm/vendor/phpseclib/phpseclib/build/sami.conf.php b/civicrm/vendor/phpseclib/phpseclib/build/sami.conf.php
deleted file mode 100644
index e9bf5fc010f84287e6abb07c5e63e4eac4952dc5..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/build/sami.conf.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-// Prevent e.g. 'Notice: Constant MATH_BIGINTEGER_MONTGOMERY already defined'.
-class MyArrayStore extends Sami\Store\ArrayStore
-{
-    public function removeClass(Sami\Project $project, $name)
-    {
-        unset($this->classes[$name]);
-    }
-}
-
-$iterator = Symfony\Component\Finder\Finder::create()
-    ->files()
-    ->name('*.php')
-    ->in(__DIR__ . '/../phpseclib/')
-;
-
-$versions = Sami\Version\GitVersionCollection::create(__DIR__ . '/../')
-    ->add('master')
-    ->add('php5')
-;
-
-return new Sami\Sami($iterator, array(
-    'theme'                => 'enhanced',
-    'versions'             => $versions,
-    'title'                => 'phpseclib API Documentation',
-    'build_dir'            => __DIR__.'/api/output/%version%',
-    'cache_dir'            => __DIR__.'/api/cache/%version%',
-    'default_opened_level' => 2,
-    'store'                => new MyArrayStore,
-));
diff --git a/civicrm/vendor/phpseclib/phpseclib/composer.json b/civicrm/vendor/phpseclib/phpseclib/composer.json
index c151c6a57c555e0b57750fcefd1c5c886c85bb45..acec44deb6cb947b649132c5b409261126fd0c50 100644
--- a/civicrm/vendor/phpseclib/phpseclib/composer.json
+++ b/civicrm/vendor/phpseclib/phpseclib/composer.json
@@ -43,6 +43,11 @@
             "name": "Hans-Jürgen Petrich",
             "email": "petrich@tronic-media.com",
             "role": "Developer"
+        },
+        {
+            "name": "Graham Campbell",
+            "email": "graham@alt-three.com",
+            "role": "Developer"
         }
     ],
     "require": {
@@ -52,12 +57,12 @@
         "phing/phing": "~2.7",
         "phpunit/phpunit": "~4.0",
         "sami/sami": "~2.0",
-        "squizlabs/php_codesniffer": "~1.5"
+        "squizlabs/php_codesniffer": "~2.0"
     },
     "suggest": {
         "ext-mcrypt": "Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.",
         "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
-        "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 4.3.3."
+        "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 5.0.0."
     },
     "include-path": ["phpseclib/"],
     "autoload": {
@@ -69,12 +74,8 @@
             "System": "phpseclib/"
         },
         "files": [
+            "phpseclib/bootstrap.php",
             "phpseclib/Crypt/Random.php"
         ]
-    },
-    "extra": {
-        "branch-alias": {
-            "dev-master": "0.3-dev"
-        }
     }
 }
diff --git a/civicrm/vendor/phpseclib/phpseclib/composer.lock b/civicrm/vendor/phpseclib/phpseclib/composer.lock
index 6d4d70808e92239686a76e2f5665031f12f16347..2ca66739b94d11190667b9a2d3b92cdd134510e9 100644
--- a/civicrm/vendor/phpseclib/phpseclib/composer.lock
+++ b/civicrm/vendor/phpseclib/phpseclib/composer.lock
@@ -1,24 +1,25 @@
 {
     "_readme": [
         "This file locks the dependencies of your project to a known state",
-        "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "dcec513bef49f692870f013fcfed86ab",
+    "hash": "ef3ada42c17aee960068e0a98b4de602",
+    "content-hash": "cec0167a357df0f3da215133e2424a6c",
     "packages": [],
     "packages-dev": [
         {
             "name": "doctrine/instantiator",
-            "version": "1.0.4",
+            "version": "1.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/instantiator.git",
-                "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119"
+                "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119",
-                "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119",
+                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
+                "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
                 "shasum": ""
             },
             "require": {
@@ -29,7 +30,7 @@
                 "ext-pdo": "*",
                 "ext-phar": "*",
                 "phpunit/phpunit": "~4.0",
-                "squizlabs/php_codesniffer": "2.0.*@ALPHA"
+                "squizlabs/php_codesniffer": "~2.0"
             },
             "type": "library",
             "extra": {
@@ -38,8 +39,8 @@
                 }
             },
             "autoload": {
-                "psr-0": {
-                    "Doctrine\\Instantiator\\": "src"
+                "psr-4": {
+                    "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -59,20 +60,20 @@
                 "constructor",
                 "instantiate"
             ],
-            "time": "2014-10-13 12:58:55"
+            "time": "2015-06-14 21:17:01"
         },
         {
             "name": "michelf/php-markdown",
-            "version": "1.4.1",
+            "version": "1.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/michelf/php-markdown.git",
-                "reference": "de9a19c7bf352d41cc99ed86c3c0ef17e87394b6"
+                "reference": "156e56ee036505ec637d761ee62dc425d807183c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/michelf/php-markdown/zipball/de9a19c7bf352d41cc99ed86c3c0ef17e87394b6",
-                "reference": "de9a19c7bf352d41cc99ed86c3c0ef17e87394b6",
+                "url": "https://api.github.com/repos/michelf/php-markdown/zipball/156e56ee036505ec637d761ee62dc425d807183c",
+                "reference": "156e56ee036505ec637d761ee62dc425d807183c",
                 "shasum": ""
             },
             "require": {
@@ -97,20 +98,20 @@
                 {
                     "name": "Michel Fortin",
                     "email": "michel.fortin@michelf.ca",
-                    "homepage": "http://michelf.ca/",
+                    "homepage": "https://michelf.ca/",
                     "role": "Developer"
                 },
                 {
                     "name": "John Gruber",
-                    "homepage": "http://daringfireball.net/"
+                    "homepage": "https://daringfireball.net/"
                 }
             ],
             "description": "PHP Markdown",
-            "homepage": "http://michelf.ca/projects/php-markdown/",
+            "homepage": "https://michelf.ca/projects/php-markdown/",
             "keywords": [
                 "markdown"
             ],
-            "time": "2014-05-05 02:43:50"
+            "time": "2015-12-24 01:37:31"
         },
         {
             "name": "nikic/php-parser",
@@ -159,16 +160,16 @@
         },
         {
             "name": "phing/phing",
-            "version": "2.9.0",
+            "version": "2.14.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phingofficial/phing.git",
-                "reference": "12af1264dd4c5b88e28ee787e829de13c5ec172e"
+                "reference": "7dd73c83c377623def54b58121f46b4dcb35dd61"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phingofficial/phing/zipball/12af1264dd4c5b88e28ee787e829de13c5ec172e",
-                "reference": "12af1264dd4c5b88e28ee787e829de13c5ec172e",
+                "url": "https://api.github.com/repos/phingofficial/phing/zipball/7dd73c83c377623def54b58121f46b4dcb35dd61",
+                "reference": "7dd73c83c377623def54b58121f46b4dcb35dd61",
                 "shasum": ""
             },
             "require": {
@@ -177,20 +178,22 @@
             "require-dev": {
                 "ext-pdo_sqlite": "*",
                 "lastcraft/simpletest": "@dev",
-                "pdepend/pdepend": "1.x",
-                "pear-pear.php.net/http_request2": "2.2.x",
-                "pear-pear.php.net/net_growl": "2.7.x",
-                "pear-pear.php.net/pear_packagefilemanager": "1.7.x",
-                "pear-pear.php.net/pear_packagefilemanager2": "1.0.x",
-                "pear-pear.php.net/xml_serializer": "0.20.x",
-                "pear/pear_exception": "@dev",
+                "mikey179/vfsstream": "^1.6",
+                "pdepend/pdepend": "2.x",
+                "pear/archive_tar": "1.4.x",
+                "pear/http_request2": "dev-trunk",
+                "pear/net_growl": "dev-trunk",
+                "pear/pear-core-minimal": "1.10.1",
                 "pear/versioncontrol_git": "@dev",
-                "pear/versioncontrol_svn": "@dev",
+                "pear/versioncontrol_svn": "~0.5",
                 "phpdocumentor/phpdocumentor": "2.x",
-                "phploc/phploc": "2.x",
+                "phploc/phploc": "~2.0.6",
+                "phpmd/phpmd": "~2.2",
                 "phpunit/phpunit": ">=3.7",
+                "sebastian/git": "~1.0",
                 "sebastian/phpcpd": "2.x",
-                "squizlabs/php_codesniffer": "1.5.x"
+                "squizlabs/php_codesniffer": "~2.2",
+                "symfony/yaml": "~2.7"
             },
             "suggest": {
                 "pdepend/pdepend": "PHP version of JDepend",
@@ -211,7 +214,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.9.x-dev"
+                    "dev-master": "2.14.x-dev"
                 }
             },
             "autoload": {
@@ -227,37 +230,148 @@
                 "LGPL-3.0"
             ],
             "authors": [
-                {
-                    "name": "Phing Community",
-                    "homepage": "http://www.phing.info/trac/wiki/Development/Contributors"
-                },
                 {
                     "name": "Michiel Rook",
                     "email": "mrook@php.net"
+                },
+                {
+                    "name": "Phing Community",
+                    "homepage": "https://www.phing.info/trac/wiki/Development/Contributors"
                 }
             ],
             "description": "PHing Is Not GNU make; it's a PHP project build system or build tool based on Apache Ant.",
-            "homepage": "http://www.phing.info/",
+            "homepage": "https://www.phing.info/",
             "keywords": [
                 "build",
                 "phing",
                 "task",
                 "tool"
             ],
-            "time": "2014-11-25 14:58:59"
+            "time": "2016-03-10 21:39:23"
+        },
+        {
+            "name": "phpdocumentor/reflection-docblock",
+            "version": "2.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+                "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
+                "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~4.0"
+            },
+            "suggest": {
+                "dflydev/markdown": "~1.0",
+                "erusev/parsedown": "~1.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "phpDocumentor": [
+                        "src/"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "mike.vanriel@naenius.com"
+                }
+            ],
+            "time": "2015-02-03 12:10:50"
+        },
+        {
+            "name": "phpspec/prophecy",
+            "version": "v1.6.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpspec/prophecy.git",
+                "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972",
+                "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/instantiator": "^1.0.2",
+                "php": "^5.3|^7.0",
+                "phpdocumentor/reflection-docblock": "~2.0",
+                "sebastian/comparator": "~1.1",
+                "sebastian/recursion-context": "~1.0"
+            },
+            "require-dev": {
+                "phpspec/phpspec": "~2.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.5.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Prophecy\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
+                },
+                {
+                    "name": "Marcello Duarte",
+                    "email": "marcello.duarte@gmail.com"
+                }
+            ],
+            "description": "Highly opinionated mocking framework for PHP 5.3+",
+            "homepage": "https://github.com/phpspec/prophecy",
+            "keywords": [
+                "Double",
+                "Dummy",
+                "fake",
+                "mock",
+                "spy",
+                "stub"
+            ],
+            "time": "2016-02-15 07:46:21"
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "2.0.12",
+            "version": "2.2.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "7ce9da20f96964bb7a4033f53834df13328dbeab"
+                "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7ce9da20f96964bb7a4033f53834df13328dbeab",
-                "reference": "7ce9da20f96964bb7a4033f53834df13328dbeab",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
+                "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
                 "shasum": ""
             },
             "require": {
@@ -265,12 +379,12 @@
                 "phpunit/php-file-iterator": "~1.3",
                 "phpunit/php-text-template": "~1.2",
                 "phpunit/php-token-stream": "~1.3",
-                "sebastian/environment": "~1.0",
+                "sebastian/environment": "^1.3.2",
                 "sebastian/version": "~1.0"
             },
             "require-dev": {
                 "ext-xdebug": ">=2.1.4",
-                "phpunit/phpunit": "~4.1"
+                "phpunit/phpunit": "~4"
             },
             "suggest": {
                 "ext-dom": "*",
@@ -280,7 +394,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.0.x-dev"
+                    "dev-master": "2.2.x-dev"
                 }
             },
             "autoload": {
@@ -289,9 +403,6 @@
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
-            "include-path": [
-                ""
-            ],
             "license": [
                 "BSD-3-Clause"
             ],
@@ -309,35 +420,37 @@
                 "testing",
                 "xunit"
             ],
-            "time": "2014-12-02 13:17:01"
+            "time": "2015-10-06 15:47:00"
         },
         {
             "name": "phpunit/php-file-iterator",
-            "version": "1.3.4",
+            "version": "1.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-                "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
+                "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
-                "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
+                "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.4.x-dev"
+                }
+            },
             "autoload": {
                 "classmap": [
-                    "File/"
+                    "src/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
-            "include-path": [
-                ""
-            ],
             "license": [
                 "BSD-3-Clause"
             ],
@@ -354,20 +467,20 @@
                 "filesystem",
                 "iterator"
             ],
-            "time": "2013-10-10 15:34:57"
+            "time": "2015-06-21 13:08:43"
         },
         {
             "name": "phpunit/php-text-template",
-            "version": "1.2.0",
+            "version": "1.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-text-template.git",
-                "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
+                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
-                "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
                 "shasum": ""
             },
             "require": {
@@ -376,20 +489,17 @@
             "type": "library",
             "autoload": {
                 "classmap": [
-                    "Text/"
+                    "src/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
-            "include-path": [
-                ""
-            ],
             "license": [
                 "BSD-3-Clause"
             ],
             "authors": [
                 {
                     "name": "Sebastian Bergmann",
-                    "email": "sb@sebastian-bergmann.de",
+                    "email": "sebastian@phpunit.de",
                     "role": "lead"
                 }
             ],
@@ -398,20 +508,20 @@
             "keywords": [
                 "template"
             ],
-            "time": "2014-01-30 17:20:04"
+            "time": "2015-06-21 13:50:34"
         },
         {
             "name": "phpunit/php-timer",
-            "version": "1.0.5",
+            "version": "1.0.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-timer.git",
-                "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
+                "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
-                "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
+                "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
                 "shasum": ""
             },
             "require": {
@@ -420,13 +530,10 @@
             "type": "library",
             "autoload": {
                 "classmap": [
-                    "PHP/"
+                    "src/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
-            "include-path": [
-                ""
-            ],
             "license": [
                 "BSD-3-Clause"
             ],
@@ -442,20 +549,20 @@
             "keywords": [
                 "timer"
             ],
-            "time": "2013-08-02 07:42:54"
+            "time": "2015-06-21 08:01:12"
         },
         {
             "name": "phpunit/php-token-stream",
-            "version": "1.3.0",
+            "version": "1.4.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-token-stream.git",
-                "reference": "f8d5d08c56de5cfd592b3340424a81733259a876"
+                "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/f8d5d08c56de5cfd592b3340424a81733259a876",
-                "reference": "f8d5d08c56de5cfd592b3340424a81733259a876",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
+                "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
                 "shasum": ""
             },
             "require": {
@@ -468,7 +575,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3-dev"
+                    "dev-master": "1.4-dev"
                 }
             },
             "autoload": {
@@ -491,20 +598,20 @@
             "keywords": [
                 "tokenizer"
             ],
-            "time": "2014-08-31 06:12:13"
+            "time": "2015-09-15 10:49:45"
         },
         {
             "name": "phpunit/phpunit",
-            "version": "4.3.5",
+            "version": "4.8.24",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "2dab9d593997db4abcf58d0daf798eb4e9cecfe1"
+                "reference": "a1066c562c52900a142a0e2bbf0582994671385e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2dab9d593997db4abcf58d0daf798eb4e9cecfe1",
-                "reference": "2dab9d593997db4abcf58d0daf798eb4e9cecfe1",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e",
+                "reference": "a1066c562c52900a142a0e2bbf0582994671385e",
                 "shasum": ""
             },
             "require": {
@@ -514,17 +621,19 @@
                 "ext-reflection": "*",
                 "ext-spl": "*",
                 "php": ">=5.3.3",
-                "phpunit/php-code-coverage": "~2.0",
-                "phpunit/php-file-iterator": "~1.3.2",
+                "phpspec/prophecy": "^1.3.1",
+                "phpunit/php-code-coverage": "~2.1",
+                "phpunit/php-file-iterator": "~1.4",
                 "phpunit/php-text-template": "~1.2",
-                "phpunit/php-timer": "~1.0.2",
+                "phpunit/php-timer": ">=1.0.6",
                 "phpunit/phpunit-mock-objects": "~2.3",
-                "sebastian/comparator": "~1.0",
-                "sebastian/diff": "~1.1",
-                "sebastian/environment": "~1.0",
-                "sebastian/exporter": "~1.0",
+                "sebastian/comparator": "~1.1",
+                "sebastian/diff": "~1.2",
+                "sebastian/environment": "~1.3",
+                "sebastian/exporter": "~1.2",
+                "sebastian/global-state": "~1.0",
                 "sebastian/version": "~1.0",
-                "symfony/yaml": "~2.0"
+                "symfony/yaml": "~2.1|~3.0"
             },
             "suggest": {
                 "phpunit/php-invoker": "~1.1"
@@ -535,7 +644,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.3.x-dev"
+                    "dev-master": "4.8.x-dev"
                 }
             },
             "autoload": {
@@ -544,10 +653,6 @@
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
-            "include-path": [
-                "",
-                "../../symfony/yaml/"
-            ],
             "license": [
                 "BSD-3-Clause"
             ],
@@ -559,35 +664,36 @@
                 }
             ],
             "description": "The PHP Unit Testing framework.",
-            "homepage": "http://www.phpunit.de/",
+            "homepage": "https://phpunit.de/",
             "keywords": [
                 "phpunit",
                 "testing",
                 "xunit"
             ],
-            "time": "2014-11-11 10:11:09"
+            "time": "2016-03-14 06:16:08"
         },
         {
             "name": "phpunit/phpunit-mock-objects",
-            "version": "2.3.0",
+            "version": "2.3.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
-                "reference": "c63d2367247365f688544f0d500af90a11a44c65"
+                "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65",
-                "reference": "c63d2367247365f688544f0d500af90a11a44c65",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
+                "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
                 "shasum": ""
             },
             "require": {
-                "doctrine/instantiator": "~1.0,>=1.0.1",
+                "doctrine/instantiator": "^1.0.2",
                 "php": ">=5.3.3",
-                "phpunit/php-text-template": "~1.2"
+                "phpunit/php-text-template": "~1.2",
+                "sebastian/exporter": "~1.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.3"
+                "phpunit/phpunit": "~4.4"
             },
             "suggest": {
                 "ext-soap": "*"
@@ -620,7 +726,7 @@
                 "mock",
                 "xunit"
             ],
-            "time": "2014-10-03 05:12:11"
+            "time": "2015-10-02 06:51:40"
         },
         {
             "name": "pimple/pimple",
@@ -727,30 +833,30 @@
         },
         {
             "name": "sebastian/comparator",
-            "version": "1.0.1",
+            "version": "1.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/comparator.git",
-                "reference": "e54a01c0da1b87db3c5a3c4c5277ddf331da4aef"
+                "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e54a01c0da1b87db3c5a3c4c5277ddf331da4aef",
-                "reference": "e54a01c0da1b87db3c5a3c4c5277ddf331da4aef",
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
+                "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3",
-                "sebastian/diff": "~1.1",
-                "sebastian/exporter": "~1.0"
+                "sebastian/diff": "~1.2",
+                "sebastian/exporter": "~1.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.1"
+                "phpunit/phpunit": "~4.4"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0.x-dev"
+                    "dev-master": "1.2.x-dev"
                 }
             },
             "autoload": {
@@ -787,32 +893,32 @@
                 "compare",
                 "equality"
             ],
-            "time": "2014-05-11 23:00:21"
+            "time": "2015-07-26 15:48:44"
         },
         {
             "name": "sebastian/diff",
-            "version": "1.2.0",
+            "version": "1.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/diff.git",
-                "reference": "5843509fed39dee4b356a306401e9dd1a931fec7"
+                "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7",
-                "reference": "5843509fed39dee4b356a306401e9dd1a931fec7",
+                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
+                "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.2"
+                "phpunit/phpunit": "~4.8"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2-dev"
+                    "dev-master": "1.4-dev"
                 }
             },
             "autoload": {
@@ -835,36 +941,36 @@
                 }
             ],
             "description": "Diff implementation",
-            "homepage": "http://www.github.com/sebastianbergmann/diff",
+            "homepage": "https://github.com/sebastianbergmann/diff",
             "keywords": [
                 "diff"
             ],
-            "time": "2014-08-15 10:29:00"
+            "time": "2015-12-08 07:14:41"
         },
         {
             "name": "sebastian/environment",
-            "version": "1.2.1",
+            "version": "1.3.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/environment.git",
-                "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7"
+                "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7",
-                "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
+                "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.3"
+                "phpunit/phpunit": "~4.4"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2.x-dev"
+                    "dev-master": "1.3.x-dev"
                 }
             },
             "autoload": {
@@ -889,32 +995,33 @@
                 "environment",
                 "hhvm"
             ],
-            "time": "2014-10-25 08:00:45"
+            "time": "2016-02-26 18:40:46"
         },
         {
             "name": "sebastian/exporter",
-            "version": "1.0.2",
+            "version": "1.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/exporter.git",
-                "reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0"
+                "reference": "7ae5513327cb536431847bcc0c10edba2701064e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c7d59948d6e82818e1bdff7cadb6c34710eb7dc0",
-                "reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
+                "reference": "7ae5513327cb536431847bcc0c10edba2701064e",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3"
+                "php": ">=5.3.3",
+                "sebastian/recursion-context": "~1.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.0"
+                "phpunit/phpunit": "~4.4"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0.x-dev"
+                    "dev-master": "1.2.x-dev"
                 }
             },
             "autoload": {
@@ -954,20 +1061,124 @@
                 "export",
                 "exporter"
             ],
-            "time": "2014-09-10 00:51:36"
+            "time": "2015-06-21 07:55:53"
+        },
+        {
+            "name": "sebastian/global-state",
+            "version": "1.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/global-state.git",
+                "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
+                "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~4.2"
+            },
+            "suggest": {
+                "ext-uopz": "*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Snapshotting of global state",
+            "homepage": "http://www.github.com/sebastianbergmann/global-state",
+            "keywords": [
+                "global state"
+            ],
+            "time": "2015-10-12 03:26:01"
+        },
+        {
+            "name": "sebastian/recursion-context",
+            "version": "1.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/recursion-context.git",
+                "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
+                "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~4.4"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Adam Harvey",
+                    "email": "aharvey@php.net"
+                }
+            ],
+            "description": "Provides functionality to recursively process PHP variables",
+            "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+            "time": "2015-11-11 19:50:13"
         },
         {
             "name": "sebastian/version",
-            "version": "1.0.3",
+            "version": "1.0.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/version.git",
-                "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43"
+                "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
-                "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
+                "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
                 "shasum": ""
             },
             "type": "library",
@@ -989,36 +1200,39 @@
             ],
             "description": "Library that helps with managing the version number of Git-hosted PHP projects",
             "homepage": "https://github.com/sebastianbergmann/version",
-            "time": "2014-03-07 15:35:33"
+            "time": "2015-06-21 13:59:46"
         },
         {
             "name": "squizlabs/php_codesniffer",
-            "version": "1.5.6",
+            "version": "2.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
-                "reference": "6f3e42d311b882b25b4d409d23a289f4d3b803d5"
+                "reference": "1bcdf03b068a530ac1962ce671dead356eeba43b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6f3e42d311b882b25b4d409d23a289f4d3b803d5",
-                "reference": "6f3e42d311b882b25b4d409d23a289f4d3b803d5",
+                "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1bcdf03b068a530ac1962ce671dead356eeba43b",
+                "reference": "1bcdf03b068a530ac1962ce671dead356eeba43b",
                 "shasum": ""
             },
             "require": {
+                "ext-simplexml": "*",
                 "ext-tokenizer": "*",
+                "ext-xmlwriter": "*",
                 "php": ">=5.1.2"
             },
-            "suggest": {
-                "phpunit/php-timer": "dev-master"
+            "require-dev": {
+                "phpunit/phpunit": "~4.0"
             },
             "bin": [
-                "scripts/phpcs"
+                "scripts/phpcs",
+                "scripts/phpcbf"
             ],
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-phpcs-fixer": "2.0.x-dev"
+                    "dev-master": "2.x-dev"
                 }
             },
             "autoload": {
@@ -1027,12 +1241,12 @@
                     "CodeSniffer/CLI.php",
                     "CodeSniffer/Exception.php",
                     "CodeSniffer/File.php",
+                    "CodeSniffer/Fixer.php",
                     "CodeSniffer/Report.php",
                     "CodeSniffer/Reporting.php",
                     "CodeSniffer/Sniff.php",
                     "CodeSniffer/Tokens.php",
                     "CodeSniffer/Reports/",
-                    "CodeSniffer/CommentParser/",
                     "CodeSniffer/Tokenizers/",
                     "CodeSniffer/DocGenerators/",
                     "CodeSniffer/Standards/AbstractPatternSniff.php",
@@ -1058,36 +1272,36 @@
                     "role": "lead"
                 }
             ],
-            "description": "PHP_CodeSniffer tokenises PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+            "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
             "homepage": "http://www.squizlabs.com/php-codesniffer",
             "keywords": [
                 "phpcs",
                 "standards"
             ],
-            "time": "2014-12-04 22:32:15"
+            "time": "2016-04-03 22:58:34"
         },
         {
             "name": "symfony/console",
-            "version": "v2.6.0",
-            "target-dir": "Symfony/Component/Console",
+            "version": "v2.8.4",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/Console.git",
-                "reference": "d3bac228fd7a2aac9193e241b239880b3ba39a10"
+                "url": "https://github.com/symfony/console.git",
+                "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Console/zipball/d3bac228fd7a2aac9193e241b239880b3ba39a10",
-                "reference": "d3bac228fd7a2aac9193e241b239880b3ba39a10",
+                "url": "https://api.github.com/repos/symfony/console/zipball/9a5aef5fc0d4eff86853d44202b02be8d5a20154",
+                "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3"
+                "php": ">=5.3.9",
+                "symfony/polyfill-mbstring": "~1.0"
             },
             "require-dev": {
                 "psr/log": "~1.0",
-                "symfony/event-dispatcher": "~2.1",
-                "symfony/process": "~2.1"
+                "symfony/event-dispatcher": "~2.1|~3.0.0",
+                "symfony/process": "~2.1|~3.0.0"
             },
             "suggest": {
                 "psr/log": "For using the console logger",
@@ -1097,241 +1311,315 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.6-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
-                "psr-0": {
+                "psr-4": {
                     "Symfony\\Component\\Console\\": ""
-                }
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
             "authors": [
-                {
-                    "name": "Symfony Community",
-                    "homepage": "http://symfony.com/contributors"
-                },
                 {
                     "name": "Fabien Potencier",
                     "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
                 }
             ],
             "description": "Symfony Console Component",
-            "homepage": "http://symfony.com",
-            "time": "2014-11-20 13:24:23"
+            "homepage": "https://symfony.com",
+            "time": "2016-03-17 09:19:04"
         },
         {
             "name": "symfony/filesystem",
-            "version": "v2.6.0",
-            "target-dir": "Symfony/Component/Filesystem",
+            "version": "v2.8.4",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/Filesystem.git",
-                "reference": "6f7c7e42f20ee200d8ac5d2ec1d2a524138305e0"
+                "url": "https://github.com/symfony/filesystem.git",
+                "reference": "f08ffdf229252cd2745558cb2112df43903bcae4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Filesystem/zipball/6f7c7e42f20ee200d8ac5d2ec1d2a524138305e0",
-                "reference": "6f7c7e42f20ee200d8ac5d2ec1d2a524138305e0",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/f08ffdf229252cd2745558cb2112df43903bcae4",
+                "reference": "f08ffdf229252cd2745558cb2112df43903bcae4",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3"
+                "php": ">=5.3.9"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.6-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
-                "psr-0": {
+                "psr-4": {
                     "Symfony\\Component\\Filesystem\\": ""
-                }
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
             "authors": [
-                {
-                    "name": "Symfony Community",
-                    "homepage": "http://symfony.com/contributors"
-                },
                 {
                     "name": "Fabien Potencier",
                     "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
                 }
             ],
             "description": "Symfony Filesystem Component",
-            "homepage": "http://symfony.com",
-            "time": "2014-11-16 17:28:09"
+            "homepage": "https://symfony.com",
+            "time": "2016-03-27 10:20:16"
         },
         {
             "name": "symfony/finder",
-            "version": "v2.6.0",
-            "target-dir": "Symfony/Component/Finder",
+            "version": "v2.8.4",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/Finder.git",
-                "reference": "d574347c652a14cfee0349f744c7880e1d9029fd"
+                "url": "https://github.com/symfony/finder.git",
+                "reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Finder/zipball/d574347c652a14cfee0349f744c7880e1d9029fd",
-                "reference": "d574347c652a14cfee0349f744c7880e1d9029fd",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/ca24cf2cd4e3826f571e0067e535758e73807aa1",
+                "reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3"
+                "php": ">=5.3.9"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.6-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
-                "psr-0": {
+                "psr-4": {
                     "Symfony\\Component\\Finder\\": ""
-                }
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
             "authors": [
-                {
-                    "name": "Symfony Community",
-                    "homepage": "http://symfony.com/contributors"
-                },
                 {
                     "name": "Fabien Potencier",
                     "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
                 }
             ],
             "description": "Symfony Finder Component",
-            "homepage": "http://symfony.com",
-            "time": "2014-11-28 10:00:40"
+            "homepage": "https://symfony.com",
+            "time": "2016-03-10 10:53:53"
         },
         {
-            "name": "symfony/process",
-            "version": "v2.6.0",
-            "target-dir": "Symfony/Component/Process",
+            "name": "symfony/polyfill-mbstring",
+            "version": "v1.1.1",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/Process.git",
-                "reference": "dc88f75d1c07791e5733f90be747961dce26cf05"
+                "url": "https://github.com/symfony/polyfill-mbstring.git",
+                "reference": "1289d16209491b584839022f29257ad859b8532d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Process/zipball/dc88f75d1c07791e5733f90be747961dce26cf05",
-                "reference": "dc88f75d1c07791e5733f90be747961dce26cf05",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
+                "reference": "1289d16209491b584839022f29257ad859b8532d",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
+            "suggest": {
+                "ext-mbstring": "For best performance"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.6-dev"
+                    "dev-master": "1.1-dev"
                 }
             },
             "autoload": {
-                "psr-0": {
-                    "Symfony\\Component\\Process\\": ""
-                }
+                "psr-4": {
+                    "Symfony\\Polyfill\\Mbstring\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
             "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
                 {
                     "name": "Symfony Community",
-                    "homepage": "http://symfony.com/contributors"
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for the Mbstring extension",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "mbstring",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "time": "2016-01-20 09:13:37"
+        },
+        {
+            "name": "symfony/process",
+            "version": "v2.8.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/process.git",
+                "reference": "fb467471952ef5cf8497c029980e556b47545333"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/process/zipball/fb467471952ef5cf8497c029980e556b47545333",
+                "reference": "fb467471952ef5cf8497c029980e556b47545333",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.9"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.8-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Process\\": ""
                 },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
                     "name": "Fabien Potencier",
                     "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
                 }
             ],
             "description": "Symfony Process Component",
-            "homepage": "http://symfony.com",
-            "time": "2014-11-04 14:29:39"
+            "homepage": "https://symfony.com",
+            "time": "2016-03-23 13:11:46"
         },
         {
             "name": "symfony/yaml",
-            "version": "v2.6.0",
-            "target-dir": "Symfony/Component/Yaml",
+            "version": "v2.8.4",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/Yaml.git",
-                "reference": "51c845cf3e4bfc182d1d5c05ed1c7338361d86f8"
+                "url": "https://github.com/symfony/yaml.git",
+                "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Yaml/zipball/51c845cf3e4bfc182d1d5c05ed1c7338361d86f8",
-                "reference": "51c845cf3e4bfc182d1d5c05ed1c7338361d86f8",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb",
+                "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3"
+                "php": ">=5.3.9"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.6-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
-                "psr-0": {
+                "psr-4": {
                     "Symfony\\Component\\Yaml\\": ""
-                }
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
             "authors": [
-                {
-                    "name": "Symfony Community",
-                    "homepage": "http://symfony.com/contributors"
-                },
                 {
                     "name": "Fabien Potencier",
                     "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
                 }
             ],
             "description": "Symfony Yaml Component",
-            "homepage": "http://symfony.com",
-            "time": "2014-11-20 13:24:23"
+            "homepage": "https://symfony.com",
+            "time": "2016-03-04 07:54:35"
         },
         {
             "name": "twig/twig",
-            "version": "v1.16.2",
+            "version": "v1.24.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "42f758d9fe2146d1f0470604fc05ee43580873fc"
+                "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/42f758d9fe2146d1f0470604fc05ee43580873fc",
-                "reference": "42f758d9fe2146d1f0470604fc05ee43580873fc",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
+                "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.2.4"
+                "php": ">=5.2.7"
+            },
+            "require-dev": {
+                "symfony/debug": "~2.7",
+                "symfony/phpunit-bridge": "~2.7"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.16-dev"
+                    "dev-master": "1.24-dev"
                 }
             },
             "autoload": {
@@ -1357,7 +1645,7 @@
                 },
                 {
                     "name": "Twig Team",
-                    "homepage": "https://github.com/fabpot/Twig/graphs/contributors",
+                    "homepage": "http://twig.sensiolabs.org/contributors",
                     "role": "Contributors"
                 }
             ],
@@ -1366,13 +1654,14 @@
             "keywords": [
                 "templating"
             ],
-            "time": "2014-10-17 12:53:44"
+            "time": "2016-01-25 21:22:18"
         }
     ],
     "aliases": [],
     "minimum-stability": "stable",
     "stability-flags": [],
     "prefer-stable": false,
+    "prefer-lowest": false,
     "platform": {
         "php": ">=5.0.0"
     },
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
index 6b1f9daa68845c309ac06c5ef55e8934ec50fe02..594011e51c93b779d06111e9280d0be497acda45 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
@@ -7,13 +7,17 @@
  *
  * PHP versions 4 and 5
  *
- * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
- * {@link Crypt_AES::setKey() setKey()}.  ie. if the key is 128-bits, the key length will be 128-bits.  If it's 136-bits
- * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link Crypt_AES::setKey() setKey()}
+ * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
+ * just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
+ * to save one include_once().
+ *
+ * If {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
+ * {@link self::setKey() setKey()}.  ie. if the key is 128-bits, the key length will be 128-bits.  If it's 136-bits
+ * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()}
  * is called, again, at which point, it'll be recalculated.
  *
  * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
- * make a whole lot of sense.  {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance.  Calling that function,
+ * make a whole lot of sense.  {@link self::setBlockLength() setBlockLength()}, for instance.  Calling that function,
  * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
  *
  * Here's a short example of how to use this library:
@@ -70,8 +74,8 @@ if (!class_exists('Crypt_Rijndael')) {
 
 /**#@+
  * @access public
- * @see Crypt_AES::encrypt()
- * @see Crypt_AES::decrypt()
+ * @see self::encrypt()
+ * @see self::decrypt()
  */
 /**
  * Encrypt / decrypt using the Counter mode.
@@ -107,20 +111,6 @@ define('CRYPT_AES_MODE_CFB', CRYPT_MODE_CFB);
 define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB);
 /**#@-*/
 
-/**#@+
- * @access private
- * @see Crypt_Base::Crypt_Base()
- */
-/**
- * Toggles the internal implementation
- */
-define('CRYPT_AES_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
-/**
- * Toggles the mcrypt implementation
- */
-define('CRYPT_AES_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
-/**#@-*/
-
 /**
  * Pure-PHP implementation of AES.
  *
@@ -134,7 +124,7 @@ class Crypt_AES extends Crypt_Rijndael
      * The namespace used by the cipher for its constants.
      *
      * @see Crypt_Base::const_namespace
-     * @var String
+     * @var string
      * @access private
      */
     var $const_namespace = 'AES';
@@ -146,7 +136,7 @@ class Crypt_AES extends Crypt_Rijndael
      *
      * @see Crypt_Rijndael::setBlockLength()
      * @access public
-     * @param Integer $length
+     * @param int $length
      */
     function setBlockLength($length)
     {
@@ -161,7 +151,7 @@ class Crypt_AES extends Crypt_Rijndael
      *
      * @see Crypt_Rijndael:setKeyLength()
      * @access public
-     * @param Integer $length
+     * @param int $length
      */
     function setKeyLength($length)
     {
@@ -183,7 +173,7 @@ class Crypt_AES extends Crypt_Rijndael
      * @see Crypt_Rijndael:setKey()
      * @see setKeyLength()
      * @access public
-     * @param String $key
+     * @param string $key
      */
     function setKey($key)
     {
@@ -193,15 +183,15 @@ class Crypt_AES extends Crypt_Rijndael
             $length = strlen($key);
             switch (true) {
                 case $length <= 16:
-                    $this->key_size = 16;
+                    $this->key_length = 16;
                     break;
                 case $length <= 24:
-                    $this->key_size = 24;
+                    $this->key_length = 24;
                     break;
                 default:
-                    $this->key_size = 32;
+                    $this->key_length = 32;
             }
-            $this->_setupEngine();
+            $this->_setEngine();
         }
     }
 }
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
index 4df2a2db0e17880006dfc869ec08d460b013e1f9..91ebe593c648c8fe16447df0ff2a8ea69cb67545 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
@@ -54,8 +54,8 @@
 
 /**#@+
  * @access public
- * @see Crypt_Base::encrypt()
- * @see Crypt_Base::decrypt()
+ * @see self::encrypt()
+ * @see self::decrypt()
  */
 /**
  * Encrypt / decrypt using the Counter mode.
@@ -91,23 +91,27 @@ define('CRYPT_MODE_CFB', 3);
 define('CRYPT_MODE_OFB', 4);
 /**
  * Encrypt / decrypt using streaming mode.
- *
  */
 define('CRYPT_MODE_STREAM', 5);
 /**#@-*/
 
 /**#@+
  * @access private
- * @see Crypt_Base::Crypt_Base()
+ * @see self::Crypt_Base()
+ * @internal These constants are for internal use only
  */
 /**
  * Base value for the internal implementation $engine switch
  */
-define('CRYPT_MODE_INTERNAL', 1);
+define('CRYPT_ENGINE_INTERNAL', 1);
 /**
  * Base value for the mcrypt implementation $engine switch
  */
-define('CRYPT_MODE_MCRYPT', 2);
+define('CRYPT_ENGINE_MCRYPT', 2);
+/**
+ * Base value for the OpenSSL implementation $engine switch
+ */
+define('CRYPT_ENGINE_OPENSSL', 3);
 /**#@-*/
 
 /**
@@ -123,8 +127,8 @@ class Crypt_Base
     /**
      * The Encryption Mode
      *
-     * @see Crypt_Base::Crypt_Base()
-     * @var Integer
+     * @see self::Crypt_Base()
+     * @var int
      * @access private
      */
     var $mode;
@@ -132,7 +136,7 @@ class Crypt_Base
     /**
      * The Block Length of the block cipher
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $block_size = 16;
@@ -140,8 +144,8 @@ class Crypt_Base
     /**
      * The Key
      *
-     * @see Crypt_Base::setKey()
-     * @var String
+     * @see self::setKey()
+     * @var string
      * @access private
      */
     var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
@@ -149,8 +153,8 @@ class Crypt_Base
     /**
      * The Initialization Vector
      *
-     * @see Crypt_Base::setIV()
-     * @var String
+     * @see self::setIV()
+     * @var string
      * @access private
      */
     var $iv;
@@ -158,9 +162,9 @@ class Crypt_Base
     /**
      * A "sliding" Initialization Vector
      *
-     * @see Crypt_Base::enableContinuousBuffer()
-     * @see Crypt_Base::_clearBuffers()
-     * @var String
+     * @see self::enableContinuousBuffer()
+     * @see self::_clearBuffers()
+     * @var string
      * @access private
      */
     var $encryptIV;
@@ -168,9 +172,9 @@ class Crypt_Base
     /**
      * A "sliding" Initialization Vector
      *
-     * @see Crypt_Base::enableContinuousBuffer()
-     * @see Crypt_Base::_clearBuffers()
-     * @var String
+     * @see self::enableContinuousBuffer()
+     * @see self::_clearBuffers()
+     * @var string
      * @access private
      */
     var $decryptIV;
@@ -178,8 +182,8 @@ class Crypt_Base
     /**
      * Continuous Buffer status
      *
-     * @see Crypt_Base::enableContinuousBuffer()
-     * @var Boolean
+     * @see self::enableContinuousBuffer()
+     * @var bool
      * @access private
      */
     var $continuousBuffer = false;
@@ -187,9 +191,9 @@ class Crypt_Base
     /**
      * Encryption buffer for CTR, OFB and CFB modes
      *
-     * @see Crypt_Base::encrypt()
-     * @see Crypt_Base::_clearBuffers()
-     * @var Array
+     * @see self::encrypt()
+     * @see self::_clearBuffers()
+     * @var array
      * @access private
      */
     var $enbuffer;
@@ -197,9 +201,9 @@ class Crypt_Base
     /**
      * Decryption buffer for CTR, OFB and CFB modes
      *
-     * @see Crypt_Base::decrypt()
-     * @see Crypt_Base::_clearBuffers()
-     * @var Array
+     * @see self::decrypt()
+     * @see self::_clearBuffers()
+     * @var array
      * @access private
      */
     var $debuffer;
@@ -210,8 +214,8 @@ class Crypt_Base
      * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
      * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
      *
-     * @see Crypt_Base::encrypt()
-     * @var Resource
+     * @see self::encrypt()
+     * @var resource
      * @access private
      */
     var $enmcrypt;
@@ -222,8 +226,8 @@ class Crypt_Base
      * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
      * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
      *
-     * @see Crypt_Base::decrypt()
-     * @var Resource
+     * @see self::decrypt()
+     * @var resource
      * @access private
      */
     var $demcrypt;
@@ -233,7 +237,7 @@ class Crypt_Base
      *
      * @see Crypt_Twofish::setKey()
      * @see Crypt_Twofish::setIV()
-     * @var Boolean
+     * @var bool
      * @access private
      */
     var $enchanged = true;
@@ -243,7 +247,7 @@ class Crypt_Base
      *
      * @see Crypt_Twofish::setKey()
      * @see Crypt_Twofish::setIV()
-     * @var Boolean
+     * @var bool
      * @access private
      */
     var $dechanged = true;
@@ -259,10 +263,10 @@ class Crypt_Base
      * use a separate ECB-mode mcrypt resource.
      *
      * @link http://phpseclib.sourceforge.net/cfb-demo.phps
-     * @see Crypt_Base::encrypt()
-     * @see Crypt_Base::decrypt()
-     * @see Crypt_Base::_setupMcrypt()
-     * @var Resource
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @see self::_setupMcrypt()
+     * @var resource
      * @access private
      */
     var $ecb;
@@ -271,7 +275,7 @@ class Crypt_Base
      * Optimizing value while CFB-encrypting
      *
      * Only relevant if $continuousBuffer enabled
-     * and $engine == CRYPT_MODE_MCRYPT
+     * and $engine == CRYPT_ENGINE_MCRYPT
      *
      * It's faster to re-init $enmcrypt if
      * $buffer bytes > $cfb_init_len than
@@ -283,8 +287,8 @@ class Crypt_Base
      * which, typically, depends on the complexity
      * on its internaly Key-expanding algorithm.
      *
-     * @see Crypt_Base::encrypt()
-     * @var Integer
+     * @see self::encrypt()
+     * @var int
      * @access private
      */
     var $cfb_init_len = 600;
@@ -292,10 +296,10 @@ class Crypt_Base
     /**
      * Does internal cipher state need to be (re)initialized?
      *
-     * @see setKey()
-     * @see setIV()
-     * @see disableContinuousBuffer()
-     * @var Boolean
+     * @see self::setKey()
+     * @see self::setIV()
+     * @see self::disableContinuousBuffer()
+     * @var bool
      * @access private
      */
     var $changed = true;
@@ -303,8 +307,8 @@ class Crypt_Base
     /**
      * Padding status
      *
-     * @see Crypt_Base::enablePadding()
-     * @var Boolean
+     * @see self::enablePadding()
+     * @var bool
      * @access private
      */
     var $padding = true;
@@ -312,8 +316,8 @@ class Crypt_Base
     /**
      * Is the mode one that is paddable?
      *
-     * @see Crypt_Base::Crypt_Base()
-     * @var Boolean
+     * @see self::Crypt_Base()
+     * @var bool
      * @access private
      */
     var $paddable = false;
@@ -323,49 +327,69 @@ class Crypt_Base
      * which will be determined automatically on __construct()
      *
      * Currently available $engines are:
-     * - CRYPT_MODE_MCRYPT   (fast, php-extension: mcrypt, extension_loaded('mcrypt') required)
-     * - CRYPT_MODE_INTERNAL (slower, pure php-engine, no php-extension required)
-     *
-     * In the pipeline... maybe. But currently not available:
-     * - CRYPT_MODE_OPENSSL  (very fast, php-extension: openssl, extension_loaded('openssl') required)
-     *
-     * If possible, CRYPT_MODE_MCRYPT will be used for each cipher.
-     * Otherwise CRYPT_MODE_INTERNAL
-     *
-     * @see Crypt_Base::encrypt()
-     * @see Crypt_Base::decrypt()
-     * @var Integer
+     * - CRYPT_ENGINE_OPENSSL  (very fast, php-extension: openssl, extension_loaded('openssl') required)
+     * - CRYPT_ENGINE_MCRYPT   (fast, php-extension: mcrypt, extension_loaded('mcrypt') required)
+     * - CRYPT_ENGINE_INTERNAL (slower, pure php-engine, no php-extension required)
+     *
+     * @see self::_setEngine()
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @var int
      * @access private
      */
     var $engine;
 
+    /**
+     * Holds the preferred crypt engine
+     *
+     * @see self::_setEngine()
+     * @see self::setPreferredEngine()
+     * @var int
+     * @access private
+     */
+    var $preferredEngine;
+
     /**
      * The mcrypt specific name of the cipher
      *
-     * Only used if $engine == CRYPT_MODE_MCRYPT
+     * Only used if $engine == CRYPT_ENGINE_MCRYPT
      *
      * @link http://www.php.net/mcrypt_module_open
      * @link http://www.php.net/mcrypt_list_algorithms
-     * @see Crypt_Base::_setupMcrypt()
-     * @var String
+     * @see self::_setupMcrypt()
+     * @var string
      * @access private
      */
     var $cipher_name_mcrypt;
 
     /**
-     * The default password key_size used by setPassword()
+     * The openssl specific name of the cipher
      *
-     * @see Crypt_Base::setPassword()
-     * @var Integer
+     * Only used if $engine == CRYPT_ENGINE_OPENSSL
+     *
+     * @link http://www.php.net/openssl-get-cipher-methods
+     * @var string
      * @access private
      */
-    var $password_key_size = 32;
+    var $cipher_name_openssl;
+
+    /**
+     * The openssl specific name of the cipher in ECB mode
+     *
+     * If OpenSSL does not support the mode we're trying to use (CTR)
+     * it can still be emulated with ECB mode.
+     *
+     * @link http://www.php.net/openssl-get-cipher-methods
+     * @var string
+     * @access private
+     */
+    var $cipher_name_openssl_ecb;
 
     /**
      * The default salt used by setPassword()
      *
-     * @see Crypt_Base::setPassword()
-     * @var String
+     * @see self::setPassword()
+     * @var string
      * @access private
      */
     var $password_default_salt = 'phpseclib/salt';
@@ -387,8 +411,8 @@ class Crypt_Base
      * $aes = new Crypt_AES(CRYPT_AES_MODE_CFB); // $aes will operate in cfb mode
      * $aes = new Crypt_AES(CRYPT_MODE_CFB);     // identical
      *
-     * @see Crypt_Base::Crypt_Base()
-     * @var String
+     * @see self::Crypt_Base()
+     * @var string
      * @access private
      */
     var $const_namespace;
@@ -397,12 +421,12 @@ class Crypt_Base
      * The name of the performance-optimized callback function
      *
      * Used by encrypt() / decrypt()
-     * only if $engine == CRYPT_MODE_INTERNAL
+     * only if $engine == CRYPT_ENGINE_INTERNAL
      *
-     * @see Crypt_Base::encrypt()
-     * @see Crypt_Base::decrypt()
-     * @see Crypt_Base::_setupInlineCrypt()
-     * @see Crypt_Base::$use_inline_crypt
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @see self::_setupInlineCrypt()
+     * @see self::$use_inline_crypt
      * @var Callback
      * @access private
      */
@@ -411,14 +435,50 @@ class Crypt_Base
     /**
      * Holds whether performance-optimized $inline_crypt() can/should be used.
      *
-     * @see Crypt_Base::encrypt()
-     * @see Crypt_Base::decrypt()
-     * @see Crypt_Base::inline_crypt
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @see self::inline_crypt
      * @var mixed
      * @access private
      */
     var $use_inline_crypt;
 
+    /**
+     * If OpenSSL can be used in ECB but not in CTR we can emulate CTR
+     *
+     * @see self::_openssl_ctr_process()
+     * @var bool
+     * @access private
+     */
+    var $openssl_emulate_ctr = false;
+
+    /**
+     * Determines what options are passed to openssl_encrypt/decrypt
+     *
+     * @see self::isValidEngine()
+     * @var mixed
+     * @access private
+     */
+    var $openssl_options;
+
+    /**
+     * Has the key length explicitly been set or should it be derived from the key, itself?
+     *
+     * @see self::setKeyLength()
+     * @var bool
+     * @access private
+     */
+    var $explicit_key_length = false;
+
+    /**
+     * Don't truncate / null pad key
+     *
+     * @see self::_clearBuffers()
+     * @var bool
+     * @access private
+     */
+    var $skip_key_adjustment = false;
+
     /**
      * Default Constructor.
      *
@@ -440,42 +500,16 @@ class Crypt_Base
      *
      * If not explicitly set, CRYPT_MODE_CBC will be used.
      *
-     * @param optional Integer $mode
+     * @param int $mode
      * @access public
      */
-    function Crypt_Base($mode = CRYPT_MODE_CBC)
+    function __construct($mode = CRYPT_MODE_CBC)
     {
-        $const_crypt_mode = 'CRYPT_' . $this->const_namespace . '_MODE';
-
-        // Determining the availibility of mcrypt support for the cipher
-        if (!defined($const_crypt_mode)) {
-            switch (true) {
-                case extension_loaded('mcrypt') && in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()):
-                    define($const_crypt_mode, CRYPT_MODE_MCRYPT);
-                    break;
-                default:
-                    define($const_crypt_mode, CRYPT_MODE_INTERNAL);
-            }
-        }
-
-        // Determining which internal $engine should be used.
-        // The fastes possible first.
-        switch (true) {
-            case empty($this->cipher_name_mcrypt): // The cipher module has no mcrypt-engine support at all so we force CRYPT_MODE_INTERNAL
-                $this->engine = CRYPT_MODE_INTERNAL;
-                break;
-            case constant($const_crypt_mode) == CRYPT_MODE_MCRYPT:
-                $this->engine = CRYPT_MODE_MCRYPT;
-                break;
-            default:
-                $this->engine = CRYPT_MODE_INTERNAL;
-        }
-
         // $mode dependent settings
         switch ($mode) {
             case CRYPT_MODE_ECB:
                 $this->paddable = true;
-                $this->mode = $mode;
+                $this->mode = CRYPT_MODE_ECB;
                 break;
             case CRYPT_MODE_CTR:
             case CRYPT_MODE_CFB:
@@ -489,22 +523,35 @@ class Crypt_Base
                 $this->mode = CRYPT_MODE_CBC;
         }
 
+        $this->_setEngine();
+
         // Determining whether inline crypting can be used by the cipher
         if ($this->use_inline_crypt !== false && function_exists('create_function')) {
             $this->use_inline_crypt = true;
         }
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @param int $mode
+     * @access public
+     */
+    function Crypt_Base($mode = CRYPT_MODE_CBC)
+    {
+        $this->__construct($mode);
+    }
+
     /**
      * Sets the initialization vector. (optional)
      *
      * SetIV is not required when CRYPT_MODE_ECB (or ie for AES: CRYPT_AES_MODE_ECB) is being used.  If not explicitly set, it'll be assumed
      * to be all zero's.
      *
-     * Note: Could, but not must, extend by the child Crypt_* class
-     *
      * @access public
-     * @param String $iv
+     * @param string $iv
+     * @internal Can be overwritten by a sub class, but does not have to be
      */
     function setIV($iv)
     {
@@ -516,6 +563,43 @@ class Crypt_Base
         $this->changed = true;
     }
 
+    /**
+     * Sets the key length.
+     *
+     * Keys with explicitly set lengths need to be treated accordingly
+     *
+     * @access public
+     * @param int $length
+     */
+    function setKeyLength($length)
+    {
+        $this->explicit_key_length = true;
+        $this->changed = true;
+        $this->_setEngine();
+    }
+
+    /**
+     * Returns the current key length in bits
+     *
+     * @access public
+     * @return int
+     */
+    function getKeyLength()
+    {
+        return $this->key_length << 3;
+    }
+
+    /**
+     * Returns the current block length in bits
+     *
+     * @access public
+     * @return int
+     */
+    function getBlockLength()
+    {
+        return $this->block_size << 3;
+    }
+
     /**
      * Sets the key.
      *
@@ -526,15 +610,20 @@ class Crypt_Base
      *
      * If the key is not explicitly set, it'll be assumed to be all null bytes.
      *
-     * Note: Could, but not must, extend by the child Crypt_* class
-     *
      * @access public
-     * @param String $key
+     * @param string $key
+     * @internal Could, but not must, extend by the child Crypt_* class
      */
     function setKey($key)
     {
+        if (!$this->explicit_key_length) {
+            $this->setKeyLength(strlen($key) << 3);
+            $this->explicit_key_length = false;
+        }
+
         $this->key = $key;
         $this->changed = true;
+        $this->_setEngine();
     }
 
     /**
@@ -546,13 +635,12 @@ class Crypt_Base
      *
      *         Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php
      *
-     * Note: Could, but not must, extend by the child Crypt_* class
-     *
      * @see Crypt/Hash.php
-     * @param String $password
-     * @param optional String $method
-     * @return Boolean
+     * @param string $password
+     * @param string $method
+     * @return bool
      * @access public
+     * @internal Could, but not must, extend by the child Crypt_* class
      */
     function setPassword($password, $method = 'pbkdf2')
     {
@@ -576,7 +664,7 @@ class Crypt_Base
                 if (isset($func_args[5])) {
                     $dkLen = $func_args[5];
                 } else {
-                    $dkLen = $method == 'pbkdf1' ? 2 * $this->password_key_size : $this->password_key_size;
+                    $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
                 }
 
                 switch (true) {
@@ -645,22 +733,100 @@ class Crypt_Base
      * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that
      * length.
      *
-     * Note: Could, but not must, extend by the child Crypt_* class
-     *
-     * @see Crypt_Base::decrypt()
+     * @see self::decrypt()
      * @access public
-     * @param String $plaintext
-     * @return String $cipertext
+     * @param string $plaintext
+     * @return string $ciphertext
+     * @internal Could, but not must, extend by the child Crypt_* class
      */
     function encrypt($plaintext)
     {
-        if ($this->engine == CRYPT_MODE_MCRYPT) {
+        if ($this->paddable) {
+            $plaintext = $this->_pad($plaintext);
+        }
+
+        if ($this->engine === CRYPT_ENGINE_OPENSSL) {
+            if ($this->changed) {
+                $this->_clearBuffers();
+                $this->changed = false;
+            }
+            switch ($this->mode) {
+                case CRYPT_MODE_STREAM:
+                    return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+                case CRYPT_MODE_ECB:
+                    $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+                    return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
+                case CRYPT_MODE_CBC:
+                    $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
+                    if (!defined('OPENSSL_RAW_DATA')) {
+                        $result = substr($result, 0, -$this->block_size);
+                    }
+                    if ($this->continuousBuffer) {
+                        $this->encryptIV = substr($result, -$this->block_size);
+                    }
+                    return $result;
+                case CRYPT_MODE_CTR:
+                    return $this->_openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer);
+                case CRYPT_MODE_CFB:
+                    // cfb loosely routines inspired by openssl's:
+                    // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
+                    $ciphertext = '';
+                    if ($this->continuousBuffer) {
+                        $iv = &$this->encryptIV;
+                        $pos = &$this->enbuffer['pos'];
+                    } else {
+                        $iv = $this->encryptIV;
+                        $pos = 0;
+                    }
+                    $len = strlen($plaintext);
+                    $i = 0;
+                    if ($pos) {
+                        $orig_pos = $pos;
+                        $max = $this->block_size - $pos;
+                        if ($len >= $max) {
+                            $i = $max;
+                            $len-= $max;
+                            $pos = 0;
+                        } else {
+                            $i = $len;
+                            $pos+= $len;
+                            $len = 0;
+                        }
+                        // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
+                        $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
+                        $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
+                        $plaintext = substr($plaintext, $i);
+                    }
+
+                    $overflow = $len % $this->block_size;
+
+                    if ($overflow) {
+                        $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+                        $iv = $this->_string_pop($ciphertext, $this->block_size);
+
+                        $size = $len - $overflow;
+                        $block = $iv ^ substr($plaintext, -$overflow);
+                        $iv = substr_replace($iv, $block, 0, $overflow);
+                        $ciphertext.= $block;
+                        $pos = $overflow;
+                    } elseif ($len) {
+                        $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+                        $iv = substr($ciphertext, -$this->block_size);
+                    }
+
+                    return $ciphertext;
+                case CRYPT_MODE_OFB:
+                    return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
+            }
+        }
+
+        if ($this->engine === CRYPT_ENGINE_MCRYPT) {
             if ($this->changed) {
                 $this->_setupMcrypt();
                 $this->changed = false;
             }
             if ($this->enchanged) {
-                mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
+                @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
                 $this->enchanged = false;
             }
 
@@ -693,15 +859,15 @@ class Crypt_Base
                 if ($len >= $block_size) {
                     if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) {
                         if ($this->enbuffer['enmcrypt_init'] === true) {
-                            mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
+                            @mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
                             $this->enbuffer['enmcrypt_init'] = false;
                         }
-                        $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
+                        $ciphertext.= @mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
                         $iv = substr($ciphertext, -$block_size);
                         $len%= $block_size;
                     } else {
                         while ($len >= $block_size) {
-                            $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
+                            $iv = @mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
                             $ciphertext.= $iv;
                             $len-= $block_size;
                             $i+= $block_size;
@@ -710,7 +876,7 @@ class Crypt_Base
                 }
 
                 if ($len) {
-                    $iv = mcrypt_generic($this->ecb, $iv);
+                    $iv = @mcrypt_generic($this->ecb, $iv);
                     $block = $iv ^ substr($plaintext, -$len);
                     $iv = substr_replace($iv, $block, 0, $len);
                     $ciphertext.= $block;
@@ -720,14 +886,10 @@ class Crypt_Base
                 return $ciphertext;
             }
 
-            if ($this->paddable) {
-                $plaintext = $this->_pad($plaintext);
-            }
-
-            $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
+            $ciphertext = @mcrypt_generic($this->enmcrypt, $plaintext);
 
             if (!$this->continuousBuffer) {
-                mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
+                @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
             }
 
             return $ciphertext;
@@ -741,9 +903,6 @@ class Crypt_Base
             $inline = $this->inline_crypt;
             return $inline('encrypt', $this, $plaintext);
         }
-        if ($this->paddable) {
-            $plaintext = $this->_pad($plaintext);
-        }
 
         $buffer = &$this->enbuffer;
         $block_size = $this->block_size;
@@ -768,26 +927,28 @@ class Crypt_Base
                 break;
             case CRYPT_MODE_CTR:
                 $xor = $this->encryptIV;
-                if (strlen($buffer['encrypted'])) {
+                if (strlen($buffer['ciphertext'])) {
                     for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
                         $block = substr($plaintext, $i, $block_size);
-                        if (strlen($block) > strlen($buffer['encrypted'])) {
-                            $buffer['encrypted'].= $this->_encryptBlock($this->_generateXor($xor, $block_size));
+                        if (strlen($block) > strlen($buffer['ciphertext'])) {
+                            $buffer['ciphertext'].= $this->_encryptBlock($xor);
                         }
-                        $key = $this->_stringShift($buffer['encrypted'], $block_size);
+                        $this->_increment_str($xor);
+                        $key = $this->_string_shift($buffer['ciphertext'], $block_size);
                         $ciphertext.= $block ^ $key;
                     }
                 } else {
                     for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
                         $block = substr($plaintext, $i, $block_size);
-                        $key = $this->_encryptBlock($this->_generateXor($xor, $block_size));
+                        $key = $this->_encryptBlock($xor);
+                        $this->_increment_str($xor);
                         $ciphertext.= $block ^ $key;
                     }
                 }
                 if ($this->continuousBuffer) {
                     $this->encryptIV = $xor;
                     if ($start = strlen($plaintext) % $block_size) {
-                        $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted'];
+                        $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
                     }
                 }
                 break;
@@ -842,7 +1003,7 @@ class Crypt_Base
                             $xor = $this->_encryptBlock($xor);
                             $buffer['xor'].= $xor;
                         }
-                        $key = $this->_stringShift($buffer['xor'], $block_size);
+                        $key = $this->_string_shift($buffer['xor'], $block_size);
                         $ciphertext.= $block ^ $key;
                     }
                 } else {
@@ -855,7 +1016,7 @@ class Crypt_Base
                 if ($this->continuousBuffer) {
                     $this->encryptIV = $xor;
                     if ($start = strlen($plaintext) % $block_size) {
-                         $buffer['xor'] = substr($key, $start) . $buffer['xor'];
+                        $buffer['xor'] = substr($key, $start) . $buffer['xor'];
                     }
                 }
                 break;
@@ -873,23 +1034,111 @@ class Crypt_Base
      * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
      * it is.
      *
-     * Note: Could, but not must, extend by the child Crypt_* class
-     *
-     * @see Crypt_Base::encrypt()
+     * @see self::encrypt()
      * @access public
-     * @param String $ciphertext
-     * @return String $plaintext
+     * @param string $ciphertext
+     * @return string $plaintext
+     * @internal Could, but not must, extend by the child Crypt_* class
      */
     function decrypt($ciphertext)
     {
-        if ($this->engine == CRYPT_MODE_MCRYPT) {
+        if ($this->paddable) {
+            // we pad with chr(0) since that's what mcrypt_generic does.  to quote from {@link http://www.php.net/function.mcrypt-generic}:
+            // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
+            $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
+        }
+
+        if ($this->engine === CRYPT_ENGINE_OPENSSL) {
+            if ($this->changed) {
+                $this->_clearBuffers();
+                $this->changed = false;
+            }
+            switch ($this->mode) {
+                case CRYPT_MODE_STREAM:
+                    $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+                    break;
+                case CRYPT_MODE_ECB:
+                    if (!defined('OPENSSL_RAW_DATA')) {
+                        $ciphertext.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
+                    }
+                    $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+                    break;
+                case CRYPT_MODE_CBC:
+                    if (!defined('OPENSSL_RAW_DATA')) {
+                        $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
+                        $ciphertext.= substr(openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
+                        $offset = 2 * $this->block_size;
+                    } else {
+                        $offset = $this->block_size;
+                    }
+                    $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV);
+                    if ($this->continuousBuffer) {
+                        $this->decryptIV = substr($ciphertext, -$offset, $this->block_size);
+                    }
+                    break;
+                case CRYPT_MODE_CTR:
+                    $plaintext = $this->_openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer);
+                    break;
+                case CRYPT_MODE_CFB:
+                    // cfb loosely routines inspired by openssl's:
+                    // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
+                    $plaintext = '';
+                    if ($this->continuousBuffer) {
+                        $iv = &$this->decryptIV;
+                        $pos = &$this->buffer['pos'];
+                    } else {
+                        $iv = $this->decryptIV;
+                        $pos = 0;
+                    }
+                    $len = strlen($ciphertext);
+                    $i = 0;
+                    if ($pos) {
+                        $orig_pos = $pos;
+                        $max = $this->block_size - $pos;
+                        if ($len >= $max) {
+                            $i = $max;
+                            $len-= $max;
+                            $pos = 0;
+                        } else {
+                            $i = $len;
+                            $pos+= $len;
+                            $len = 0;
+                        }
+                        // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize
+                        $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
+                        $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
+                        $ciphertext = substr($ciphertext, $i);
+                    }
+                    $overflow = $len % $this->block_size;
+                    if ($overflow) {
+                        $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+                        if ($len - $overflow) {
+                            $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow);
+                        }
+                        $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+                        $plaintext.= $iv ^ substr($ciphertext, -$overflow);
+                        $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow);
+                        $pos = $overflow;
+                    } elseif ($len) {
+                        $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+                        $iv = substr($ciphertext, -$this->block_size);
+                    }
+                    break;
+                case CRYPT_MODE_OFB:
+                    $plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
+            }
+
+            return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
+        }
+
+        if ($this->engine === CRYPT_ENGINE_MCRYPT) {
             $block_size = $this->block_size;
             if ($this->changed) {
                 $this->_setupMcrypt();
                 $this->changed = false;
             }
             if ($this->dechanged) {
-                mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
+                @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
                 $this->dechanged = false;
             }
 
@@ -917,12 +1166,12 @@ class Crypt_Base
                 }
                 if ($len >= $block_size) {
                     $cb = substr($ciphertext, $i, $len - $len % $block_size);
-                    $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
+                    $plaintext.= @mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
                     $iv = substr($cb, -$block_size);
                     $len%= $block_size;
                 }
                 if ($len) {
-                    $iv = mcrypt_generic($this->ecb, $iv);
+                    $iv = @mcrypt_generic($this->ecb, $iv);
                     $plaintext.= $iv ^ substr($ciphertext, -$len);
                     $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
                     $pos = $len;
@@ -931,16 +1180,10 @@ class Crypt_Base
                 return $plaintext;
             }
 
-            if ($this->paddable) {
-                // we pad with chr(0) since that's what mcrypt_generic does.  to quote from {@link http://www.php.net/function.mcrypt-generic}:
-                // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
-                $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($block_size - strlen($ciphertext) % $block_size) % $block_size, chr(0));
-            }
-
-            $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
+            $plaintext = @mdecrypt_generic($this->demcrypt, $ciphertext);
 
             if (!$this->continuousBuffer) {
-                mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
+                @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
             }
 
             return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
@@ -956,10 +1199,6 @@ class Crypt_Base
         }
 
         $block_size = $this->block_size;
-        if ($this->paddable) {
-            // we pad with chr(0) since that's what mcrypt_generic does [...]
-            $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($block_size - strlen($ciphertext) % $block_size) % $block_size, chr(0));
-        }
 
         $buffer = &$this->debuffer;
         $plaintext = '';
@@ -986,15 +1225,17 @@ class Crypt_Base
                     for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
                         $block = substr($ciphertext, $i, $block_size);
                         if (strlen($block) > strlen($buffer['ciphertext'])) {
-                            $buffer['ciphertext'].= $this->_encryptBlock($this->_generateXor($xor, $block_size));
+                            $buffer['ciphertext'].= $this->_encryptBlock($xor);
+                            $this->_increment_str($xor);
                         }
-                        $key = $this->_stringShift($buffer['ciphertext'], $block_size);
+                        $key = $this->_string_shift($buffer['ciphertext'], $block_size);
                         $plaintext.= $block ^ $key;
                     }
                 } else {
                     for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
                         $block = substr($ciphertext, $i, $block_size);
-                        $key = $this->_encryptBlock($this->_generateXor($xor, $block_size));
+                        $key = $this->_encryptBlock($xor);
+                        $this->_increment_str($xor);
                         $plaintext.= $block ^ $key;
                     }
                 }
@@ -1055,7 +1296,7 @@ class Crypt_Base
                             $xor = $this->_encryptBlock($xor);
                             $buffer['xor'].= $xor;
                         }
-                        $key = $this->_stringShift($buffer['xor'], $block_size);
+                        $key = $this->_string_shift($buffer['xor'], $block_size);
                         $plaintext.= $block ^ $key;
                     }
                 } else {
@@ -1068,7 +1309,7 @@ class Crypt_Base
                 if ($this->continuousBuffer) {
                     $this->decryptIV = $xor;
                     if ($start = strlen($ciphertext) % $block_size) {
-                         $buffer['xor'] = substr($key, $start) . $buffer['xor'];
+                        $buffer['xor'] = substr($key, $start) . $buffer['xor'];
                     }
                 }
                 break;
@@ -1079,6 +1320,178 @@ class Crypt_Base
         return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
     }
 
+    /**
+     * OpenSSL CTR Processor
+     *
+     * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
+     * for CTR is the same for both encrypting and decrypting this function is re-used by both Crypt_Base::encrypt()
+     * and Crypt_Base::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this
+     * function will emulate CTR with ECB when necessary.
+     *
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @param string $plaintext
+     * @param string $encryptIV
+     * @param array $buffer
+     * @return string
+     * @access private
+     */
+    function _openssl_ctr_process($plaintext, &$encryptIV, &$buffer)
+    {
+        $ciphertext = '';
+
+        $block_size = $this->block_size;
+        $key = $this->key;
+
+        if ($this->openssl_emulate_ctr) {
+            $xor = $encryptIV;
+            if (strlen($buffer['ciphertext'])) {
+                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                    $block = substr($plaintext, $i, $block_size);
+                    if (strlen($block) > strlen($buffer['ciphertext'])) {
+                        $result = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+                        $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
+                        $buffer['ciphertext'].= $result;
+                    }
+                    $this->_increment_str($xor);
+                    $otp = $this->_string_shift($buffer['ciphertext'], $block_size);
+                    $ciphertext.= $block ^ $otp;
+                }
+            } else {
+                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                    $block = substr($plaintext, $i, $block_size);
+                    $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+                    $otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
+                    $this->_increment_str($xor);
+                    $ciphertext.= $block ^ $otp;
+                }
+            }
+            if ($this->continuousBuffer) {
+                $encryptIV = $xor;
+                if ($start = strlen($plaintext) % $block_size) {
+                    $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
+                }
+            }
+
+            return $ciphertext;
+        }
+
+        if (strlen($buffer['ciphertext'])) {
+            $ciphertext = $plaintext ^ $this->_string_shift($buffer['ciphertext'], strlen($plaintext));
+            $plaintext = substr($plaintext, strlen($ciphertext));
+
+            if (!strlen($plaintext)) {
+                return $ciphertext;
+            }
+        }
+
+        $overflow = strlen($plaintext) % $block_size;
+        if ($overflow) {
+            $plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2
+            $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+            $temp = $this->_string_pop($encrypted, $block_size);
+            $ciphertext.= $encrypted . ($plaintext2 ^ $temp);
+            if ($this->continuousBuffer) {
+                $buffer['ciphertext'] = substr($temp, $overflow);
+                $encryptIV = $temp;
+            }
+        } elseif (!strlen($buffer['ciphertext'])) {
+            $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+            $temp = $this->_string_pop($ciphertext, $block_size);
+            if ($this->continuousBuffer) {
+                $encryptIV = $temp;
+            }
+        }
+        if ($this->continuousBuffer) {
+            if (!defined('OPENSSL_RAW_DATA')) {
+                $encryptIV.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+            }
+            $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+            if ($overflow) {
+                $this->_increment_str($encryptIV);
+            }
+        }
+
+        return $ciphertext;
+    }
+
+    /**
+     * OpenSSL OFB Processor
+     *
+     * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
+     * for OFB is the same for both encrypting and decrypting this function is re-used by both Crypt_Base::encrypt()
+     * and Crypt_Base::decrypt().
+     *
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @param string $plaintext
+     * @param string $encryptIV
+     * @param array $buffer
+     * @return string
+     * @access private
+     */
+    function _openssl_ofb_process($plaintext, &$encryptIV, &$buffer)
+    {
+        if (strlen($buffer['xor'])) {
+            $ciphertext = $plaintext ^ $buffer['xor'];
+            $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
+            $plaintext = substr($plaintext, strlen($ciphertext));
+        } else {
+            $ciphertext = '';
+        }
+
+        $block_size = $this->block_size;
+
+        $len = strlen($plaintext);
+        $key = $this->key;
+        $overflow = $len % $block_size;
+
+        if (strlen($plaintext)) {
+            if ($overflow) {
+                $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+                $xor = $this->_string_pop($ciphertext, $block_size);
+                if ($this->continuousBuffer) {
+                    $encryptIV = $xor;
+                }
+                $ciphertext.= $this->_string_shift($xor, $overflow) ^ substr($plaintext, -$overflow);
+                if ($this->continuousBuffer) {
+                    $buffer['xor'] = $xor;
+                }
+            } else {
+                $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+                if ($this->continuousBuffer) {
+                    $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size);
+                }
+            }
+        }
+
+        return $ciphertext;
+    }
+
+    /**
+     * phpseclib <-> OpenSSL Mode Mapper
+     *
+     * May need to be overwritten by classes extending this one in some cases
+     *
+     * @return int
+     * @access private
+     */
+    function _openssl_translate_mode()
+    {
+        switch ($this->mode) {
+            case CRYPT_MODE_ECB:
+                return 'ecb';
+            case CRYPT_MODE_CBC:
+                return 'cbc';
+            case CRYPT_MODE_CTR:
+                return 'ctr';
+            case CRYPT_MODE_CFB:
+                return 'cfb';
+            case CRYPT_MODE_OFB:
+                return 'ofb';
+        }
+    }
+
     /**
      * Pad "packets".
      *
@@ -1091,7 +1504,7 @@ class Crypt_Base
      * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
      * transmitted separately)
      *
-     * @see Crypt_Base::disablePadding()
+     * @see self::disablePadding()
      * @access public
      */
     function enablePadding()
@@ -1102,7 +1515,7 @@ class Crypt_Base
     /**
      * Do not pad packets.
      *
-     * @see Crypt_Base::enablePadding()
+     * @see self::enablePadding()
      * @access public
      */
     function disablePadding()
@@ -1144,10 +1557,9 @@ class Crypt_Base
      * continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),
      * however, they are also less intuitive and more likely to cause you problems.
      *
-     * Note: Could, but not must, extend by the child Crypt_* class
-     *
-     * @see Crypt_Base::disableContinuousBuffer()
+     * @see self::disableContinuousBuffer()
      * @access public
+     * @internal Could, but not must, extend by the child Crypt_* class
      */
     function enableContinuousBuffer()
     {
@@ -1156,6 +1568,8 @@ class Crypt_Base
         }
 
         $this->continuousBuffer = true;
+
+        $this->_setEngine();
     }
 
     /**
@@ -1163,10 +1577,9 @@ class Crypt_Base
      *
      * The default behavior.
      *
-     * Note: Could, but not must, extend by the child Crypt_* class
-     *
-     * @see Crypt_Base::enableContinuousBuffer()
+     * @see self::enableContinuousBuffer()
      * @access public
+     * @internal Could, but not must, extend by the child Crypt_* class
      */
     function disableContinuousBuffer()
     {
@@ -1179,16 +1592,159 @@ class Crypt_Base
 
         $this->continuousBuffer = false;
         $this->changed = true;
+
+        $this->_setEngine();
     }
 
     /**
-     * Encrypts a block
+     * Test for engine validity
+     *
+     * @see self::Crypt_Base()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        switch ($engine) {
+            case CRYPT_ENGINE_OPENSSL:
+                if ($this->mode == CRYPT_MODE_STREAM && $this->continuousBuffer) {
+                    return false;
+                }
+                $this->openssl_emulate_ctr = false;
+                $result = $this->cipher_name_openssl &&
+                          extension_loaded('openssl') &&
+                          // PHP 5.3.0 - 5.3.2 did not let you set IV's
+                          version_compare(PHP_VERSION, '5.3.3', '>=');
+                if (!$result) {
+                    return false;
+                }
+
+                // prior to PHP 5.4.0 OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING were not defined. instead of expecting an integer
+                // $options openssl_encrypt expected a boolean $raw_data.
+                if (!defined('OPENSSL_RAW_DATA')) {
+                    $this->openssl_options = true;
+                } else {
+                    $this->openssl_options = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING;
+                }
+
+                $methods = openssl_get_cipher_methods();
+                if (in_array($this->cipher_name_openssl, $methods)) {
+                    return true;
+                }
+                // not all of openssl's symmetric cipher's support ctr. for those
+                // that don't we'll emulate it
+                switch ($this->mode) {
+                    case CRYPT_MODE_CTR:
+                        if (in_array($this->cipher_name_openssl_ecb, $methods)) {
+                            $this->openssl_emulate_ctr = true;
+                            return true;
+                        }
+                }
+                return false;
+            case CRYPT_ENGINE_MCRYPT:
+                return $this->cipher_name_mcrypt &&
+                       extension_loaded('mcrypt') &&
+                       in_array($this->cipher_name_mcrypt, @mcrypt_list_algorithms());
+            case CRYPT_ENGINE_INTERNAL:
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Sets the preferred crypt engine
+     *
+     * Currently, $engine could be:
+     *
+     * - CRYPT_ENGINE_OPENSSL  [very fast]
+     *
+     * - CRYPT_ENGINE_MCRYPT   [fast]
+     *
+     * - CRYPT_ENGINE_INTERNAL [slow]
+     *
+     * If the preferred crypt engine is not available the fastest available one will be used
+     *
+     * @see self::Crypt_Base()
+     * @param int $engine
+     * @access public
+     */
+    function setPreferredEngine($engine)
+    {
+        switch ($engine) {
+            //case CRYPT_ENGINE_OPENSSL:
+            case CRYPT_ENGINE_MCRYPT:
+            case CRYPT_ENGINE_INTERNAL:
+                $this->preferredEngine = $engine;
+                break;
+            default:
+                $this->preferredEngine = CRYPT_ENGINE_OPENSSL;
+        }
+
+        $this->_setEngine();
+    }
+
+    /**
+     * Returns the engine currently being utilized
      *
-     * Note: Must extend by the child Crypt_* class
+     * @see self::_setEngine()
+     * @access public
+     */
+    function getEngine()
+    {
+        return $this->engine;
+    }
+
+    /**
+     * Sets the engine as appropriate
      *
+     * @see self::Crypt_Base()
      * @access private
-     * @param String $in
-     * @return String
+     */
+    function _setEngine()
+    {
+        $this->engine = null;
+
+        $candidateEngines = array(
+            $this->preferredEngine,
+            CRYPT_ENGINE_OPENSSL,
+            CRYPT_ENGINE_MCRYPT
+        );
+        foreach ($candidateEngines as $engine) {
+            if ($this->isValidEngine($engine)) {
+                $this->engine = $engine;
+                break;
+            }
+        }
+        if (!$this->engine) {
+            $this->engine = CRYPT_ENGINE_INTERNAL;
+        }
+
+        if ($this->engine != CRYPT_ENGINE_MCRYPT && $this->enmcrypt) {
+            // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed,
+            // (re)open them with the module named in $this->cipher_name_mcrypt
+            @mcrypt_module_close($this->enmcrypt);
+            @mcrypt_module_close($this->demcrypt);
+            $this->enmcrypt = null;
+            $this->demcrypt = null;
+
+            if ($this->ecb) {
+                @mcrypt_module_close($this->ecb);
+                $this->ecb = null;
+            }
+        }
+
+        $this->changed = true;
+    }
+
+    /**
+     * Encrypts a block
+     *
+     * @access private
+     * @param string $in
+     * @return string
+     * @internal Must be extended by the child Crypt_* class
      */
     function _encryptBlock($in)
     {
@@ -1198,11 +1754,10 @@ class Crypt_Base
     /**
      * Decrypts a block
      *
-     * Note: Must extend by the child Crypt_* class
-     *
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
+     * @internal Must be extended by the child Crypt_* class
      */
     function _decryptBlock($in)
     {
@@ -1212,12 +1767,11 @@ class Crypt_Base
     /**
      * Setup the key (expansion)
      *
-     * Only used if $engine == CRYPT_MODE_INTERNAL
-     *
-     * Note: Must extend by the child Crypt_* class
+     * Only used if $engine == CRYPT_ENGINE_INTERNAL
      *
-     * @see Crypt_Base::_setup()
+     * @see self::_setup()
      * @access private
+     * @internal Must be extended by the child Crypt_* class
      */
     function _setupKey()
     {
@@ -1225,10 +1779,10 @@ class Crypt_Base
     }
 
     /**
-     * Setup the CRYPT_MODE_INTERNAL $engine
+     * Setup the CRYPT_ENGINE_INTERNAL $engine
      *
      * (re)init, if necessary, the internal cipher $engine and flush all $buffers
-     * Used (only) if $engine == CRYPT_MODE_INTERNAL
+     * Used (only) if $engine == CRYPT_ENGINE_INTERNAL
      *
      * _setup() will be called each time if $changed === true
      * typically this happens when using one or more of following public methods:
@@ -1241,14 +1795,12 @@ class Crypt_Base
      *
      * - First run of encrypt() / decrypt() with no init-settings
      *
-     * Internally: _setup() is called always before(!) en/decryption.
-     *
-     * Note: Could, but not must, extend by the child Crypt_* class
-     *
-     * @see setKey()
-     * @see setIV()
-     * @see disableContinuousBuffer()
+     * @see self::setKey()
+     * @see self::setIV()
+     * @see self::disableContinuousBuffer()
      * @access private
+     * @internal _setup() is always called before en/decryption.
+     * @internal Could, but not must, extend by the child Crypt_* class
      */
     function _setup()
     {
@@ -1261,10 +1813,10 @@ class Crypt_Base
     }
 
     /**
-     * Setup the CRYPT_MODE_MCRYPT $engine
+     * Setup the CRYPT_ENGINE_MCRYPT $engine
      *
      * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers
-     * Used (only) if $engine = CRYPT_MODE_MCRYPT
+     * Used (only) if $engine = CRYPT_ENGINE_MCRYPT
      *
      * _setupMcrypt() will be called each time if $changed === true
      * typically this happens when using one or more of following public methods:
@@ -1277,13 +1829,11 @@ class Crypt_Base
      *
      * - First run of encrypt() / decrypt()
      *
-     *
-     * Note: Could, but not must, extend by the child Crypt_* class
-     *
-     * @see setKey()
-     * @see setIV()
-     * @see disableContinuousBuffer()
+     * @see self::setKey()
+     * @see self::setIV()
+     * @see self::disableContinuousBuffer()
      * @access private
+     * @internal Could, but not must, extend by the child Crypt_* class
      */
     function _setupMcrypt()
     {
@@ -1300,20 +1850,19 @@ class Crypt_Base
                 CRYPT_MODE_STREAM => MCRYPT_MODE_STREAM,
             );
 
-            $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
-            $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
+            $this->demcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
+            $this->enmcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
 
             // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer()
             // to workaround mcrypt's broken ncfb implementation in buffered mode
             // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
             if ($this->mode == CRYPT_MODE_CFB) {
-                $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
+                $this->ecb = @mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
             }
-
         } // else should mcrypt_generic_deinit be called?
 
         if ($this->mode == CRYPT_MODE_CFB) {
-            mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
+            @mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
         }
     }
 
@@ -1327,10 +1876,10 @@ class Crypt_Base
      * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
      * and padding will, hence forth, be enabled.
      *
-     * @see Crypt_Base::_unpad()
-     * @param String $text
+     * @see self::_unpad()
+     * @param string $text
      * @access private
-     * @return String
+     * @return string
      */
     function _pad($text)
     {
@@ -1356,10 +1905,10 @@ class Crypt_Base
      * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
      * and false will be returned.
      *
-     * @see Crypt_Base::_pad()
-     * @param String $text
+     * @see self::_pad()
+     * @param string $text
      * @access private
-     * @return String
+     * @return string
      */
     function _unpad($text)
     {
@@ -1383,18 +1932,20 @@ class Crypt_Base
      * after disableContinuousBuffer() or on cipher $engine (re)init
      * ie after setKey() or setIV()
      *
-     * Note: Could, but not must, extend by the child Crypt_* class
-     *
      * @access public
+     * @internal Could, but not must, extend by the child Crypt_* class
      */
     function _clearBuffers()
     {
-        $this->enbuffer = array('encrypted'  => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
-        $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
+        $this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
 
         // mcrypt's handling of invalid's $iv:
         // $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
         $this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
+
+        if (!$this->skip_key_adjustment) {
+            $this->key = str_pad(substr($this->key, 0, $this->key_length), $this->key_length, "\0");
+        }
     }
 
     /**
@@ -1402,12 +1953,12 @@ class Crypt_Base
      *
      * Inspired by array_shift
      *
-     * @param String $string
-     * @param optional Integer $index
+     * @param string $string
+     * @param int $index
      * @access private
-     * @return String
+     * @return string
      */
-    function _stringShift(&$string, $index = 1)
+    function _string_shift(&$string, $index = 1)
     {
         $substr = substr($string, 0, $index);
         $string = substr($string, $index);
@@ -1415,43 +1966,57 @@ class Crypt_Base
     }
 
     /**
-     * Generate CTR XOR encryption key
+     * String Pop
      *
-     * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
-     * plaintext / ciphertext in CTR mode.
+     * Inspired by array_pop
      *
-     * @see Crypt_Base::decrypt()
-     * @see Crypt_Base::encrypt()
-     * @param String $iv
-     * @param Integer $length
+     * @param string $string
+     * @param int $index
      * @access private
-     * @return String $xor
+     * @return string
      */
-    function _generateXor(&$iv, $length)
+    function _string_pop(&$string, $index = 1)
     {
-        $xor = '';
-        $block_size = $this->block_size;
-        $num_blocks = floor(($length + ($block_size - 1)) / $block_size);
-        for ($i = 0; $i < $num_blocks; $i++) {
-            $xor.= $iv;
-            for ($j = 4; $j <= $block_size; $j+= 4) {
-                $temp = substr($iv, -$j, 4);
-                switch ($temp) {
-                    case "\xFF\xFF\xFF\xFF":
-                        $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
-                        break;
-                    case "\x7F\xFF\xFF\xFF":
-                        $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
-                        break 2;
-                    default:
-                        extract(unpack('Ncount', $temp));
-                        $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
-                        break 2;
-                }
+        $substr = substr($string, -$index);
+        $string = substr($string, 0, -$index);
+        return $substr;
+    }
+
+    /**
+     * Increment the current string
+     *
+     * @see self::decrypt()
+     * @see self::encrypt()
+     * @param string $var
+     * @access private
+     */
+    function _increment_str(&$var)
+    {
+        for ($i = 4; $i <= strlen($var); $i+= 4) {
+            $temp = substr($var, -$i, 4);
+            switch ($temp) {
+                case "\xFF\xFF\xFF\xFF":
+                    $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4);
+                    break;
+                case "\x7F\xFF\xFF\xFF":
+                    $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4);
+                    return;
+                default:
+                    $temp = unpack('Nnum', $temp);
+                    $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4);
+                    return;
             }
         }
 
-        return $xor;
+        $remainder = strlen($var) % 4;
+
+        if ($remainder == 0) {
+            return;
+        }
+
+        $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT));
+        $temp = substr(pack('N', $temp['num'] + 1), -$remainder);
+        $var = substr_replace($var, $temp, 0, $remainder);
     }
 
     /**
@@ -1464,7 +2029,7 @@ class Crypt_Base
      *
      *     _setupInlineCrypt() would be called only if:
      *
-     *     - $engine == CRYPT_MODE_INTERNAL and
+     *     - $engine == CRYPT_ENGINE_INTERNAL and
      *
      *     - $use_inline_crypt === true
      *
@@ -1507,16 +2072,15 @@ class Crypt_Base
      *       - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only
      *
      *
-     * @see Crypt_Base::_setup()
-     * @see Crypt_Base::_createInlineCryptFunction()
-     * @see Crypt_Base::encrypt()
-     * @see Crypt_Base::decrypt()
+     * @see self::_setup()
+     * @see self::_createInlineCryptFunction()
+     * @see self::encrypt()
+     * @see self::decrypt()
      * @access private
+     * @internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()
      */
     function _setupInlineCrypt()
     {
-        // If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()
-
         // If, for any reason, an extending Crypt_Base() Crypt_* class
         // not using inline crypting then it must be ensured that: $this->use_inline_crypt = false
         // ie in the class var declaration of $use_inline_crypt in general for the Crypt_* class,
@@ -1630,12 +2194,12 @@ class Crypt_Base
      *    );
      *    </code>
      *
-     * @see Crypt_Base::_setupInlineCrypt()
-     * @see Crypt_Base::encrypt()
-     * @see Crypt_Base::decrypt()
-     * @param Array $cipher_code
+     * @see self::_setupInlineCrypt()
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @param array $cipher_code
      * @access private
-     * @return String (the name of the created callback function)
+     * @return string (the name of the created callback function)
      */
     function _createInlineCryptFunction($cipher_code)
     {
@@ -1656,7 +2220,6 @@ class Crypt_Base
             case CRYPT_MODE_ECB:
                 $encrypt = $init_encrypt . '
                     $_ciphertext = "";
-                    $_text = $self->_pad($_text);
                     $_plaintext_len = strlen($_text);
 
                     for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
@@ -1688,23 +2251,24 @@ class Crypt_Base
                     $_plaintext_len = strlen($_text);
                     $_xor = $self->encryptIV;
                     $_buffer = &$self->enbuffer;
-
-                    if (strlen($_buffer["encrypted"])) {
+                    if (strlen($_buffer["ciphertext"])) {
                         for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
                             $_block = substr($_text, $_i, '.$block_size.');
-                            if (strlen($_block) > strlen($_buffer["encrypted"])) {
-                                $in = $self->_generateXor($_xor, '.$block_size.');
+                            if (strlen($_block) > strlen($_buffer["ciphertext"])) {
+                                $in = $_xor;
                                 '.$encrypt_block.'
-                                $_buffer["encrypted"].= $in;
+                                $self->_increment_str($_xor);
+                                $_buffer["ciphertext"].= $in;
                             }
-                            $_key = $self->_stringShift($_buffer["encrypted"], '.$block_size.');
+                            $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
                             $_ciphertext.= $_block ^ $_key;
                         }
                     } else {
                         for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
                             $_block = substr($_text, $_i, '.$block_size.');
-                            $in = $self->_generateXor($_xor, '.$block_size.');
+                            $in = $_xor;
                             '.$encrypt_block.'
+                            $self->_increment_str($_xor);
                             $_key = $in;
                             $_ciphertext.= $_block ^ $_key;
                         }
@@ -1712,7 +2276,7 @@ class Crypt_Base
                     if ($self->continuousBuffer) {
                         $self->encryptIV = $_xor;
                         if ($_start = $_plaintext_len % '.$block_size.') {
-                            $_buffer["encrypted"] = substr($_key, $_start) . $_buffer["encrypted"];
+                            $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
                         }
                     }
 
@@ -1729,18 +2293,20 @@ class Crypt_Base
                         for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
                             $_block = substr($_text, $_i, '.$block_size.');
                             if (strlen($_block) > strlen($_buffer["ciphertext"])) {
-                                $in = $self->_generateXor($_xor, '.$block_size.');
+                                $in = $_xor;
                                 '.$encrypt_block.'
+                                $self->_increment_str($_xor);
                                 $_buffer["ciphertext"].= $in;
                             }
-                            $_key = $self->_stringShift($_buffer["ciphertext"], '.$block_size.');
+                            $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
                             $_plaintext.= $_block ^ $_key;
                         }
                     } else {
                         for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
                             $_block = substr($_text, $_i, '.$block_size.');
-                            $in = $self->_generateXor($_xor, '.$block_size.');
+                            $in = $_xor;
                             '.$encrypt_block.'
+                            $self->_increment_str($_xor);
                             $_key = $in;
                             $_plaintext.= $_block ^ $_key;
                         }
@@ -1870,7 +2436,7 @@ class Crypt_Base
                                 $_xor = $in;
                                 $_buffer["xor"].= $_xor;
                             }
-                            $_key = $self->_stringShift($_buffer["xor"], '.$block_size.');
+                            $_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
                             $_ciphertext.= $_block ^ $_key;
                         }
                     } else {
@@ -1906,7 +2472,7 @@ class Crypt_Base
                                 $_xor = $in;
                                 $_buffer["xor"].= $_xor;
                             }
-                            $_key = $self->_stringShift($_buffer["xor"], '.$block_size.');
+                            $_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
                             $_plaintext.= $_block ^ $_key;
                         }
                     } else {
@@ -1943,7 +2509,6 @@ class Crypt_Base
             default:
                 $encrypt = $init_encrypt . '
                     $_ciphertext = "";
-                    $_text = $self->_pad($_text);
                     $_plaintext_len = strlen($_text);
 
                     $in = $self->encryptIV;
@@ -1996,16 +2561,51 @@ class Crypt_Base
      * is stored, classwide (!), here for reusing.
      *
      * The string-based index of $function is a classwide
-     * uniqe value representing, at least, the $mode of
+     * unique value representing, at least, the $mode of
      * operation (or more... depends of the optimizing level)
      * for which $mode the lambda function was created.
      *
      * @access private
-     * @return &Array
+     * @return array &$functions
      */
     function &_getLambdaFunctions()
     {
         static $functions = array();
         return $functions;
     }
+
+    /**
+     * Generates a digest from $bytes
+     *
+     * @see self::_setupInlineCrypt()
+     * @access private
+     * @param $bytes
+     * @return string
+     */
+    function _hashInlineCryptFunction($bytes)
+    {
+        if (!defined('CRYPT_BASE_WHIRLPOOL_AVAILABLE')) {
+            define('CRYPT_BASE_WHIRLPOOL_AVAILABLE', (bool)(extension_loaded('hash') && in_array('whirlpool', hash_algos())));
+        }
+
+        $result = '';
+        $hash = $bytes;
+
+        switch (true) {
+            case CRYPT_BASE_WHIRLPOOL_AVAILABLE:
+                foreach (str_split($bytes, 64) as $t) {
+                    $hash = hash('whirlpool', $hash, true);
+                    $result .= $t ^ $hash;
+                }
+                return $result . hash('whirlpool', $hash, true);
+            default:
+                $len = strlen($bytes);
+                for ($i = 0; $i < $len; $i+=20) {
+                    $t = substr($bytes, $i, 20);
+                    $hash = pack('H*', sha1($hash));
+                    $result .= $t ^ $hash;
+                }
+                return $result . pack('H*', sha1($hash));
+        }
+    }
 }
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
index f39f17d747b6af1e7df4d0c5d37d2c2a2f1ac9ab..e610209b00151e785dd367a4ea4028c0584af5c2 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
@@ -64,8 +64,8 @@ if (!class_exists('Crypt_Base')) {
 
 /**#@+
  * @access public
- * @see Crypt_Blowfish::encrypt()
- * @see Crypt_Blowfish::decrypt()
+ * @see self::encrypt()
+ * @see self::decrypt()
  */
 /**
  * Encrypt / decrypt using the Counter mode.
@@ -101,20 +101,6 @@ define('CRYPT_BLOWFISH_MODE_CFB', CRYPT_MODE_CFB);
 define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB);
 /**#@-*/
 
-/**#@+
- * @access private
- * @see Crypt_Base::Crypt_Base()
- */
-/**
- * Toggles the internal implementation
- */
-define('CRYPT_BLOWFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
-/**
- * Toggles the mcrypt implementation
- */
-define('CRYPT_BLOWFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
-/**#@-*/
-
 /**
  * Pure-PHP implementation of Blowfish.
  *
@@ -129,26 +115,16 @@ class Crypt_Blowfish extends Crypt_Base
      * Block Length of the cipher
      *
      * @see Crypt_Base::block_size
-     * @var Integer
+     * @var int
      * @access private
      */
     var $block_size = 8;
 
-    /**
-     * The default password key_size used by setPassword()
-     *
-     * @see Crypt_Base::password_key_size
-     * @see Crypt_Base::setPassword()
-     * @var Integer
-     * @access private
-     */
-    var $password_key_size = 56;
-
     /**
      * The namespace used by the cipher for its constants.
      *
      * @see Crypt_Base::const_namespace
-     * @var String
+     * @var string
      * @access private
      */
     var $const_namespace = 'BLOWFISH';
@@ -157,7 +133,7 @@ class Crypt_Blowfish extends Crypt_Base
      * The mcrypt specific name of the cipher
      *
      * @see Crypt_Base::cipher_name_mcrypt
-     * @var String
+     * @var string
      * @access private
      */
     var $cipher_name_mcrypt = 'blowfish';
@@ -166,7 +142,7 @@ class Crypt_Blowfish extends Crypt_Base
      * Optimizing value while CFB-encrypting
      *
      * @see Crypt_Base::cfb_init_len
-     * @var Integer
+     * @var int
      * @access private
      */
     var $cfb_init_len = 500;
@@ -174,12 +150,12 @@ class Crypt_Blowfish extends Crypt_Base
     /**
      * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
      *
-     * S-Box 1
+     * S-Box 0
      *
      * @access private
      * @var    array
      */
-    var $sbox0 = array (
+    var $sbox0 = array(
         0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
         0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
         0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
@@ -340,7 +316,7 @@ class Crypt_Blowfish extends Crypt_Base
     /**
      * P-Array consists of 18 32-bit subkeys
      *
-     * @var array $parray
+     * @var array
      * @access private
      */
     var $parray = array(
@@ -354,7 +330,7 @@ class Crypt_Blowfish extends Crypt_Base
      *
      * Holds the expanded key [p] and the key-depended s-boxes [sb]
      *
-     * @var array $bctx
+     * @var array
      * @access private
      */
     var $bctx;
@@ -362,37 +338,66 @@ class Crypt_Blowfish extends Crypt_Base
     /**
      * Holds the last used key
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $kl;
 
     /**
-     * Sets the key.
-     *
-     * Keys can be of any length.  Blowfish, itself, requires the use of a key between 32 and max. 448-bits long.
-     * If the key is less than 32-bits we NOT fill the key to 32bit but let the key as it is to be compatible
-     * with mcrypt because mcrypt act this way with blowfish key's < 32 bits.
+     * The Key Length (in bytes)
      *
-     * If the key is more than 448-bits, we trim the excess bits.
+     * @see Crypt_Base::setKeyLength()
+     * @var int
+     * @access private
+     * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16.  Exists in conjunction with $Nk
+     *    because the encryption / decryption / key schedule creation requires this number and not $key_length.  We could
+     *    derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
+     *    of that, we'll just precompute it once.
+     */
+    var $key_length = 16;
+
+    /**
+     * Sets the key length.
      *
-     * If the key is not explicitly set, or empty, it'll be assumed a 128 bits key to be all null bytes.
+     * Key lengths can be between 32 and 448 bits.
      *
      * @access public
-     * @see Crypt_Base::setKey()
-     * @param String $key
+     * @param int $length
      */
-    function setKey($key)
+    function setKeyLength($length)
     {
-        $keylength = strlen($key);
+        if ($length < 32) {
+            $this->key_length = 7;
+        } elseif ($length > 448) {
+            $this->key_length = 56;
+        } else {
+            $this->key_length = $length >> 3;
+        }
 
-        if (!$keylength) {
-            $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-        } elseif ($keylength > 56) {
-            $key = substr($key, 0, 56);
+        parent::setKeyLength($length);
+    }
+
+    /**
+     * Test for engine validity
+     *
+     * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
+     *
+     * @see Crypt_Base::isValidEngine()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        if ($engine == CRYPT_ENGINE_OPENSSL) {
+            if ($this->key_length != 16) {
+                return false;
+            }
+            $this->cipher_name_openssl_ecb = 'bf-ecb';
+            $this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode();
         }
 
-        parent::setKey($key);
+        return parent::isValidEngine($engine);
     }
 
     /**
@@ -455,8 +460,8 @@ class Crypt_Blowfish extends Crypt_Base
      * Encrypts a block
      *
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
      */
     function _encryptBlock($in)
     {
@@ -472,17 +477,15 @@ class Crypt_Blowfish extends Crypt_Base
         $r = $in[2];
 
         for ($i = 0; $i < 16; $i+= 2) {
-                $l^= $p[$i];
-                $r^= ($sb_0[$l >> 24 & 0xff]  +
-                      $sb_1[$l >> 16 & 0xff]  ^
-                      $sb_2[$l >>  8 & 0xff]) +
-                      $sb_3[$l       & 0xff];
-
-                $r^= $p[$i + 1];
-                $l^= ($sb_0[$r >> 24 & 0xff]  +
-                      $sb_1[$r >> 16 & 0xff]  ^
-                      $sb_2[$r >>  8 & 0xff]) +
-                      $sb_3[$r       & 0xff];
+            $l^= $p[$i];
+            $r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff]  + $sb_1[$l >> 16 & 0xff]) ^
+                  $sb_2[$l >>  8 & 0xff]) +
+                  $sb_3[$l       & 0xff]);
+
+            $r^= $p[$i + 1];
+            $l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff]  + $sb_1[$r >> 16 & 0xff]) ^
+                  $sb_2[$r >>  8 & 0xff]) +
+                  $sb_3[$r       & 0xff]);
         }
         return pack("N*", $r ^ $p[17], $l ^ $p[16]);
     }
@@ -491,8 +494,8 @@ class Crypt_Blowfish extends Crypt_Base
      * Decrypts a block
      *
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
      */
     function _decryptBlock($in)
     {
@@ -508,18 +511,15 @@ class Crypt_Blowfish extends Crypt_Base
 
         for ($i = 17; $i > 2; $i-= 2) {
             $l^= $p[$i];
-            $r^= ($sb_0[$l >> 24 & 0xff]  +
-                  $sb_1[$l >> 16 & 0xff]  ^
+            $r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
                   $sb_2[$l >>  8 & 0xff]) +
-                  $sb_3[$l       & 0xff];
+                  $sb_3[$l       & 0xff]);
 
             $r^= $p[$i - 1];
-            $l^= ($sb_0[$r >> 24 & 0xff]  +
-                  $sb_1[$r >> 16 & 0xff]  ^
+            $l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
                   $sb_2[$r >>  8 & 0xff]) +
-                  $sb_3[$r       & 0xff];
+                  $sb_3[$r       & 0xff]);
         }
-
         return pack("N*", $r ^ $p[0], $l ^ $p[1]);
     }
 
@@ -534,15 +534,26 @@ class Crypt_Blowfish extends Crypt_Base
         $lambda_functions =& Crypt_Blowfish::_getLambdaFunctions();
 
         // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
+        // (Currently, for Crypt_Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
         // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
-        $gen_hi_opt_code = (bool)( count($lambda_functions) < 10);
+        $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
 
+        // Generation of a unique hash for our generated code
+        $code_hash = "Crypt_Blowfish, {$this->mode}";
+        if ($gen_hi_opt_code) {
+            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+        }
+
+        // on 32-bit linux systems with PHP < 5.3 float to integer conversion is bad
         switch (true) {
-            case $gen_hi_opt_code:
-                $code_hash = md5(str_pad("Crypt_Blowfish, {$this->mode}, ", 32, "\0") . $this->key);
+            case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8:
+            case version_compare(PHP_VERSION, '5.3.0') >= 0:
+            case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
+                $safeint = '%s';
                 break;
             default:
-                $code_hash = "Crypt_Blowfish, {$this->mode}";
+                $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
+                $safeint.= '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
         }
 
         if (!isset($lambda_functions[$code_hash])) {
@@ -580,16 +591,14 @@ class Crypt_Blowfish extends Crypt_Base
             for ($i = 0; $i < 16; $i+= 2) {
                 $encrypt_block.= '
                     $l^= ' . $p[$i] . ';
-                    $r^= ($sb_0[$l >> 24 & 0xff]  +
-                          $sb_1[$l >> 16 & 0xff]  ^
+                    $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
                           $sb_2[$l >>  8 & 0xff]) +
-                          $sb_3[$l       & 0xff];
+                          $sb_3[$l       & 0xff]') . ';
 
                     $r^= ' . $p[$i + 1] . ';
-                    $l^= ($sb_0[$r >> 24 & 0xff]  +
-                          $sb_1[$r >> 16 & 0xff]  ^
+                    $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . '  ^
                           $sb_2[$r >>  8 & 0xff]) +
-                          $sb_3[$r       & 0xff];
+                          $sb_3[$r       & 0xff]') . ';
                 ';
             }
             $encrypt_block.= '
@@ -609,16 +618,14 @@ class Crypt_Blowfish extends Crypt_Base
             for ($i = 17; $i > 2; $i-= 2) {
                 $decrypt_block.= '
                     $l^= ' . $p[$i] . ';
-                    $r^= ($sb_0[$l >> 24 & 0xff]  +
-                          $sb_1[$l >> 16 & 0xff]  ^
+                    $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
                           $sb_2[$l >>  8 & 0xff]) +
-                          $sb_3[$l       & 0xff];
+                          $sb_3[$l       & 0xff]') . ';
 
                     $r^= ' . $p[$i - 1] . ';
-                    $l^= ($sb_0[$r >> 24 & 0xff]  +
-                          $sb_1[$r >> 16 & 0xff]  ^
+                    $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
                           $sb_2[$r >>  8 & 0xff]) +
-                          $sb_3[$r       & 0xff];
+                          $sb_3[$r       & 0xff]') . ';
                 ';
             }
 
@@ -641,4 +648,24 @@ class Crypt_Blowfish extends Crypt_Base
         }
         $this->inline_crypt = $lambda_functions[$code_hash];
     }
+
+    /**
+     * Convert float to int
+     *
+     * On 32-bit Linux installs running PHP < 5.3 converting floats to ints doesn't always work
+     *
+     * @access private
+     * @param string $x
+     * @return int
+     */
+    function safe_intval($x)
+    {
+        // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
+        // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
+        if (is_int($x) || version_compare(PHP_VERSION, '5.3.0') >= 0 || (PHP_OS & "\xDF\xDF\xDF") === 'WIN') {
+            return $x;
+        }
+        return (fmod($x, 0x80000000) & 0x7FFFFFFF) |
+            ((fmod(floor($x / 0x80000000), 2) & 1) << 31);
+    }
 }
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
index f92f30b2d8413f00122e75d9c38807949d8640d2..4c57401871099302a58f568f86756d36edb0a069 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
@@ -69,8 +69,8 @@ if (!class_exists('Crypt_Base')) {
 
 /**#@+
  * @access private
- * @see Crypt_DES::_setupKey()
- * @see Crypt_DES::_processBlock()
+ * @see self::_setupKey()
+ * @see self::_processBlock()
  */
 /**
  * Contains $keys[CRYPT_DES_ENCRYPT]
@@ -84,8 +84,8 @@ define('CRYPT_DES_DECRYPT', 1);
 
 /**#@+
  * @access public
- * @see Crypt_DES::encrypt()
- * @see Crypt_DES::decrypt()
+ * @see self::encrypt()
+ * @see self::decrypt()
  */
 /**
  * Encrypt / decrypt using the Counter mode.
@@ -121,20 +121,6 @@ define('CRYPT_DES_MODE_CFB', CRYPT_MODE_CFB);
 define('CRYPT_DES_MODE_OFB', CRYPT_MODE_OFB);
 /**#@-*/
 
-/**#@+
- * @access private
- * @see Crypt_Base::Crypt_Base()
- */
-/**
- * Toggles the internal implementation
- */
-define('CRYPT_DES_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
-/**
- * Toggles the mcrypt implementation
- */
-define('CRYPT_DES_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
-/**#@-*/
-
 /**
  * Pure-PHP implementation of DES.
  *
@@ -148,36 +134,25 @@ class Crypt_DES extends Crypt_Base
      * Block Length of the cipher
      *
      * @see Crypt_Base::block_size
-     * @var Integer
+     * @var int
      * @access private
      */
     var $block_size = 8;
 
     /**
-     * The Key
+     * Key Length (in bytes)
      *
-     * @see Crypt_Base::key
-     * @see setKey()
-     * @var String
+     * @see Crypt_Base::setKeyLength()
+     * @var int
      * @access private
      */
-    var $key = "\0\0\0\0\0\0\0\0";
-
-    /**
-     * The default password key_size used by setPassword()
-     *
-     * @see Crypt_Base::password_key_size
-     * @see Crypt_Base::setPassword()
-     * @var Integer
-     * @access private
-     */
-    var $password_key_size = 8;
+    var $key_length = 8;
 
     /**
      * The namespace used by the cipher for its constants.
      *
      * @see Crypt_Base::const_namespace
-     * @var String
+     * @var string
      * @access private
      */
     var $const_namespace = 'DES';
@@ -186,16 +161,31 @@ class Crypt_DES extends Crypt_Base
      * The mcrypt specific name of the cipher
      *
      * @see Crypt_Base::cipher_name_mcrypt
-     * @var String
+     * @var string
      * @access private
      */
     var $cipher_name_mcrypt = 'des';
 
+    /**
+     * The OpenSSL names of the cipher / modes
+     *
+     * @see Crypt_Base::openssl_mode_names
+     * @var array
+     * @access private
+     */
+    var $openssl_mode_names = array(
+        CRYPT_MODE_ECB => 'des-ecb',
+        CRYPT_MODE_CBC => 'des-cbc',
+        CRYPT_MODE_CFB => 'des-cfb',
+        CRYPT_MODE_OFB => 'des-ofb'
+        // CRYPT_MODE_CTR is undefined for DES
+    );
+
     /**
      * Optimizing value while CFB-encrypting
      *
      * @see Crypt_Base::cfb_init_len
-     * @var Integer
+     * @var int
      * @access private
      */
     var $cfb_init_len = 500;
@@ -205,9 +195,9 @@ class Crypt_DES extends Crypt_Base
      *
      * Used only if $engine == CRYPT_DES_MODE_INTERNAL
      *
-     * @see Crypt_DES::_setupKey()
-     * @see Crypt_DES::_processBlock()
-     * @var Integer
+     * @see self::_setupKey()
+     * @see self::_processBlock()
+     * @var int
      * @access private
      */
     var $des_rounds = 1;
@@ -215,17 +205,17 @@ class Crypt_DES extends Crypt_Base
     /**
      * max possible size of $key
      *
-     * @see Crypt_DES::setKey()
-     * @var String
+     * @see self::setKey()
+     * @var string
      * @access private
      */
-    var $key_size_max = 8;
+    var $key_length_max = 8;
 
     /**
      * The Key Schedule
      *
-     * @see Crypt_DES::_setupKey()
-     * @var Array
+     * @see self::_setupKey()
+     * @var array
      * @access private
      */
     var $keys;
@@ -237,9 +227,9 @@ class Crypt_DES extends Crypt_Base
      * with each byte containing all bits in the same state as the
      * corresponding bit in the index value.
      *
-     * @see Crypt_DES::_processBlock()
-     * @see Crypt_DES::_setupKey()
-     * @var Array
+     * @see self::_processBlock()
+     * @see self::_setupKey()
+     * @var array
      * @access private
      */
     var $shuffle = array(
@@ -378,7 +368,7 @@ class Crypt_DES extends Crypt_Base
      *
      * Indexing this table with each source byte performs the initial bit permutation.
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $ipmap = array(
@@ -420,7 +410,7 @@ class Crypt_DES extends Crypt_Base
      * Inverse IP mapping helper table.
      * Indexing this table with a byte value reverses the bit order.
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $invipmap = array(
@@ -464,7 +454,7 @@ class Crypt_DES extends Crypt_Base
      * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
      * P table: concatenation can then be replaced by exclusive ORs.
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $sbox1 = array(
@@ -489,7 +479,7 @@ class Crypt_DES extends Crypt_Base
     /**
      * Pre-permuted S-box2
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $sbox2 = array(
@@ -514,7 +504,7 @@ class Crypt_DES extends Crypt_Base
     /**
      * Pre-permuted S-box3
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $sbox3 = array(
@@ -539,7 +529,7 @@ class Crypt_DES extends Crypt_Base
     /**
      * Pre-permuted S-box4
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $sbox4 = array(
@@ -564,7 +554,7 @@ class Crypt_DES extends Crypt_Base
     /**
      * Pre-permuted S-box5
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $sbox5 = array(
@@ -589,7 +579,7 @@ class Crypt_DES extends Crypt_Base
     /**
      * Pre-permuted S-box6
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $sbox6 = array(
@@ -614,7 +604,7 @@ class Crypt_DES extends Crypt_Base
     /**
      * Pre-permuted S-box7
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $sbox7 = array(
@@ -639,7 +629,7 @@ class Crypt_DES extends Crypt_Base
     /**
      * Pre-permuted S-box8
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $sbox8 = array(
@@ -661,6 +651,28 @@ class Crypt_DES extends Crypt_Base
         0x00000820, 0x00020020, 0x08000000, 0x08020800
     );
 
+    /**
+     * Test for engine validity
+     *
+     * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
+     *
+     * @see Crypt_Base::isValidEngine()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        if ($this->key_length_max == 8) {
+            if ($engine == CRYPT_ENGINE_OPENSSL) {
+                $this->cipher_name_openssl_ecb = 'des-ecb';
+                $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
+            }
+        }
+
+        return parent::isValidEngine($engine);
+    }
+
     /**
      * Sets the key.
      *
@@ -674,14 +686,14 @@ class Crypt_DES extends Crypt_Base
      *
      * @see Crypt_Base::setKey()
      * @access public
-     * @param String $key
+     * @param string $key
      */
     function setKey($key)
     {
         // We check/cut here only up to max length of the key.
         // Key padding to the proper length will be done in _setupKey()
-        if (strlen($key) > $this->key_size_max) {
-            $key = substr($key, 0, $this->key_size_max);
+        if (strlen($key) > $this->key_length_max) {
+            $key = substr($key, 0, $this->key_length_max);
         }
 
         // Sets the key
@@ -693,10 +705,10 @@ class Crypt_DES extends Crypt_Base
      *
      * @see Crypt_Base::_encryptBlock()
      * @see Crypt_Base::encrypt()
-     * @see Crypt_DES::encrypt()
+     * @see self::encrypt()
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
      */
     function _encryptBlock($in)
     {
@@ -708,10 +720,10 @@ class Crypt_DES extends Crypt_Base
      *
      * @see Crypt_Base::_decryptBlock()
      * @see Crypt_Base::decrypt()
-     * @see Crypt_DES::decrypt()
+     * @see self::decrypt()
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
      */
     function _decryptBlock($in)
     {
@@ -725,12 +737,12 @@ class Crypt_DES extends Crypt_Base
      * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
      * idea of what this function does.
      *
-     * @see Crypt_DES::_encryptBlock()
-     * @see Crypt_DES::_decryptBlock()
+     * @see self::_encryptBlock()
+     * @see self::_decryptBlock()
      * @access private
-     * @param String $block
-     * @param Integer $mode
-     * @return String
+     * @param string $block
+     * @param int $mode
+     * @return string
      */
     function _processBlock($block, $mode)
     {
@@ -1358,21 +1370,20 @@ class Crypt_DES extends Crypt_Base
         $des_rounds = $this->des_rounds;
 
         // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
+        // (Currently, for Crypt_DES,       one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
+        // (Currently, for Crypt_TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
         // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
         $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
 
-        // Generation of a uniqe hash for our generated code
-        switch (true) {
-            case $gen_hi_opt_code:
-                // For hi-optimized code, we create for each combination of
-                // $mode, $des_rounds and $this->key its own encrypt/decrypt function.
-                $code_hash = md5(str_pad("Crypt_DES, $des_rounds, {$this->mode}, ", 32, "\0") . $this->key);
-                break;
-            default:
-                // After max 10 hi-optimized functions, we create generic
-                // (still very fast.. but not ultra) functions for each $mode/$des_rounds
-                // Currently 2 * 5 generic functions will be then max. possible.
-                $code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
+        // Generation of a unique hash for our generated code
+        $code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
+        if ($gen_hi_opt_code) {
+            // For hi-optimized code, we create for each combination of
+            // $mode, $des_rounds and $this->key its own encrypt/decrypt function.
+            // After max 10 hi-optimized functions, we create generic
+            // (still very fast.. but not ultra) functions for each $mode/$des_rounds
+            // Currently 2 * 5 generic functions will be then max. possible.
+            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
         }
 
         // Is there a re-usable $lambda_functions in there? If not, we have to create it.
@@ -1427,7 +1438,6 @@ class Crypt_DES extends Crypt_Base
             // Creating code for en- and decryption.
             $crypt_block = array();
             foreach (array(CRYPT_DES_ENCRYPT, CRYPT_DES_DECRYPT) as $c) {
-
                 /* Do the initial IP permutation. */
                 $crypt_block[$c] = '
                     $in = unpack("N*", $in);
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
index 4ab75b2dbd4f66e2d6fcbe6a93a44674ff549ea1..ca421ace2311fb863d5bb10c4dd8bc355da3adc1 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
@@ -7,7 +7,7 @@
  *
  * md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
  *
- * If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
+ * If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to
  * the hash.  If no valid algorithm is provided, sha1 will be used.
  *
  * PHP versions 4 and 5
@@ -56,7 +56,7 @@
 
 /**#@+
  * @access private
- * @see Crypt_Hash::Crypt_Hash()
+ * @see self::Crypt_Hash()
  */
 /**
  * Toggles the internal implementation
@@ -84,8 +84,8 @@ class Crypt_Hash
     /**
      * Hash Parameter
      *
-     * @see Crypt_Hash::setHash()
-     * @var Integer
+     * @see self::setHash()
+     * @var int
      * @access private
      */
     var $hashParam;
@@ -93,8 +93,8 @@ class Crypt_Hash
     /**
      * Byte-length of compression blocks / key (Internal HMAC)
      *
-     * @see Crypt_Hash::setAlgorithm()
-     * @var Integer
+     * @see self::setAlgorithm()
+     * @var int
      * @access private
      */
     var $b;
@@ -102,8 +102,8 @@ class Crypt_Hash
     /**
      * Byte-length of hash output (Internal HMAC)
      *
-     * @see Crypt_Hash::setHash()
-     * @var Integer
+     * @see self::setHash()
+     * @var int
      * @access private
      */
     var $l = false;
@@ -111,8 +111,8 @@ class Crypt_Hash
     /**
      * Hash Algorithm
      *
-     * @see Crypt_Hash::setHash()
-     * @var String
+     * @see self::setHash()
+     * @var string
      * @access private
      */
     var $hash;
@@ -120,8 +120,8 @@ class Crypt_Hash
     /**
      * Key
      *
-     * @see Crypt_Hash::setKey()
-     * @var String
+     * @see self::setKey()
+     * @var string
      * @access private
      */
     var $key = false;
@@ -129,8 +129,8 @@ class Crypt_Hash
     /**
      * Outer XOR (Internal HMAC)
      *
-     * @see Crypt_Hash::setKey()
-     * @var String
+     * @see self::setKey()
+     * @var string
      * @access private
      */
     var $opad;
@@ -138,8 +138,8 @@ class Crypt_Hash
     /**
      * Inner XOR (Internal HMAC)
      *
-     * @see Crypt_Hash::setKey()
-     * @var String
+     * @see self::setKey()
+     * @var string
      * @access private
      */
     var $ipad;
@@ -147,13 +147,13 @@ class Crypt_Hash
     /**
      * Default Constructor.
      *
-     * @param optional String $hash
+     * @param string $hash
      * @return Crypt_Hash
      * @access public
      */
-    function Crypt_Hash($hash = 'sha1')
+    function __construct($hash = 'sha1')
     {
-        if ( !defined('CRYPT_HASH_MODE') ) {
+        if (!defined('CRYPT_HASH_MODE')) {
             switch (true) {
                 case extension_loaded('hash'):
                     define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
@@ -169,13 +169,25 @@ class Crypt_Hash
         $this->setHash($hash);
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @param int $mode
+     * @access public
+     */
+    function Crypt_Hash($hash = 'sha1')
+    {
+        $this->__construct($mode);
+    }
+
     /**
      * Sets the key for HMACs
      *
      * Keys can be of any length.
      *
      * @access public
-     * @param optional String $key
+     * @param string $key
      */
     function setKey($key = false)
     {
@@ -188,7 +200,7 @@ class Crypt_Hash
      * As set by the constructor or by the setHash() method.
      *
      * @access public
-     * @return String
+     * @return string
      */
     function getHash()
     {
@@ -199,7 +211,7 @@ class Crypt_Hash
      * Sets the hash function.
      *
      * @access public
-     * @param String $hash
+     * @param string $hash
      */
     function setHash($hash)
     {
@@ -242,7 +254,7 @@ class Crypt_Hash
                 $mode = CRYPT_HASH_MODE;
         }
 
-        switch ( $mode ) {
+        switch ($mode) {
             case CRYPT_HASH_MODE_MHASH:
                 switch ($hash) {
                     case 'md5':
@@ -276,26 +288,26 @@ class Crypt_Hash
 
         switch ($hash) {
             case 'md2':
-                 $this->b = 16;
-                 $this->hash = array($this, '_md2');
-                 break;
+                $this->b = 16;
+                $this->hash = array($this, '_md2');
+                break;
             case 'md5':
-                 $this->b = 64;
-                 $this->hash = array($this, '_md5');
-                 break;
+                $this->b = 64;
+                $this->hash = array($this, '_md5');
+                break;
             case 'sha256':
-                 $this->b = 64;
-                 $this->hash = array($this, '_sha256');
-                 break;
+                $this->b = 64;
+                $this->hash = array($this, '_sha256');
+                break;
             case 'sha384':
             case 'sha512':
-                 $this->b = 128;
-                 $this->hash = array($this, '_sha512');
-                 break;
+                $this->b = 128;
+                $this->hash = array($this, '_sha512');
+                break;
             case 'sha1':
             default:
-                 $this->b = 64;
-                 $this->hash = array($this, '_sha1');
+                $this->b = 64;
+                $this->hash = array($this, '_sha1');
         }
 
         $this->ipad = str_repeat(chr(0x36), $this->b);
@@ -306,15 +318,15 @@ class Crypt_Hash
      * Compute the HMAC.
      *
      * @access public
-     * @param String $text
-     * @return String
+     * @param string $text
+     * @return string
      */
     function hash($text)
     {
         $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
 
         if (!empty($this->key) || is_string($this->key)) {
-            switch ( $mode ) {
+            switch ($mode) {
                 case CRYPT_HASH_MODE_MHASH:
                     $output = mhash($this->hash, $text, $this->key);
                     break;
@@ -337,7 +349,7 @@ class Crypt_Hash
                     $output = call_user_func($this->hash, $output); // step 7
             }
         } else {
-            switch ( $mode ) {
+            switch ($mode) {
                 case CRYPT_HASH_MODE_MHASH:
                     $output = mhash($this->hash, $text);
                     break;
@@ -356,7 +368,7 @@ class Crypt_Hash
      * Returns the hash length (in bytes)
      *
      * @access public
-     * @return Integer
+     * @return int
      */
     function getLength()
     {
@@ -367,7 +379,7 @@ class Crypt_Hash
      * Wrapper for MD5
      *
      * @access private
-     * @param String $m
+     * @param string $m
      */
     function _md5($m)
     {
@@ -378,7 +390,7 @@ class Crypt_Hash
      * Wrapper for SHA1
      *
      * @access private
-     * @param String $m
+     * @param string $m
      */
     function _sha1($m)
     {
@@ -391,7 +403,7 @@ class Crypt_Hash
      * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
      *
      * @access private
-     * @param String $m
+     * @param string $m
      */
     function _md2($m)
     {
@@ -467,7 +479,7 @@ class Crypt_Hash
      * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
      *
      * @access private
-     * @param String $m
+     * @param string $m
      */
     function _sha256($m)
     {
@@ -511,14 +523,15 @@ class Crypt_Hash
 
             // Extend the sixteen 32-bit words into sixty-four 32-bit words
             for ($i = 16; $i < 64; $i++) {
+                // @codingStandardsIgnoreStart
                 $s0 = $this->_rightRotate($w[$i - 15],  7) ^
                       $this->_rightRotate($w[$i - 15], 18) ^
                       $this->_rightShift( $w[$i - 15],  3);
                 $s1 = $this->_rightRotate($w[$i - 2], 17) ^
                       $this->_rightRotate($w[$i - 2], 19) ^
                       $this->_rightShift( $w[$i - 2], 10);
+                // @codingStandardsIgnoreEnd
                 $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
-
             }
 
             // Initialize hash value for this chunk
@@ -572,7 +585,7 @@ class Crypt_Hash
      * Pure-PHP implementation of SHA384 and SHA512
      *
      * @access private
-     * @param String $m
+     * @param string $m
      */
     function _sha512($m)
     {
@@ -755,10 +768,10 @@ class Crypt_Hash
      * Right Rotate
      *
      * @access private
-     * @param Integer $int
-     * @param Integer $amt
-     * @see _sha256()
-     * @return Integer
+     * @param int $int
+     * @param int $amt
+     * @see self::_sha256()
+     * @return int
      */
     function _rightRotate($int, $amt)
     {
@@ -771,10 +784,10 @@ class Crypt_Hash
      * Right Shift
      *
      * @access private
-     * @param Integer $int
-     * @param Integer $amt
-     * @see _sha256()
-     * @return Integer
+     * @param int $int
+     * @param int $amt
+     * @see self::_sha256()
+     * @return int
      */
     function _rightShift($int, $amt)
     {
@@ -786,9 +799,9 @@ class Crypt_Hash
      * Not
      *
      * @access private
-     * @param Integer $int
-     * @see _sha256()
-     * @return Integer
+     * @param int $int
+     * @see self::_sha256()
+     * @return int
      */
     function _not($int)
     {
@@ -801,9 +814,9 @@ class Crypt_Hash
      * _sha256() adds multiple unsigned 32-bit integers.  Since PHP doesn't support unsigned integers and since the
      * possibility of overflow exists, care has to be taken.  Math_BigInteger() could be used but this should be faster.
      *
-     * @param Integer $...
-     * @return Integer
-     * @see _sha256()
+     * @param int $...
+     * @return int
+     * @see self::_sha256()
      * @access private
      */
     function _add()
@@ -819,7 +832,14 @@ class Crypt_Hash
             $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
         }
 
-        return fmod($result, $mod);
+        // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
+        // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
+        if (is_int($result) || version_compare(PHP_VERSION, '5.3.0') >= 0 || (PHP_OS & "\xDF\xDF\xDF") === 'WIN') {
+            return fmod($result, $mod);
+        }
+
+        return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
+            ((fmod(floor($result / 0x80000000), 2) & 1) << 31);
     }
 
     /**
@@ -827,9 +847,9 @@ class Crypt_Hash
      *
      * Inspired by array_shift
      *
-     * @param String $string
-     * @param optional Integer $index
-     * @return String
+     * @param string $string
+     * @param int $index
+     * @return string
      * @access private
      */
     function _string_shift(&$string, $index = 1)
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
index 96c9f18c16ccd85698526fa7eef6ea7acafb3a5f..97b4550cc353ea21242783b63ea4a36a6f1a7b34 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
@@ -62,8 +62,8 @@ if (!class_exists('Crypt_Base')) {
 
 /**#@+
  * @access public
- * @see Crypt_RC2::encrypt()
- * @see Crypt_RC2::decrypt()
+ * @see self::encrypt()
+ * @see self::decrypt()
  */
 /**
  * Encrypt / decrypt using the Counter mode.
@@ -99,20 +99,6 @@ define('CRYPT_RC2_MODE_CFB', CRYPT_MODE_CFB);
 define('CRYPT_RC2_MODE_OFB', CRYPT_MODE_OFB);
 /**#@-*/
 
-/**#@+
- * @access private
- * @see Crypt_RC2::Crypt_RC2()
- */
-/**
- * Toggles the internal implementation
- */
-define('CRYPT_RC2_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
-/**
- * Toggles the mcrypt implementation
- */
-define('CRYPT_RC2_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
-/**#@-*/
-
 /**
  * Pure-PHP implementation of RC2.
  *
@@ -125,7 +111,7 @@ class Crypt_RC2 extends Crypt_Base
      * Block Length of the cipher
      *
      * @see Crypt_Base::block_size
-     * @var Integer
+     * @var int
      * @access private
      */
     var $block_size = 8;
@@ -134,27 +120,47 @@ class Crypt_RC2 extends Crypt_Base
      * The Key
      *
      * @see Crypt_Base::key
-     * @see setKey()
-     * @var String
+     * @see self::setKey()
+     * @var string
+     * @access private
+     */
+    var $key;
+
+    /**
+     * The Original (unpadded) Key
+     *
+     * @see Crypt_Base::key
+     * @see self::setKey()
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @var string
      * @access private
      */
-    var $key = "\0";
+    var $orig_key;
 
     /**
-     * The default password key_size used by setPassword()
+     * Don't truncate / null pad key
      *
-     * @see Crypt_Base::password_key_size
-     * @see Crypt_Base::setPassword()
-     * @var Integer
+     * @see Crypt_Base::_clearBuffers()
+     * @var bool
      * @access private
      */
-    var $password_key_size = 16; // = 128 bits
+    var $skip_key_adjustment = true;
+
+    /**
+     * Key Length (in bytes)
+     *
+     * @see Crypt_RC2::setKeyLength()
+     * @var int
+     * @access private
+     */
+    var $key_length = 16; // = 128 bits
 
     /**
      * The namespace used by the cipher for its constants.
      *
      * @see Crypt_Base::const_namespace
-     * @var String
+     * @var string
      * @access private
      */
     var $const_namespace = 'RC2';
@@ -163,7 +169,7 @@ class Crypt_RC2 extends Crypt_Base
      * The mcrypt specific name of the cipher
      *
      * @see Crypt_Base::cipher_name_mcrypt
-     * @var String
+     * @var string
      * @access private
      */
     var $cipher_name_mcrypt = 'rc2';
@@ -172,7 +178,7 @@ class Crypt_RC2 extends Crypt_Base
      * Optimizing value while CFB-encrypting
      *
      * @see Crypt_Base::cfb_init_len
-     * @var Integer
+     * @var int
      * @access private
      */
     var $cfb_init_len = 500;
@@ -180,20 +186,31 @@ class Crypt_RC2 extends Crypt_Base
     /**
      * The key length in bits.
      *
-     * @see Crypt_RC2::setKeyLength()
-     * @see Crypt_RC2::setKey()
-     * @var Integer
+     * @see self::setKeyLength()
+     * @see self::setKey()
+     * @var int
      * @access private
      * @internal Should be in range [1..1024].
      * @internal Changing this value after setting the key has no effect.
      */
     var $default_key_length = 1024;
 
+    /**
+     * The key length in bits.
+     *
+     * @see self::isValidEnine()
+     * @see self::setKey()
+     * @var int
+     * @access private
+     * @internal Should be in range [1..1024].
+     */
+    var $current_key_length;
+
     /**
      * The Key Schedule
      *
-     * @see Crypt_RC2::_setupKey()
-     * @var Array
+     * @see self::_setupKey()
+     * @var array
      * @access private
      */
     var $keys;
@@ -202,8 +219,8 @@ class Crypt_RC2 extends Crypt_Base
      * Key expansion randomization table.
      * Twice the same 256-value sequence to save a modulus in key expansion.
      *
-     * @see Crypt_RC2::setKey()
-     * @var Array
+     * @see self::setKey()
+     * @var array
      * @access private
      */
     var $pitable = array(
@@ -276,8 +293,8 @@ class Crypt_RC2 extends Crypt_Base
     /**
      * Inverse key expansion randomization table.
      *
-     * @see Crypt_RC2::setKey()
-     * @var Array
+     * @see self::setKey()
+     * @var array
      * @access private
      */
     var $invpitable = array(
@@ -316,55 +333,68 @@ class Crypt_RC2 extends Crypt_Base
     );
 
     /**
-     * Default Constructor.
-     *
-     * Determines whether or not the mcrypt extension should be used.
-     *
-     * $mode could be:
-     *
-     * - CRYPT_RC2_MODE_ECB
-     *
-     * - CRYPT_RC2_MODE_CBC
-     *
-     * - CRYPT_RC2_MODE_CTR
+     * Test for engine validity
      *
-     * - CRYPT_RC2_MODE_CFB
-     *
-     * - CRYPT_RC2_MODE_OFB
-     *
-     * If not explicitly set, CRYPT_RC2_MODE_CBC will be used.
+     * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
      *
      * @see Crypt_Base::Crypt_Base()
-     * @param optional Integer $mode
+     * @param int $engine
      * @access public
+     * @return bool
      */
-    function Crypt_RC2($mode = CRYPT_RC2_MODE_CBC)
+    function isValidEngine($engine)
     {
-        parent::Crypt_Base($mode);
-        $this->setKey('');
+        switch ($engine) {
+            case CRYPT_ENGINE_OPENSSL:
+                if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) {
+                    return false;
+                }
+                $this->cipher_name_openssl_ecb = 'rc2-ecb';
+                $this->cipher_name_openssl = 'rc2-' . $this->_openssl_translate_mode();
+        }
+
+        return parent::isValidEngine($engine);
     }
 
     /**
-     * Sets the key length
+     * Sets the key length.
      *
-     * Valid key lengths are 1 to 1024.
+     * Valid key lengths are 8 to 1024.
      * Calling this function after setting the key has no effect until the next
      *  Crypt_RC2::setKey() call.
      *
      * @access public
-     * @param Integer $length in bits
+     * @param int $length in bits
      */
     function setKeyLength($length)
     {
-        if ($length >= 1 && $length <= 1024) {
+        if ($length < 8) {
+            $this->default_key_length = 8;
+        } elseif ($length > 1024) {
+            $this->default_key_length = 128;
+        } else {
             $this->default_key_length = $length;
         }
+        $this->current_key_length = $this->default_key_length;
+
+        parent::setKeyLength($length);
+    }
+
+    /**
+     * Returns the current key length
+     *
+     * @access public
+     * @return int
+     */
+    function getKeyLength()
+    {
+        return $this->current_key_length;
     }
 
     /**
      * Sets the key.
      *
-     * Keys can be of any length. RC2, itself, uses 1 to 1024 bit keys (eg.
+     * Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg.
      * strlen($key) <= 128), however, we only use the first 128 bytes if $key
      * has more then 128 bytes in it, and set $key to a single null byte if
      * it is empty.
@@ -374,16 +404,19 @@ class Crypt_RC2 extends Crypt_Base
      *
      * @see Crypt_Base::setKey()
      * @access public
-     * @param String $key
-     * @param Integer $t1 optional          Effective key length in bits.
+     * @param string $key
+     * @param int $t1 optional Effective key length in bits.
      */
     function setKey($key, $t1 = 0)
     {
+        $this->orig_key = $key;
+
         if ($t1 <= 0) {
             $t1 = $this->default_key_length;
-        } else if ($t1 > 1024) {
+        } elseif ($t1 > 1024) {
             $t1 = 1024;
         }
+        $this->current_key_length = $t1;
         // Key byte count should be 1..128.
         $key = strlen($key) ? substr($key, 0, 128) : "\x00";
         $t = strlen($key);
@@ -413,17 +446,64 @@ class Crypt_RC2 extends Crypt_Base
         // Prepare the key for mcrypt.
         $l[0] = $this->invpitable[$l[0]];
         array_unshift($l, 'C*');
+
         parent::setKey(call_user_func_array('pack', $l));
     }
 
+    /**
+     * Encrypts a message.
+     *
+     * Mostly a wrapper for Crypt_Base::encrypt, with some additional OpenSSL handling code
+     *
+     * @see self::decrypt()
+     * @access public
+     * @param string $plaintext
+     * @return string $ciphertext
+     */
+    function encrypt($plaintext)
+    {
+        if ($this->engine == CRYPT_ENGINE_OPENSSL) {
+            $temp = $this->key;
+            $this->key = $this->orig_key;
+            $result = parent::encrypt($plaintext);
+            $this->key = $temp;
+            return $result;
+        }
+
+        return parent::encrypt($plaintext);
+    }
+
+    /**
+     * Decrypts a message.
+     *
+     * Mostly a wrapper for Crypt_Base::decrypt, with some additional OpenSSL handling code
+     *
+     * @see self::encrypt()
+     * @access public
+     * @param string $ciphertext
+     * @return string $plaintext
+     */
+    function decrypt($ciphertext)
+    {
+        if ($this->engine == CRYPT_ENGINE_OPENSSL) {
+            $temp = $this->key;
+            $this->key = $this->orig_key;
+            $result = parent::decrypt($ciphertext);
+            $this->key = $temp;
+            return $result;
+        }
+
+        return parent::decrypt($ciphertext);
+    }
+
     /**
      * Encrypts a block
      *
      * @see Crypt_Base::_encryptBlock()
      * @see Crypt_Base::encrypt()
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
      */
     function _encryptBlock($in)
     {
@@ -467,8 +547,8 @@ class Crypt_RC2 extends Crypt_Base
      * @see Crypt_Base::_decryptBlock()
      * @see Crypt_Base::decrypt()
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
      */
     function _decryptBlock($in)
     {
@@ -506,6 +586,21 @@ class Crypt_RC2 extends Crypt_Base
         return pack('vvvv', $r0, $r1, $r2, $r3);
     }
 
+    /**
+     * Setup the CRYPT_ENGINE_MCRYPT $engine
+     *
+     * @see Crypt_Base::_setupMcrypt()
+     * @access private
+     */
+    function _setupMcrypt()
+    {
+        if (!isset($this->key)) {
+            $this->setKey('');
+        }
+
+        parent::_setupMcrypt();
+    }
+
     /**
      * Creates the key schedule
      *
@@ -514,6 +609,10 @@ class Crypt_RC2 extends Crypt_Base
      */
     function _setupKey()
     {
+        if (!isset($this->key)) {
+            $this->setKey('');
+        }
+
         // Key has already been expanded in Crypt_RC2::setKey():
         // Only the first value must be altered.
         $l = unpack('Ca/Cb/v*', $this->key);
@@ -536,14 +635,14 @@ class Crypt_RC2 extends Crypt_Base
         // The first 10 generated $lambda_functions will use the $keys hardcoded as integers
         // for the mixing rounds, for better inline crypt performance [~20% faster].
         // But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10.
-        $keys = $this->keys;
-        if (count($lambda_functions) >= 10) {
-            foreach ($this->keys as $k => $v) {
-                $keys[$k] = '$keys[' . $k . ']';
-            }
-        }
+        // (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit)
+        $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
 
-        $code_hash = md5(str_pad("Crypt_RC2, {$this->mode}, ", 32, "\0") . implode(',', $keys));
+        // Generation of a unique hash for our generated code
+        $code_hash = "Crypt_RC2, {$this->mode}";
+        if ($gen_hi_opt_code) {
+            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+        }
 
         // Is there a re-usable $lambda_functions in there?
         // If not, we have to create it.
@@ -551,6 +650,16 @@ class Crypt_RC2 extends Crypt_Base
             // Init code for both, encrypt and decrypt.
             $init_crypt = '$keys = $self->keys;';
 
+            switch (true) {
+                case $gen_hi_opt_code:
+                    $keys = $this->keys;
+                default:
+                    $keys = array();
+                    foreach ($this->keys as $k => $v) {
+                        $keys[$k] = '$keys[' . $k . ']';
+                    }
+            }
+
             // $in is the current 8 bytes block which has to be en/decrypt
             $encrypt_block = $decrypt_block = '
                 $in = unpack("v4", $in);
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
index d5eda8c349ae96e644ba606f98e5bfae9f5f823b..ce29e6affcee57bc6477c3d2d227f00a37aed0c3 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
@@ -71,21 +71,7 @@ if (!class_exists('Crypt_Base')) {
 
 /**#@+
  * @access private
- * @see Crypt_RC4::Crypt_RC4()
- */
-/**
- * Toggles the internal implementation
- */
-define('CRYPT_RC4_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
-/**
- * Toggles the mcrypt implementation
- */
-define('CRYPT_RC4_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
-/**#@-*/
-
-/**#@+
- * @access private
- * @see Crypt_RC4::_crypt()
+ * @see self::_crypt()
  */
 define('CRYPT_RC4_ENCRYPT', 0);
 define('CRYPT_RC4_DECRYPT', 1);
@@ -107,26 +93,25 @@ class Crypt_RC4 extends Crypt_Base
      * so we the block_size to 0
      *
      * @see Crypt_Base::block_size
-     * @var Integer
+     * @var int
      * @access private
      */
     var $block_size = 0;
 
     /**
-     * The default password key_size used by setPassword()
+     * Key Length (in bytes)
      *
-     * @see Crypt_Base::password_key_size
-     * @see Crypt_Base::setPassword()
-     * @var Integer
+     * @see Crypt_RC4::setKeyLength()
+     * @var int
      * @access private
      */
-    var $password_key_size = 128; // = 1024 bits
+    var $key_length = 128; // = 1024 bits
 
     /**
      * The namespace used by the cipher for its constants.
      *
      * @see Crypt_Base::const_namespace
-     * @var String
+     * @var string
      * @access private
      */
     var $const_namespace = 'RC4';
@@ -135,7 +120,7 @@ class Crypt_RC4 extends Crypt_Base
      * The mcrypt specific name of the cipher
      *
      * @see Crypt_Base::cipher_name_mcrypt
-     * @var String
+     * @var string
      * @access private
      */
     var $cipher_name_mcrypt = 'arcfour';
@@ -152,8 +137,8 @@ class Crypt_RC4 extends Crypt_Base
     /**
      * The Key
      *
-     * @see Crypt_RC4::setKey()
-     * @var String
+     * @see self::setKey()
+     * @var string
      * @access private
      */
     var $key = "\0";
@@ -161,8 +146,8 @@ class Crypt_RC4 extends Crypt_Base
     /**
      * The Key Stream for decryption and encryption
      *
-     * @see Crypt_RC4::setKey()
-     * @var Array
+     * @see self::setKey()
+     * @var array
      * @access private
      */
     var $stream;
@@ -176,9 +161,52 @@ class Crypt_RC4 extends Crypt_Base
      * @return Crypt_RC4
      * @access public
      */
+    function __construct()
+    {
+        parent::__construct(CRYPT_MODE_STREAM);
+    }
+
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @access public
+     */
     function Crypt_RC4()
     {
-        parent::Crypt_Base(CRYPT_MODE_STREAM);
+        $this->__construct();
+    }
+
+    /**
+     * Test for engine validity
+     *
+     * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
+     *
+     * @see Crypt_Base::Crypt_Base()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        switch ($engine) {
+            case CRYPT_ENGINE_OPENSSL:
+                switch (strlen($this->key)) {
+                    case 5:
+                        $this->cipher_name_openssl = 'rc4-40';
+                        break;
+                    case 8:
+                        $this->cipher_name_openssl = 'rc4-64';
+                        break;
+                    case 16:
+                        $this->cipher_name_openssl = 'rc4';
+                        break;
+                    default:
+                        return false;
+                }
+        }
+
+        return parent::isValidEngine($engine);
     }
 
     /**
@@ -196,8 +224,8 @@ class Crypt_RC4 extends Crypt_Base
      * {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
      * {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
      *
-     * @param String $iv
-     * @see Crypt_RC4::setKey()
+     * @param string $iv
+     * @see self::setKey()
      * @access public
      */
     function setIV($iv)
@@ -205,32 +233,38 @@ class Crypt_RC4 extends Crypt_Base
     }
 
     /**
-     * Sets the key.
+     * Sets the key length
      *
-     * Keys can be between 1 and 256 bytes long.  If they are longer then 256 bytes, the first 256 bytes will
-     * be used.  If no key is explicitly set, it'll be assumed to be a single null byte.
+     * Keys can be between 1 and 256 bytes long.
      *
      * @access public
-     * @see Crypt_Base::setKey()
-     * @param String $key
+     * @param int $length
      */
-    function setKey($key)
+    function setKeyLength($length)
     {
-        parent::setKey(substr($key, 0, 256));
+        if ($length < 8) {
+            $this->key_length = 1;
+        } elseif ($length > 2048) {
+            $this->key_length = 256;
+        } else {
+            $this->key_length = $length >> 3;
+        }
+
+        parent::setKeyLength($length);
     }
 
     /**
      * Encrypts a message.
      *
      * @see Crypt_Base::decrypt()
-     * @see Crypt_RC4::_crypt()
+     * @see self::_crypt()
      * @access public
-     * @param String $plaintext
-     * @return String $ciphertext
+     * @param string $plaintext
+     * @return string $ciphertext
      */
     function encrypt($plaintext)
     {
-        if ($this->engine == CRYPT_MODE_MCRYPT) {
+        if ($this->engine != CRYPT_ENGINE_INTERNAL) {
             return parent::encrypt($plaintext);
         }
         return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
@@ -243,14 +277,14 @@ class Crypt_RC4 extends Crypt_Base
      * At least if the continuous buffer is disabled.
      *
      * @see Crypt_Base::encrypt()
-     * @see Crypt_RC4::_crypt()
+     * @see self::_crypt()
      * @access public
-     * @param String $ciphertext
-     * @return String $plaintext
+     * @param string $ciphertext
+     * @return string $plaintext
      */
     function decrypt($ciphertext)
     {
-        if ($this->engine == CRYPT_MODE_MCRYPT) {
+        if ($this->engine != CRYPT_ENGINE_INTERNAL) {
             return parent::decrypt($ciphertext);
         }
         return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
@@ -287,12 +321,12 @@ class Crypt_RC4 extends Crypt_Base
     /**
      * Encrypts or decrypts a message.
      *
-     * @see Crypt_RC4::encrypt()
-     * @see Crypt_RC4::decrypt()
+     * @see self::encrypt()
+     * @see self::decrypt()
      * @access private
-     * @param String $text
-     * @param Integer $mode
-     * @return String $text
+     * @param string $text
+     * @param int $mode
+     * @return string $text
      */
     function _crypt($text, $mode)
     {
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
index 53f94354fcbcbfe96a0f2f475a76784f93054a64..3eacfe161e0b360c929b3f8a2644b853147173f9 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
@@ -87,8 +87,8 @@ if (!class_exists('Crypt_Hash')) {
 
 /**#@+
  * @access public
- * @see Crypt_RSA::encrypt()
- * @see Crypt_RSA::decrypt()
+ * @see self::encrypt()
+ * @see self::decrypt()
  */
 /**
  * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}
@@ -96,8 +96,8 @@ if (!class_exists('Crypt_Hash')) {
  *
  * Uses sha1 by default.
  *
- * @see Crypt_RSA::setHash()
- * @see Crypt_RSA::setMGFHash()
+ * @see self::setHash()
+ * @see self::setMGFHash()
  */
 define('CRYPT_RSA_ENCRYPTION_OAEP',  1);
 /**
@@ -107,21 +107,28 @@ define('CRYPT_RSA_ENCRYPTION_OAEP',  1);
  * compatibility with protocols (like SSH-1) written before OAEP's introduction.
  */
 define('CRYPT_RSA_ENCRYPTION_PKCS1', 2);
+/**
+ * Do not use any padding
+ *
+ * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy
+ * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc.
+ */
+define('CRYPT_RSA_ENCRYPTION_NONE', 3);
 /**#@-*/
 
 /**#@+
  * @access public
- * @see Crypt_RSA::sign()
- * @see Crypt_RSA::verify()
- * @see Crypt_RSA::setHash()
+ * @see self::sign()
+ * @see self::verify()
+ * @see self::setHash()
  */
 /**
  * Use the Probabilistic Signature Scheme for signing
  *
  * Uses sha1 by default.
  *
- * @see Crypt_RSA::setSaltLength()
- * @see Crypt_RSA::setMGFHash()
+ * @see self::setSaltLength()
+ * @see self::setMGFHash()
  */
 define('CRYPT_RSA_SIGNATURE_PSS',  1);
 /**
@@ -135,7 +142,7 @@ define('CRYPT_RSA_SIGNATURE_PKCS1', 2);
 
 /**#@+
  * @access private
- * @see Crypt_RSA::createKey()
+ * @see self::createKey()
  */
 /**
  * ASN1 Integer
@@ -161,7 +168,7 @@ define('CRYPT_RSA_ASN1_SEQUENCE',   48);
 
 /**#@+
  * @access private
- * @see Crypt_RSA::Crypt_RSA()
+ * @see self::Crypt_RSA()
  */
 /**
  * To use the pure-PHP implementation
@@ -182,8 +189,8 @@ define('CRYPT_RSA_OPENSSL_CONFIG', dirname(__FILE__) . '/../openssl.cnf');
 
 /**#@+
  * @access public
- * @see Crypt_RSA::createKey()
- * @see Crypt_RSA::setPrivateKeyFormat()
+ * @see self::createKey()
+ * @see self::setPrivateKeyFormat()
  */
 /**
  * PKCS#1 formatted private key
@@ -202,13 +209,13 @@ define('CRYPT_RSA_PRIVATE_FORMAT_XML', 2);
 /**
  * PKCS#8 formatted private key
  */
-define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 3);
+define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 8);
 /**#@-*/
 
 /**#@+
  * @access public
- * @see Crypt_RSA::createKey()
- * @see Crypt_RSA::setPublicKeyFormat()
+ * @see self::createKey()
+ * @see self::setPublicKeyFormat()
  */
 /**
  * Raw public key
@@ -275,7 +282,7 @@ class Crypt_RSA
     /**
      * Precomputed Zero
      *
-     * @var Array
+     * @var Math_BigInteger
      * @access private
      */
     var $zero;
@@ -283,7 +290,7 @@ class Crypt_RSA
     /**
      * Precomputed One
      *
-     * @var Array
+     * @var Math_BigInteger
      * @access private
      */
     var $one;
@@ -291,7 +298,7 @@ class Crypt_RSA
     /**
      * Private Key Format
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $privateKeyFormat = CRYPT_RSA_PRIVATE_FORMAT_PKCS1;
@@ -299,7 +306,7 @@ class Crypt_RSA
     /**
      * Public Key Format
      *
-     * @var Integer
+     * @var int
      * @access public
      */
     var $publicKeyFormat = CRYPT_RSA_PUBLIC_FORMAT_PKCS8;
@@ -331,7 +338,7 @@ class Crypt_RSA
     /**
      * Primes for Chinese Remainder Theorem (ie. p and q)
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $primes;
@@ -339,7 +346,7 @@ class Crypt_RSA
     /**
      * Exponents for Chinese Remainder Theorem (ie. dP and dQ)
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $exponents;
@@ -347,7 +354,7 @@ class Crypt_RSA
     /**
      * Coefficients for Chinese Remainder Theorem (ie. qInv)
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $coefficients;
@@ -355,7 +362,7 @@ class Crypt_RSA
     /**
      * Hash name
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $hashName;
@@ -371,7 +378,7 @@ class Crypt_RSA
     /**
      * Length of hash function output
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $hLen;
@@ -379,7 +386,7 @@ class Crypt_RSA
     /**
      * Length of salt
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $sLen;
@@ -395,7 +402,7 @@ class Crypt_RSA
     /**
      * Length of MGF hash function output
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $mgfHLen;
@@ -403,7 +410,7 @@ class Crypt_RSA
     /**
      * Encryption mode
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $encryptionMode = CRYPT_RSA_ENCRYPTION_OAEP;
@@ -411,7 +418,7 @@ class Crypt_RSA
     /**
      * Signature mode
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $signatureMode = CRYPT_RSA_SIGNATURE_PSS;
@@ -419,7 +426,7 @@ class Crypt_RSA
     /**
      * Public Exponent
      *
-     * @var Mixed
+     * @var mixed
      * @access private
      */
     var $publicExponent = false;
@@ -427,7 +434,7 @@ class Crypt_RSA
     /**
      * Password
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $password = false;
@@ -438,8 +445,8 @@ class Crypt_RSA
      * For use with parsing XML formatted keys.  PHP's XML Parser functions use utilized - instead of PHP's DOM functions -
      * because PHP's XML Parser functions work on PHP4 whereas PHP's DOM functions - although surperior - don't.
      *
-     * @see Crypt_RSA::_start_element_handler()
-     * @var Array
+     * @see self::_start_element_handler()
+     * @var array
      * @access private
      */
     var $components = array();
@@ -449,9 +456,9 @@ class Crypt_RSA
      *
      * For use with parsing XML formatted keys.
      *
-     * @see Crypt_RSA::_character_handler()
-     * @see Crypt_RSA::_stop_element_handler()
-     * @var Mixed
+     * @see self::_character_handler()
+     * @see self::_stop_element_handler()
+     * @var mixed
      * @access private
      */
     var $current;
@@ -460,8 +467,8 @@ class Crypt_RSA
      * OpenSSL configuration file name.
      *
      * Set to null to use system configuration file.
-     * @see Crypt_RSA::createKey()
-     * @var Mixed
+     * @see self::createKey()
+     * @var mixed
      * @Access public
      */
     var $configFile;
@@ -469,7 +476,7 @@ class Crypt_RSA
     /**
      * Public key comment field.
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $comment = 'phpseclib-generated-key';
@@ -484,7 +491,7 @@ class Crypt_RSA
      * @return Crypt_RSA
      * @access public
      */
-    function Crypt_RSA()
+    function __construct()
     {
         if (!class_exists('Math_BigInteger')) {
             include_once 'Math/BigInteger.php';
@@ -492,7 +499,7 @@ class Crypt_RSA
 
         $this->configFile = CRYPT_RSA_OPENSSL_CONFIG;
 
-        if ( !defined('CRYPT_RSA_MODE') ) {
+        if (!defined('CRYPT_RSA_MODE')) {
             switch (true) {
                 // Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular,
                 // Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger
@@ -532,6 +539,7 @@ class Crypt_RSA
                         case !isset($versions['Header']):
                         case !isset($versions['Library']):
                         case $versions['Header'] == $versions['Library']:
+                        case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0:
                             define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_OPENSSL);
                             break;
                         default:
@@ -554,6 +562,17 @@ class Crypt_RSA
         $this->mgfHLen = $this->mgfHash->getLength();
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @access public
+     */
+    function Crypt_RSA()
+    {
+        $this->__construct();
+    }
+
     /**
      * Create public / private key pair
      *
@@ -564,9 +583,9 @@ class Crypt_RSA
      *                  Will need to be passed back to Crypt_RSA::createKey() as the third parameter for further processing.
      *
      * @access public
-     * @param optional Integer $bits
-     * @param optional Integer $timeout
-     * @param optional Math_BigInteger $p
+     * @param int $bits
+     * @param int $timeout
+     * @param Math_BigInteger $p
      */
     function createKey($bits = 1024, $timeout = false, $partial = array())
     {
@@ -585,7 +604,7 @@ class Crypt_RSA
         }
 
         // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
-        if ( CRYPT_RSA_MODE == CRYPT_RSA_MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) {
+        if (CRYPT_RSA_MODE == CRYPT_RSA_MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) {
             $config = array();
             if (isset($this->configFile)) {
                 $config['config'] = $this->configFile;
@@ -599,7 +618,8 @@ class Crypt_RSA
             $publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, CRYPT_RSA_PUBLIC_FORMAT_PKCS1)));
 
             // clear the buffer of error strings stemming from a minimalistic openssl.cnf
-            while (openssl_error_string() !== false);
+            while (openssl_error_string() !== false) {
+            }
 
             return array(
                 'privatekey' => $privatekey,
@@ -743,9 +763,9 @@ class Crypt_RSA
      * Convert a private key to the appropriate format.
      *
      * @access private
-     * @see setPrivateKeyFormat()
-     * @param String $RSAPrivateKey
-     * @return String
+     * @see self::setPrivateKeyFormat()
+     * @param string $RSAPrivateKey
+     * @return string
      */
     function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
     {
@@ -789,19 +809,39 @@ class Crypt_RSA
                 $encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none';
                 $key.= $encryption;
                 $key.= "\r\nComment: " . $this->comment . "\r\n";
-                $public = pack('Na*Na*Na*',
-                    strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']
+                $public = pack(
+                    'Na*Na*Na*',
+                    strlen('ssh-rsa'),
+                    'ssh-rsa',
+                    strlen($raw['publicExponent']),
+                    $raw['publicExponent'],
+                    strlen($raw['modulus']),
+                    $raw['modulus']
                 );
-                $source = pack('Na*Na*Na*Na*',
-                    strlen('ssh-rsa'), 'ssh-rsa', strlen($encryption), $encryption,
-                    strlen($this->comment), $this->comment, strlen($public), $public
+                $source = pack(
+                    'Na*Na*Na*Na*',
+                    strlen('ssh-rsa'),
+                    'ssh-rsa',
+                    strlen($encryption),
+                    $encryption,
+                    strlen($this->comment),
+                    $this->comment,
+                    strlen($public),
+                    $public
                 );
                 $public = base64_encode($public);
                 $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
                 $key.= chunk_split($public, 64);
-                $private = pack('Na*Na*Na*Na*',
-                    strlen($raw['privateExponent']), $raw['privateExponent'], strlen($raw['prime1']), $raw['prime1'],
-                    strlen($raw['prime2']), $raw['prime2'], strlen($raw['coefficient']), $raw['coefficient']
+                $private = pack(
+                    'Na*Na*Na*Na*',
+                    strlen($raw['privateExponent']),
+                    $raw['privateExponent'],
+                    strlen($raw['prime1']),
+                    $raw['prime1'],
+                    strlen($raw['prime2']),
+                    $raw['prime2'],
+                    strlen($raw['coefficient']),
+                    $raw['coefficient']
                 );
                 if (empty($this->password) && !is_string($this->password)) {
                     $source.= pack('Na*', strlen($private), $private);
@@ -868,8 +908,14 @@ class Crypt_RSA
 
                 if ($this->privateKeyFormat == CRYPT_RSA_PRIVATE_FORMAT_PKCS8) {
                     $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
-                    $RSAPrivateKey = pack('Ca*a*Ca*a*',
-                        CRYPT_RSA_ASN1_INTEGER, "\01\00", $rsaOID, 4, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey
+                    $RSAPrivateKey = pack(
+                        'Ca*a*Ca*a*',
+                        CRYPT_RSA_ASN1_INTEGER,
+                        "\01\00",
+                        $rsaOID,
+                        4,
+                        $this->_encodeLength(strlen($RSAPrivateKey)),
+                        $RSAPrivateKey
                     );
                     $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
                     if (!empty($this->password) || is_string($this->password)) {
@@ -883,20 +929,35 @@ class Crypt_RSA
                         $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
                         $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
 
-                        $parameters = pack('Ca*a*Ca*N',
-                            CRYPT_RSA_ASN1_OCTETSTRING, $this->_encodeLength(strlen($salt)), $salt,
-                            CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(4), $iterationCount
+                        $parameters = pack(
+                            'Ca*a*Ca*N',
+                            CRYPT_RSA_ASN1_OCTETSTRING,
+                            $this->_encodeLength(strlen($salt)),
+                            $salt,
+                            CRYPT_RSA_ASN1_INTEGER,
+                            $this->_encodeLength(4),
+                            $iterationCount
                         );
                         $pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
 
-                        $encryptionAlgorithm = pack('Ca*a*Ca*a*',
-                            CRYPT_RSA_ASN1_OBJECT, $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)), $pbeWithMD5AndDES_CBC,
-                            CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($parameters)), $parameters
+                        $encryptionAlgorithm = pack(
+                            'Ca*a*Ca*a*',
+                            CRYPT_RSA_ASN1_OBJECT,
+                            $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
+                            $pbeWithMD5AndDES_CBC,
+                            CRYPT_RSA_ASN1_SEQUENCE,
+                            $this->_encodeLength(strlen($parameters)),
+                            $parameters
                         );
 
-                        $RSAPrivateKey = pack('Ca*a*Ca*a*',
-                            CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($encryptionAlgorithm)), $encryptionAlgorithm,
-                            CRYPT_RSA_ASN1_OCTETSTRING, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey
+                        $RSAPrivateKey = pack(
+                            'Ca*a*Ca*a*',
+                            CRYPT_RSA_ASN1_SEQUENCE,
+                            $this->_encodeLength(strlen($encryptionAlgorithm)),
+                            $encryptionAlgorithm,
+                            CRYPT_RSA_ASN1_OCTETSTRING,
+                            $this->_encodeLength(strlen($RSAPrivateKey)),
+                            $RSAPrivateKey
                         );
 
                         $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
@@ -943,9 +1004,9 @@ class Crypt_RSA
      * Convert a public key to the appropriate format
      *
      * @access private
-     * @see setPublicKeyFormat()
-     * @param String $RSAPrivateKey
-     * @return String
+     * @see self::setPublicKeyFormat()
+     * @param string $RSAPrivateKey
+     * @return string
      */
     function _convertPublicKey($n, $e)
     {
@@ -983,9 +1044,12 @@ class Crypt_RSA
                     'publicExponent' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent)
                 );
 
-                $RSAPublicKey = pack('Ca*a*a*',
-                    CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
-                    $components['modulus'], $components['publicExponent']
+                $RSAPublicKey = pack(
+                    'Ca*a*a*',
+                    CRYPT_RSA_ASN1_SEQUENCE,
+                    $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
+                    $components['modulus'],
+                    $components['publicExponent']
                 );
 
                 if ($this->publicKeyFormat == CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW) {
@@ -998,8 +1062,11 @@ class Crypt_RSA
                     $RSAPublicKey = chr(0) . $RSAPublicKey;
                     $RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
 
-                    $RSAPublicKey = pack('Ca*a*',
-                        CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey
+                    $RSAPublicKey = pack(
+                        'Ca*a*',
+                        CRYPT_RSA_ASN1_SEQUENCE,
+                        $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)),
+                        $rsaOID . $RSAPublicKey
                     );
 
                     $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
@@ -1015,11 +1082,11 @@ class Crypt_RSA
      * Break a public or private key down into its constituant components
      *
      * @access private
-     * @see _convertPublicKey()
-     * @see _convertPrivateKey()
-     * @param String $key
-     * @param Integer $type
-     * @return Array
+     * @see self::_convertPublicKey()
+     * @see self::_convertPrivateKey()
+     * @param string $key
+     * @param int $type
+     * @return array
      */
     function _parseKey($key, $type)
     {
@@ -1435,7 +1502,7 @@ class Crypt_RSA
      * More specifically, this returns the size of the modulo in bits.
      *
      * @access public
-     * @return Integer
+     * @return int
      */
     function getSize()
     {
@@ -1448,9 +1515,9 @@ class Crypt_RSA
      * Called by xml_set_element_handler()
      *
      * @access private
-     * @param Resource $parser
-     * @param String $name
-     * @param Array $attribs
+     * @param resource $parser
+     * @param string $name
+     * @param array $attribs
      */
     function _start_element_handler($parser, $name, $attribs)
     {
@@ -1489,8 +1556,8 @@ class Crypt_RSA
      * Called by xml_set_element_handler()
      *
      * @access private
-     * @param Resource $parser
-     * @param String $name
+     * @param resource $parser
+     * @param string $name
      */
     function _stop_element_handler($parser, $name)
     {
@@ -1506,8 +1573,8 @@ class Crypt_RSA
      * Called by xml_set_character_data_handler()
      *
      * @access private
-     * @param Resource $parser
-     * @param String $data
+     * @param resource $parser
+     * @param string $data
      */
     function _data_handler($parser, $data)
     {
@@ -1523,8 +1590,8 @@ class Crypt_RSA
      * Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed)
      *
      * @access public
-     * @param String $key
-     * @param Integer $type optional
+     * @param string $key
+     * @param int $type optional
      */
     function loadKey($key, $type = false)
     {
@@ -1589,7 +1656,6 @@ class Crypt_RSA
                     break;
                 }
             }
-
         } else {
             $components = $this->_parseKey($key, $type);
         }
@@ -1638,10 +1704,10 @@ class Crypt_RSA
      * Private keys can be encrypted with a password.  To unset the password, pass in the empty string or false.
      * Or rather, pass in $password such that empty($password) && !is_string($password) is true.
      *
-     * @see createKey()
-     * @see loadKey()
+     * @see self::createKey()
+     * @see self::loadKey()
      * @access public
-     * @param String $password
+     * @param string $password
      */
     function setPassword($password = false)
     {
@@ -1663,11 +1729,11 @@ class Crypt_RSA
      *
      * Returns true on success, false on failure
      *
-     * @see getPublicKey()
+     * @see self::getPublicKey()
      * @access public
-     * @param String $key optional
-     * @param Integer $type optional
-     * @return Boolean
+     * @param string $key optional
+     * @param int $type optional
+     * @return bool
      */
     function setPublicKey($key = false, $type = false)
     {
@@ -1723,16 +1789,16 @@ class Crypt_RSA
      *
      * Returns true on success, false on failure
      *
-     * @see getPublicKey()
+     * @see self::getPublicKey()
      * @access public
-     * @param String $key optional
-     * @param Integer $type optional
-     * @return Boolean
+     * @param string $key optional
+     * @param int $type optional
+     * @return bool
      */
     function setPrivateKey($key = false, $type = false)
     {
         if ($key === false && !empty($this->publicExponent)) {
-            unset($this->publicExponent);
+            $this->publicExponent = false;
             return true;
         }
 
@@ -1740,7 +1806,7 @@ class Crypt_RSA
         if (!$rsa->loadKey($key, $type)) {
             return false;
         }
-        unset($rsa->publicExponent);
+        $rsa->publicExponent = false;
 
         // don't overwrite the old key if the new key is invalid
         $this->loadKey($rsa);
@@ -1754,10 +1820,10 @@ class Crypt_RSA
      * or if the public key was set via setPublicKey().  If the currently loaded key is supposed to be the public key this
      * function won't return it since this library, for the most part, doesn't distinguish between public and private keys.
      *
-     * @see getPublicKey()
+     * @see self::getPublicKey()
      * @access public
-     * @param String $key
-     * @param Integer $type optional
+     * @param string $key
+     * @param int $type optional
      */
     function getPublicKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS8)
     {
@@ -1772,15 +1838,51 @@ class Crypt_RSA
         return $temp;
     }
 
+    /**
+     * Returns the public key's fingerprint
+     *
+     * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is
+     * no public key currently loaded, false is returned.
+     * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716)
+     *
+     * @access public
+     * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned
+     * for invalid values.
+     * @return mixed
+     */
+    function getPublicKeyFingerprint($algorithm = 'md5')
+    {
+        if (empty($this->modulus) || empty($this->publicExponent)) {
+            return false;
+        }
+
+        $modulus = $this->modulus->toBytes(true);
+        $publicExponent = $this->publicExponent->toBytes(true);
+
+        $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
+
+        switch ($algorithm) {
+            case 'sha256':
+                $hash = new Crypt_Hash('sha256');
+                $base = base64_encode($hash->hash($RSAPublicKey));
+                return substr($base, 0, strlen($base) - 1);
+            case 'md5':
+                return substr(chunk_split(md5($RSAPublicKey), 2, ':'), 0, -1);
+            default:
+                return false;
+        }
+    }
+
     /**
      * Returns the private key
      *
      * The private key is only returned if the currently loaded key contains the constituent prime numbers.
      *
-     * @see getPublicKey()
+     * @see self::getPublicKey()
      * @access public
-     * @param String $key
-     * @param Integer $type optional
+     * @param string $key
+     * @param int $type optional
+     * @return mixed
      */
     function getPrivateKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1)
     {
@@ -1801,10 +1903,10 @@ class Crypt_RSA
      * Returns the private key without the prime number constituants.  Structurally identical to a public key that
      * hasn't been set as the public key
      *
-     * @see getPrivateKey()
+     * @see self::getPrivateKey()
      * @access private
-     * @param String $key
-     * @param Integer $type optional
+     * @param string $key
+     * @param int $type optional
      */
     function _getPrivatePublicKey($mode = CRYPT_RSA_PUBLIC_FORMAT_PKCS8)
     {
@@ -1823,6 +1925,7 @@ class Crypt_RSA
      *  __toString() magic method
      *
      * @access public
+     * @return string
      */
     function __toString()
     {
@@ -1838,6 +1941,7 @@ class Crypt_RSA
      *  __clone() magic method
      *
      * @access public
+     * @return Crypt_RSA
      */
     function __clone()
     {
@@ -1850,8 +1954,8 @@ class Crypt_RSA
      * Generates the smallest and largest numbers requiring $bits bits
      *
      * @access private
-     * @param Integer $bits
-     * @return Array
+     * @param int $bits
+     * @return array
      */
     function _generateMinMax($bits)
     {
@@ -1879,13 +1983,13 @@ class Crypt_RSA
      * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
      *
      * @access private
-     * @param String $string
-     * @return Integer
+     * @param string $string
+     * @return int
      */
     function _decodeLength(&$string)
     {
         $length = ord($this->_string_shift($string));
-        if ( $length & 0x80 ) { // definite length, long form
+        if ($length & 0x80) { // definite length, long form
             $length&= 0x7F;
             $temp = $this->_string_shift($string, $length);
             list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
@@ -1900,8 +2004,8 @@ class Crypt_RSA
      * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
      *
      * @access private
-     * @param Integer $length
-     * @return String
+     * @param int $length
+     * @return string
      */
     function _encodeLength($length)
     {
@@ -1918,9 +2022,9 @@ class Crypt_RSA
      *
      * Inspired by array_shift
      *
-     * @param String $string
-     * @param optional Integer $index
-     * @return String
+     * @param string $string
+     * @param int $index
+     * @return string
      * @access private
      */
     function _string_shift(&$string, $index = 1)
@@ -1933,9 +2037,9 @@ class Crypt_RSA
     /**
      * Determines the private key format
      *
-     * @see createKey()
+     * @see self::createKey()
      * @access public
-     * @param Integer $format
+     * @param int $format
      */
     function setPrivateKeyFormat($format)
     {
@@ -1945,9 +2049,9 @@ class Crypt_RSA
     /**
      * Determines the public key format
      *
-     * @see createKey()
+     * @see self::createKey()
      * @access public
-     * @param Integer $format
+     * @param int $format
      */
     function setPublicKeyFormat($format)
     {
@@ -1961,7 +2065,7 @@ class Crypt_RSA
      * decryption.  If $hash isn't supported, sha1 is used.
      *
      * @access public
-     * @param String $hash
+     * @param string $hash
      */
     function setHash($hash)
     {
@@ -1990,7 +2094,7 @@ class Crypt_RSA
      * best if Hash and MGFHash are set to the same thing this is not a requirement.
      *
      * @access public
-     * @param String $hash
+     * @param string $hash
      */
     function setMGFHash($hash)
     {
@@ -2019,7 +2123,7 @@ class Crypt_RSA
      *    of the hash function Hash) and 0.
      *
      * @access public
-     * @param Integer $format
+     * @param int $format
      */
     function setSaltLength($sLen)
     {
@@ -2033,8 +2137,8 @@ class Crypt_RSA
      *
      * @access private
      * @param Math_BigInteger $x
-     * @param Integer $xLen
-     * @return String
+     * @param int $xLen
+     * @return string
      */
     function _i2osp($x, $xLen)
     {
@@ -2052,7 +2156,7 @@ class Crypt_RSA
      * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
      *
      * @access private
-     * @param String $x
+     * @param string $x
      * @return Math_BigInteger
      */
     function _os2ip($x)
@@ -2071,8 +2175,14 @@ class Crypt_RSA
      */
     function _exponentiate($x)
     {
-        if (empty($this->primes) || empty($this->coefficients) || empty($this->exponents)) {
-            return $x->modPow($this->exponent, $this->modulus);
+        switch (true) {
+            case empty($this->primes):
+            case $this->primes[1]->equals($this->zero):
+            case empty($this->coefficients):
+            case $this->coefficients[2]->equals($this->zero):
+            case empty($this->exponents):
+            case $this->exponents[1]->equals($this->zero):
+                return $x->modPow($this->exponent, $this->modulus);
         }
 
         $num_primes = count($this->primes);
@@ -2146,7 +2256,7 @@ class Crypt_RSA
      * @access private
      * @param Math_BigInteger $x
      * @param Math_BigInteger $r
-     * @param Integer $i
+     * @param int $i
      * @return Math_BigInteger
      */
     function _blind($x, $r, $i)
@@ -2171,9 +2281,9 @@ class Crypt_RSA
      * Thanks for the heads up singpolyma!
      *
      * @access private
-     * @param String $x
-     * @param String $y
-     * @return Boolean
+     * @param string $x
+     * @param string $y
+     * @return bool
      */
     function _equals($x, $y)
     {
@@ -2267,9 +2377,9 @@ class Crypt_RSA
      * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.
      *
      * @access private
-     * @param String $mgfSeed
-     * @param Integer $mgfLen
-     * @return String
+     * @param string $mgfSeed
+     * @param int $mgfLen
+     * @return string
      */
     function _mgf1($mgfSeed, $maskLen)
     {
@@ -2292,9 +2402,9 @@ class Crypt_RSA
      * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}.
      *
      * @access private
-     * @param String $m
-     * @param String $l
-     * @return String
+     * @param string $m
+     * @param string $l
+     * @return string
      */
     function _rsaes_oaep_encrypt($m, $l = '')
     {
@@ -2355,9 +2465,9 @@ class Crypt_RSA
      *    this document.
      *
      * @access private
-     * @param String $c
-     * @param String $l
-     * @return String
+     * @param string $c
+     * @param string $l
+     * @return string
      */
     function _rsaes_oaep_decrypt($c, $l = '')
     {
@@ -2408,14 +2518,30 @@ class Crypt_RSA
         return substr($m, 1);
     }
 
+    /**
+     * Raw Encryption / Decryption
+     *
+     * Doesn't use padding and is not recommended.
+     *
+     * @access private
+     * @param string $m
+     * @return string
+     */
+    function _raw_encrypt($m)
+    {
+        $temp = $this->_os2ip($m);
+        $temp = $this->_rsaep($temp);
+        return  $this->_i2osp($temp, $this->k);
+    }
+
     /**
      * RSAES-PKCS1-V1_5-ENCRYPT
      *
      * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}.
      *
      * @access private
-     * @param String $m
-     * @return String
+     * @param string $m
+     * @return string
      */
     function _rsaes_pkcs1_v1_5_encrypt($m)
     {
@@ -2473,8 +2599,8 @@ class Crypt_RSA
      * not private key encrypted ciphertext's.
      *
      * @access private
-     * @param String $c
-     * @return String
+     * @param string $c
+     * @return string
      */
     function _rsaes_pkcs1_v1_5_decrypt($c)
     {
@@ -2522,8 +2648,8 @@ class Crypt_RSA
      * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}.
      *
      * @access private
-     * @param String $m
-     * @param Integer $emBits
+     * @param string $m
+     * @param int $emBits
      */
     function _emsa_pss_encode($m, $emBits)
     {
@@ -2531,7 +2657,7 @@ class Crypt_RSA
         // be output.
 
         $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8)
-        $sLen = $this->sLen == false ? $this->hLen : $this->sLen;
+        $sLen = $this->sLen !== null ? $this->sLen : $this->hLen;
 
         $mHash = $this->hash->hash($m);
         if ($emLen < $this->hLen + $sLen + 2) {
@@ -2558,10 +2684,10 @@ class Crypt_RSA
      * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}.
      *
      * @access private
-     * @param String $m
-     * @param String $em
-     * @param Integer $emBits
-     * @return String
+     * @param string $m
+     * @param string $em
+     * @param int $emBits
+     * @return string
      */
     function _emsa_pss_verify($m, $em, $emBits)
     {
@@ -2569,7 +2695,7 @@ class Crypt_RSA
         // be output.
 
         $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8);
-        $sLen = $this->sLen == false ? $this->hLen : $this->sLen;
+        $sLen = $this->sLen !== null ? $this->sLen : $this->hLen;
 
         $mHash = $this->hash->hash($m);
         if ($emLen < $this->hLen + $sLen + 2) {
@@ -2605,8 +2731,8 @@ class Crypt_RSA
      * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}.
      *
      * @access private
-     * @param String $m
-     * @return String
+     * @param string $m
+     * @return string
      */
     function _rsassa_pss_sign($m)
     {
@@ -2631,9 +2757,9 @@ class Crypt_RSA
      * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}.
      *
      * @access private
-     * @param String $m
-     * @param String $s
-     * @return String
+     * @param string $m
+     * @param string $s
+     * @return string
      */
     function _rsassa_pss_verify($m, $s)
     {
@@ -2671,9 +2797,9 @@ class Crypt_RSA
      * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
      *
      * @access private
-     * @param String $m
-     * @param Integer $emLen
-     * @return String
+     * @param string $m
+     * @param int $emLen
+     * @return string
      */
     function _emsa_pkcs1_v1_5_encode($m, $emLen)
     {
@@ -2723,8 +2849,8 @@ class Crypt_RSA
      * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}.
      *
      * @access private
-     * @param String $m
-     * @return String
+     * @param string $m
+     * @return string
      */
     function _rsassa_pkcs1_v1_5_sign($m)
     {
@@ -2753,8 +2879,8 @@ class Crypt_RSA
      * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}.
      *
      * @access private
-     * @param String $m
-     * @return String
+     * @param string $m
+     * @return string
      */
     function _rsassa_pkcs1_v1_5_verify($m, $s)
     {
@@ -2797,7 +2923,7 @@ class Crypt_RSA
      * Valid values include CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_ENCRYPTION_PKCS1.
      *
      * @access public
-     * @param Integer $mode
+     * @param int $mode
      */
     function setEncryptionMode($mode)
     {
@@ -2810,7 +2936,7 @@ class Crypt_RSA
      * Valid values include CRYPT_RSA_SIGNATURE_PSS and CRYPT_RSA_SIGNATURE_PKCS1
      *
      * @access public
-     * @param Integer $mode
+     * @param int $mode
      */
     function setSignatureMode($mode)
     {
@@ -2821,7 +2947,7 @@ class Crypt_RSA
      * Set public key comment.
      *
      * @access public
-     * @param String $comment
+     * @param string $comment
      */
     function setComment($comment)
     {
@@ -2832,7 +2958,7 @@ class Crypt_RSA
      * Get public key comment.
      *
      * @access public
-     * @return String
+     * @return string
      */
     function getComment()
     {
@@ -2846,14 +2972,21 @@ class Crypt_RSA
      * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will
      * be concatenated together.
      *
-     * @see decrypt()
+     * @see self::decrypt()
      * @access public
-     * @param String $plaintext
-     * @return String
+     * @param string $plaintext
+     * @return string
      */
     function encrypt($plaintext)
     {
         switch ($this->encryptionMode) {
+            case CRYPT_RSA_ENCRYPTION_NONE:
+                $plaintext = str_split($plaintext, $this->k);
+                $ciphertext = '';
+                foreach ($plaintext as $m) {
+                    $ciphertext.= $this->_raw_encrypt($m);
+                }
+                return $ciphertext;
             case CRYPT_RSA_ENCRYPTION_PKCS1:
                 $length = $this->k - 11;
                 if ($length <= 0) {
@@ -2885,10 +3018,10 @@ class Crypt_RSA
     /**
      * Decryption
      *
-     * @see encrypt()
+     * @see self::encrypt()
      * @access public
-     * @param String $plaintext
-     * @return String
+     * @param string $plaintext
+     * @return string
      */
     function decrypt($ciphertext)
     {
@@ -2902,6 +3035,9 @@ class Crypt_RSA
         $plaintext = '';
 
         switch ($this->encryptionMode) {
+            case CRYPT_RSA_ENCRYPTION_NONE:
+                $decrypt = '_raw_encrypt';
+                break;
             case CRYPT_RSA_ENCRYPTION_PKCS1:
                 $decrypt = '_rsaes_pkcs1_v1_5_decrypt';
                 break;
@@ -2924,10 +3060,10 @@ class Crypt_RSA
     /**
      * Create a signature
      *
-     * @see verify()
+     * @see self::verify()
      * @access public
-     * @param String $message
-     * @return String
+     * @param string $message
+     * @return string
      */
     function sign($message)
     {
@@ -2947,11 +3083,11 @@ class Crypt_RSA
     /**
      * Verifies a signature
      *
-     * @see sign()
+     * @see self::sign()
      * @access public
-     * @param String $message
-     * @param String $signature
-     * @return Boolean
+     * @param string $message
+     * @param string $signature
+     * @return bool
      */
     function verify($message, $signature)
     {
@@ -2972,8 +3108,8 @@ class Crypt_RSA
      * Extract raw BER from Base64 encoding
      *
      * @access private
-     * @param String $str
-     * @return String
+     * @param string $str
+     * @return string
      */
     function _extractBER($str)
     {
@@ -2986,7 +3122,7 @@ class Crypt_RSA
          * subject=/O=organization/OU=org unit/CN=common name
          * issuer=/O=organization/CN=common name
          */
-        $temp = preg_replace('#.*?^-+[^-]+-+#ms', '', $str, 1);
+        $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
         // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
         $temp = preg_replace('#-+[^-]+-+#', '', $temp);
         // remove new lines
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
index 918b97bf96c3e86123a85c58713e1adf331e0999..472d47c02739fb3168b9a5cf8582f3f167325771 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
@@ -61,16 +61,15 @@ if (!function_exists('crypt_random_string')) {
      * microoptimizations because this function has the potential of being called a huge number of times.
      * eg. for RSA key generation.
      *
-     * @param Integer $length
-     * @return String
+     * @param int $length
+     * @return string
      * @access public
      */
     function crypt_random_string($length)
     {
         if (CRYPT_RANDOM_IS_WINDOWS) {
-            // method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
-            // ie. class_alias is a function that was introduced in PHP 5.3
-            if (function_exists('mcrypt_create_iv') && function_exists('class_alias')) {
+            // method 1. prior to PHP 5.3, mcrypt_create_iv() would call rand() on windows
+            if (extension_loaded('mcrypt') && version_compare(PHP_VERSION, '5.3.0', '>=')) {
                 return mcrypt_create_iv($length);
             }
             // method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
@@ -86,12 +85,12 @@ if (!function_exists('crypt_random_string')) {
             // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80
             //
             // we're calling it, all the same, in the off chance that the mcrypt extension is not available
-            if (function_exists('openssl_random_pseudo_bytes') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
+            if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
                 return openssl_random_pseudo_bytes($length);
             }
         } else {
             // method 1. the fastest
-            if (function_exists('openssl_random_pseudo_bytes')) {
+            if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.0', '>=')) {
                 return openssl_random_pseudo_bytes($length);
             }
             // method 2
@@ -109,7 +108,7 @@ if (!function_exists('crypt_random_string')) {
             // surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're
             // not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
             // restrictions or some such
-            if (function_exists('mcrypt_create_iv')) {
+            if (extension_loaded('mcrypt')) {
                 return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
             }
         }
@@ -149,13 +148,13 @@ if (!function_exists('crypt_random_string')) {
             session_start();
 
             $v = $seed = $_SESSION['seed'] = pack('H*', sha1(
-                serialize($_SERVER) .
-                serialize($_POST) .
-                serialize($_GET) .
-                serialize($_COOKIE) .
-                serialize($GLOBALS) .
-                serialize($_SESSION) .
-                serialize($_OLD_SESSION)
+                (isset($_SERVER) ? phpseclib_safe_serialize($_SERVER) : '') .
+                (isset($_POST) ? phpseclib_safe_serialize($_POST) : '') .
+                (isset($_GET) ? phpseclib_safe_serialize($_GET) : '') .
+                (isset($_COOKIE) ? phpseclib_safe_serialize($_COOKIE) : '') .
+                phpseclib_safe_serialize($GLOBALS) .
+                phpseclib_safe_serialize($_SESSION) .
+                phpseclib_safe_serialize($_OLD_SESSION)
             ));
             if (!isset($_SESSION['count'])) {
                 $_SESSION['count'] = 0;
@@ -171,9 +170,9 @@ if (!function_exists('crypt_random_string')) {
                 ini_set('session.use_cookies', $old_use_cookies);
                 session_cache_limiter($old_session_cache_limiter);
             } else {
-               if ($_OLD_SESSION !== false) {
-                   $_SESSION = $_OLD_SESSION;
-                   unset($_OLD_SESSION);
+                if ($_OLD_SESSION !== false) {
+                    $_SESSION = $_OLD_SESSION;
+                    unset($_OLD_SESSION);
                 } else {
                     unset($_SESSION);
                 }
@@ -261,6 +260,41 @@ if (!function_exists('crypt_random_string')) {
     }
 }
 
+if (!function_exists('phpseclib_safe_serialize')) {
+    /**
+     * Safely serialize variables
+     *
+     * If a class has a private __sleep() method it'll give a fatal error on PHP 5.2 and earlier.
+     * PHP 5.3 will emit a warning.
+     *
+     * @param mixed $arr
+     * @access public
+     */
+    function phpseclib_safe_serialize(&$arr)
+    {
+        if (is_object($arr)) {
+            return '';
+        }
+        if (!is_array($arr)) {
+            return serialize($arr);
+        }
+        // prevent circular array recursion
+        if (isset($arr['__phpseclib_marker'])) {
+            return '';
+        }
+        $safearr = array();
+        $arr['__phpseclib_marker'] = true;
+        foreach (array_keys($arr) as $key) {
+            // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage
+            if ($key !== '__phpseclib_marker') {
+                $safearr[$key] = phpseclib_safe_serialize($arr[$key]);
+            }
+        }
+        unset($arr['__phpseclib_marker']);
+        return serialize($safearr);
+    }
+}
+
 if (!function_exists('phpseclib_resolve_include_path')) {
     /**
      * Resolve filename against the include path.
@@ -269,7 +303,7 @@ if (!function_exists('phpseclib_resolve_include_path')) {
      * PHP 5.3.2) with fallback implementation for earlier PHP versions.
      *
      * @param string $filename
-     * @return mixed Filename (string) on success, false otherwise.
+     * @return string|false
      * @access public
      */
     function phpseclib_resolve_include_path($filename)
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
index a131b26aefe4408d8b98874fdade565047b0b103..56bc4e9a9845bf3d32973e3b18411cc252b669f5 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
@@ -7,11 +7,11 @@
  *
  * PHP versions 4 and 5
  *
- * If {@link Crypt_Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits.  If
- * {@link Crypt_Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
- * {@link Crypt_Rijndael::setKey() setKey()}.  ie. if the key is 128-bits, the key length will be 128-bits.  If it's
+ * If {@link self::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits.  If
+ * {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
+ * {@link self::setKey() setKey()}.  ie. if the key is 128-bits, the key length will be 128-bits.  If it's
  * 136-bits it'll be null-padded to 192-bits and 192 bits will be the key length until
- * {@link Crypt_Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.
+ * {@link self::setKey() setKey()} is called, again, at which point, it'll be recalculated.
  *
  * Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length.  mcrypt, for example,
  * does not.  AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
@@ -81,8 +81,8 @@ if (!class_exists('Crypt_Base')) {
 
 /**#@+
  * @access public
- * @see Crypt_Rijndael::encrypt()
- * @see Crypt_Rijndael::decrypt()
+ * @see self::encrypt()
+ * @see self::decrypt()
  */
 /**
  * Encrypt / decrypt using the Counter mode.
@@ -118,20 +118,6 @@ define('CRYPT_RIJNDAEL_MODE_CFB', CRYPT_MODE_CFB);
 define('CRYPT_RIJNDAEL_MODE_OFB', CRYPT_MODE_OFB);
 /**#@-*/
 
-/**#@+
- * @access private
- * @see Crypt_Base::Crypt_Base()
- */
-/**
- * Toggles the internal implementation
- */
-define('CRYPT_RIJNDAEL_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
-/**
- * Toggles the mcrypt implementation
- */
-define('CRYPT_RIJNDAEL_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
-/**#@-*/
-
 /**
  * Pure-PHP implementation of Rijndael.
  *
@@ -141,21 +127,11 @@ define('CRYPT_RIJNDAEL_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
  */
 class Crypt_Rijndael extends Crypt_Base
 {
-    /**
-     * The default password key_size used by setPassword()
-     *
-     * @see Crypt_Base::password_key_size
-     * @see Crypt_Base::setPassword()
-     * @var Integer
-     * @access private
-     */
-    var $password_key_size = 16;
-
     /**
      * The namespace used by the cipher for its constants.
      *
      * @see Crypt_Base::const_namespace
-     * @var String
+     * @var string
      * @access private
      */
     var $const_namespace = 'RIJNDAEL';
@@ -163,15 +139,15 @@ class Crypt_Rijndael extends Crypt_Base
     /**
      * The mcrypt specific name of the cipher
      *
-     * Mcrypt is useable for 128/192/256-bit $block_size/$key_size. For 160/224 not.
+     * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not.
      * Crypt_Rijndael determines automatically whether mcrypt is useable
-     * or not for the current $block_size/$key_size.
+     * or not for the current $block_size/$key_length.
      * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly.
      *
      * @see Crypt_Base::cipher_name_mcrypt
      * @see Crypt_Base::engine
-     * @see _setupEngine()
-     * @var String
+     * @see self::isValidEngine()
+     * @var string
      * @access private
      */
     var $cipher_name_mcrypt = 'rijndael-128';
@@ -181,25 +157,16 @@ class Crypt_Rijndael extends Crypt_Base
      *
      * @see Crypt_Base::password_default_salt
      * @see Crypt_Base::setPassword()
-     * @var String
+     * @var string
      * @access private
      */
     var $password_default_salt = 'phpseclib';
 
-    /**
-     * Has the key length explicitly been set or should it be derived from the key, itself?
-     *
-     * @see setKeyLength()
-     * @var Boolean
-     * @access private
-     */
-    var $explicit_key_length = false;
-
     /**
      * The Key Schedule
      *
-     * @see _setup()
-     * @var Array
+     * @see self::_setup()
+     * @var array
      * @access private
      */
     var $w;
@@ -207,8 +174,8 @@ class Crypt_Rijndael extends Crypt_Base
     /**
      * The Inverse Key Schedule
      *
-     * @see _setup()
-     * @var Array
+     * @see self::_setup()
+     * @var array
      * @access private
      */
     var $dw;
@@ -216,35 +183,34 @@ class Crypt_Rijndael extends Crypt_Base
     /**
      * The Block Length divided by 32
      *
-     * @see setBlockLength()
-     * @var Integer
+     * @see self::setBlockLength()
+     * @var int
      * @access private
      * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4.  Exists in conjunction with $block_size
      *    because the encryption / decryption / key schedule creation requires this number and not $block_size.  We could
      *    derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
      *    of that, we'll just precompute it once.
-     *
      */
     var $Nb = 4;
 
     /**
-     * The Key Length
+     * The Key Length (in bytes)
      *
-     * @see setKeyLength()
-     * @var Integer
+     * @see self::setKeyLength()
+     * @var int
      * @access private
      * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16.  Exists in conjunction with $Nk
-     *    because the encryption / decryption / key schedule creation requires this number and not $key_size.  We could
-     *    derive this from $key_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
+     *    because the encryption / decryption / key schedule creation requires this number and not $key_length.  We could
+     *    derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
      *    of that, we'll just precompute it once.
      */
-    var $key_size = 16;
+    var $key_length = 16;
 
     /**
      * The Key Length divided by 32
      *
-     * @see setKeyLength()
-     * @var Integer
+     * @see self::setKeyLength()
+     * @var int
      * @access private
      * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
      */
@@ -253,7 +219,7 @@ class Crypt_Rijndael extends Crypt_Base
     /**
      * The Number of Rounds
      *
-     * @var Integer
+     * @var int
      * @access private
      * @internal The max value is 14, the min value is 10.
      */
@@ -262,7 +228,7 @@ class Crypt_Rijndael extends Crypt_Base
     /**
      * Shift offsets
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $c;
@@ -270,411 +236,11 @@ class Crypt_Rijndael extends Crypt_Base
     /**
      * Holds the last used key- and block_size information
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $kl;
 
-    /**
-     * Precomputed mixColumns table
-     *
-     * According to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
-     * precomputed tables can be used in the mixColumns phase.  in that example, they're assigned t0...t3, so
-     * those are the names we'll use.
-     *
-     * @see Crypt_Rijndael:_encryptBlock()
-     * @see Crypt_Rijndael:_decryptBlock()
-     * @var Array
-     * @access private
-     */
-    var $t0 = array(
-        0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554,
-        0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A,
-        0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B,
-        0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B,
-        0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F,
-        0x6834345C, 0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F,
-        0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5,
-        0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F,
-        0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB,
-        0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497,
-        0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED,
-        0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A,
-        0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594,
-        0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3,
-        0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504,
-        0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D,
-        0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739,
-        0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395,
-        0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883,
-        0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76,
-        0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4,
-        0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B,
-        0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0,
-        0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818,
-        0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651,
-        0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85,
-        0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12,
-        0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9,
-        0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7,
-        0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A,
-        0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, 0x844242C6, 0xD06868B8,
-        0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A
-    );
-
-    /**
-     * Precomputed mixColumns table
-     *
-     * @see Crypt_Rijndael:_encryptBlock()
-     * @see Crypt_Rijndael:_decryptBlock()
-     * @var Array
-     * @access private
-     */
-    var $t1 = array(
-        0xA5C66363, 0x84F87C7C, 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5,
-        0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, 0xE64DABAB, 0x9AEC7676,
-        0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0,
-        0xEC41ADAD, 0x67B3D4D4, 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0,
-        0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, 0x02F5F7F7, 0x4F83CCCC,
-        0x5C683434, 0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515,
-        0x0C080404, 0x5295C7C7, 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A,
-        0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, 0xCD7FB2B2, 0x9FEA7575,
-        0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0,
-        0xF6A45252, 0x4D763B3B, 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484,
-        0xF5A65353, 0x68B9D1D1, 0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, 0xC879B1B1, 0xEDB65B5B,
-        0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF,
-        0x6BBBD0D0, 0x2AC5EFEF, 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585,
-        0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, 0xBA259F9F, 0xE34BA8A8,
-        0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5,
-        0xDF63BCBC, 0xC177B6B6, 0x75AFDADA, 0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2,
-        0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, 0xCC884444, 0x392E1717,
-        0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373,
-        0xA0C06060, 0x98198181, 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888,
-        0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, 0x1D160B0B, 0x76ADDBDB,
-        0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A, 0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C,
-        0x5D9FC2C2, 0x6EBDD3D3, 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979,
-        0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, 0xD29C4E4E, 0xE049A9A9,
-        0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808,
-        0xD56FBABA, 0x88F07878, 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6,
-        0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B, 0xDC61BDBD, 0x860D8B8B, 0x850F8A8A,
-        0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E,
-        0xA3C26161, 0x5F6A3535, 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E,
-        0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, 0x89078E8E, 0xA7339494,
-        0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF,
-        0x8F038C8C, 0xF859A1A1, 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6, 0xC6844242, 0xB8D06868,
-        0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, 0xD66DBBBB, 0x3A2C1616
-    );
-
-    /**
-     * Precomputed mixColumns table
-     *
-     * @see Crypt_Rijndael:_encryptBlock()
-     * @see Crypt_Rijndael:_decryptBlock()
-     * @var Array
-     * @access private
-     */
-    var $t2 = array(
-        0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5,
-        0x30506030, 0x01030201, 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76,
-        0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, 0x47C98E47, 0xF00BFBF0,
-        0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0,
-        0xB7C275B7, 0xFD1CE1FD, 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC,
-        0x345C6834, 0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, 0x31536231, 0x153F2A15,
-        0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A,
-        0x07090E07, 0x12362412, 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75,
-        0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, 0x5AEEB45A, 0xA0FB5BA0,
-        0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384,
-        0x53F5A653, 0xD168B9D1, 0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B,
-        0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, 0x58E8B058, 0xCF4A85CF,
-        0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185,
-        0x45CF8A45, 0xF910E9F9, 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8,
-        0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, 0x38487038, 0xF504F1F5,
-        0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA, 0x21634221, 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2,
-        0xCD4C81CD, 0x0C14180C, 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17,
-        0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, 0x192B3219, 0x7395E673,
-        0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88,
-        0x46CA8C46, 0xEE29C7EE, 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB,
-        0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A, 0x49DB9249, 0x060A0C06, 0x246C4824, 0x5CE4B85C,
-        0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279,
-        0xE732D5E7, 0xC8438BC8, 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9,
-        0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, 0xAEE947AE, 0x08181008,
-        0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6,
-        0xE823CBE8, 0xDD7CA1DD, 0x749CE874, 0x1F213E1F, 0x4BDD964B, 0xBDDC61BD, 0x8B860D8B, 0x8A850F8A,
-        0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, 0xF601F7F6, 0x0E121C0E,
-        0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E,
-        0xE138D9E1, 0xF813EBF8, 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394,
-        0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, 0x28785028, 0xDF7AA5DF,
-        0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, 0xBFDA65BF, 0xE631D7E6, 0x42C68442, 0x68B8D068,
-        0x41C38241, 0x99B02999, 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16
-    );
-
-    /**
-     * Precomputed mixColumns table
-     *
-     * @see Crypt_Rijndael:_encryptBlock()
-     * @see Crypt_Rijndael:_decryptBlock()
-     * @var Array
-     * @access private
-     */
-    var $t3 = array(
-        0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
-        0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
-        0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
-        0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
-        0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
-        0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
-        0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
-        0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
-        0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
-        0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
-        0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
-        0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
-        0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
-        0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
-        0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
-        0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
-        0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
-        0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
-        0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
-        0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
-        0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
-        0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
-        0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
-        0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
-        0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
-        0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
-        0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
-        0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
-        0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
-        0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
-        0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
-        0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
-    );
-
-    /**
-     * Precomputed invMixColumns table
-     *
-     * @see Crypt_Rijndael:_encryptBlock()
-     * @see Crypt_Rijndael:_decryptBlock()
-     * @var Array
-     * @access private
-     */
-    var $dt0 = array(
-        0x51F4A750, 0x7E416553, 0x1A17A4C3, 0x3A275E96, 0x3BAB6BCB, 0x1F9D45F1, 0xACFA58AB, 0x4BE30393,
-        0x2030FA55, 0xAD766DF6, 0x88CC7691, 0xF5024C25, 0x4FE5D7FC, 0xC52ACBD7, 0x26354480, 0xB562A38F,
-        0xDEB15A49, 0x25BA1B67, 0x45EA0E98, 0x5DFEC0E1, 0xC32F7502, 0x814CF012, 0x8D4697A3, 0x6BD3F9C6,
-        0x038F5FE7, 0x15929C95, 0xBF6D7AEB, 0x955259DA, 0xD4BE832D, 0x587421D3, 0x49E06929, 0x8EC9C844,
-        0x75C2896A, 0xF48E7978, 0x99583E6B, 0x27B971DD, 0xBEE14FB6, 0xF088AD17, 0xC920AC66, 0x7DCE3AB4,
-        0x63DF4A18, 0xE51A3182, 0x97513360, 0x62537F45, 0xB16477E0, 0xBB6BAE84, 0xFE81A01C, 0xF9082B94,
-        0x70486858, 0x8F45FD19, 0x94DE6C87, 0x527BF8B7, 0xAB73D323, 0x724B02E2, 0xE31F8F57, 0x6655AB2A,
-        0xB2EB2807, 0x2FB5C203, 0x86C57B9A, 0xD33708A5, 0x302887F2, 0x23BFA5B2, 0x02036ABA, 0xED16825C,
-        0x8ACF1C2B, 0xA779B492, 0xF307F2F0, 0x4E69E2A1, 0x65DAF4CD, 0x0605BED5, 0xD134621F, 0xC4A6FE8A,
-        0x342E539D, 0xA2F355A0, 0x058AE132, 0xA4F6EB75, 0x0B83EC39, 0x4060EFAA, 0x5E719F06, 0xBD6E1051,
-        0x3E218AF9, 0x96DD063D, 0xDD3E05AE, 0x4DE6BD46, 0x91548DB5, 0x71C45D05, 0x0406D46F, 0x605015FF,
-        0x1998FB24, 0xD6BDE997, 0x894043CC, 0x67D99E77, 0xB0E842BD, 0x07898B88, 0xE7195B38, 0x79C8EEDB,
-        0xA17C0A47, 0x7C420FE9, 0xF8841EC9, 0x00000000, 0x09808683, 0x322BED48, 0x1E1170AC, 0x6C5A724E,
-        0xFD0EFFFB, 0x0F853856, 0x3DAED51E, 0x362D3927, 0x0A0FD964, 0x685CA621, 0x9B5B54D1, 0x24362E3A,
-        0x0C0A67B1, 0x9357E70F, 0xB4EE96D2, 0x1B9B919E, 0x80C0C54F, 0x61DC20A2, 0x5A774B69, 0x1C121A16,
-        0xE293BA0A, 0xC0A02AE5, 0x3C22E043, 0x121B171D, 0x0E090D0B, 0xF28BC7AD, 0x2DB6A8B9, 0x141EA9C8,
-        0x57F11985, 0xAF75074C, 0xEE99DDBB, 0xA37F60FD, 0xF701269F, 0x5C72F5BC, 0x44663BC5, 0x5BFB7E34,
-        0x8B432976, 0xCB23C6DC, 0xB6EDFC68, 0xB8E4F163, 0xD731DCCA, 0x42638510, 0x13972240, 0x84C61120,
-        0x854A247D, 0xD2BB3DF8, 0xAEF93211, 0xC729A16D, 0x1D9E2F4B, 0xDCB230F3, 0x0D8652EC, 0x77C1E3D0,
-        0x2BB3166C, 0xA970B999, 0x119448FA, 0x47E96422, 0xA8FC8CC4, 0xA0F03F1A, 0x567D2CD8, 0x223390EF,
-        0x87494EC7, 0xD938D1C1, 0x8CCAA2FE, 0x98D40B36, 0xA6F581CF, 0xA57ADE28, 0xDAB78E26, 0x3FADBFA4,
-        0x2C3A9DE4, 0x5078920D, 0x6A5FCC9B, 0x547E4662, 0xF68D13C2, 0x90D8B8E8, 0x2E39F75E, 0x82C3AFF5,
-        0x9F5D80BE, 0x69D0937C, 0x6FD52DA9, 0xCF2512B3, 0xC8AC993B, 0x10187DA7, 0xE89C636E, 0xDB3BBB7B,
-        0xCD267809, 0x6E5918F4, 0xEC9AB701, 0x834F9AA8, 0xE6956E65, 0xAAFFE67E, 0x21BCCF08, 0xEF15E8E6,
-        0xBAE79BD9, 0x4A6F36CE, 0xEA9F09D4, 0x29B07CD6, 0x31A4B2AF, 0x2A3F2331, 0xC6A59430, 0x35A266C0,
-        0x744EBC37, 0xFC82CAA6, 0xE090D0B0, 0x33A7D815, 0xF104984A, 0x41ECDAF7, 0x7FCD500E, 0x1791F62F,
-        0x764DD68D, 0x43EFB04D, 0xCCAA4D54, 0xE49604DF, 0x9ED1B5E3, 0x4C6A881B, 0xC12C1FB8, 0x4665517F,
-        0x9D5EEA04, 0x018C355D, 0xFA877473, 0xFB0B412E, 0xB3671D5A, 0x92DBD252, 0xE9105633, 0x6DD64713,
-        0x9AD7618C, 0x37A10C7A, 0x59F8148E, 0xEB133C89, 0xCEA927EE, 0xB761C935, 0xE11CE5ED, 0x7A47B13C,
-        0x9CD2DF59, 0x55F2733F, 0x1814CE79, 0x73C737BF, 0x53F7CDEA, 0x5FFDAA5B, 0xDF3D6F14, 0x7844DB86,
-        0xCAAFF381, 0xB968C43E, 0x3824342C, 0xC2A3405F, 0x161DC372, 0xBCE2250C, 0x283C498B, 0xFF0D9541,
-        0x39A80171, 0x080CB3DE, 0xD8B4E49C, 0x6456C190, 0x7BCB8461, 0xD532B670, 0x486C5C74, 0xD0B85742
-    );
-
-    /**
-     * Precomputed invMixColumns table
-     *
-     * @see Crypt_Rijndael:_encryptBlock()
-     * @see Crypt_Rijndael:_decryptBlock()
-     * @var Array
-     * @access private
-     */
-    var $dt1 = array(
-        0x5051F4A7, 0x537E4165, 0xC31A17A4, 0x963A275E, 0xCB3BAB6B, 0xF11F9D45, 0xABACFA58, 0x934BE303,
-        0x552030FA, 0xF6AD766D, 0x9188CC76, 0x25F5024C, 0xFC4FE5D7, 0xD7C52ACB, 0x80263544, 0x8FB562A3,
-        0x49DEB15A, 0x6725BA1B, 0x9845EA0E, 0xE15DFEC0, 0x02C32F75, 0x12814CF0, 0xA38D4697, 0xC66BD3F9,
-        0xE7038F5F, 0x9515929C, 0xEBBF6D7A, 0xDA955259, 0x2DD4BE83, 0xD3587421, 0x2949E069, 0x448EC9C8,
-        0x6A75C289, 0x78F48E79, 0x6B99583E, 0xDD27B971, 0xB6BEE14F, 0x17F088AD, 0x66C920AC, 0xB47DCE3A,
-        0x1863DF4A, 0x82E51A31, 0x60975133, 0x4562537F, 0xE0B16477, 0x84BB6BAE, 0x1CFE81A0, 0x94F9082B,
-        0x58704868, 0x198F45FD, 0x8794DE6C, 0xB7527BF8, 0x23AB73D3, 0xE2724B02, 0x57E31F8F, 0x2A6655AB,
-        0x07B2EB28, 0x032FB5C2, 0x9A86C57B, 0xA5D33708, 0xF2302887, 0xB223BFA5, 0xBA02036A, 0x5CED1682,
-        0x2B8ACF1C, 0x92A779B4, 0xF0F307F2, 0xA14E69E2, 0xCD65DAF4, 0xD50605BE, 0x1FD13462, 0x8AC4A6FE,
-        0x9D342E53, 0xA0A2F355, 0x32058AE1, 0x75A4F6EB, 0x390B83EC, 0xAA4060EF, 0x065E719F, 0x51BD6E10,
-        0xF93E218A, 0x3D96DD06, 0xAEDD3E05, 0x464DE6BD, 0xB591548D, 0x0571C45D, 0x6F0406D4, 0xFF605015,
-        0x241998FB, 0x97D6BDE9, 0xCC894043, 0x7767D99E, 0xBDB0E842, 0x8807898B, 0x38E7195B, 0xDB79C8EE,
-        0x47A17C0A, 0xE97C420F, 0xC9F8841E, 0x00000000, 0x83098086, 0x48322BED, 0xAC1E1170, 0x4E6C5A72,
-        0xFBFD0EFF, 0x560F8538, 0x1E3DAED5, 0x27362D39, 0x640A0FD9, 0x21685CA6, 0xD19B5B54, 0x3A24362E,
-        0xB10C0A67, 0x0F9357E7, 0xD2B4EE96, 0x9E1B9B91, 0x4F80C0C5, 0xA261DC20, 0x695A774B, 0x161C121A,
-        0x0AE293BA, 0xE5C0A02A, 0x433C22E0, 0x1D121B17, 0x0B0E090D, 0xADF28BC7, 0xB92DB6A8, 0xC8141EA9,
-        0x8557F119, 0x4CAF7507, 0xBBEE99DD, 0xFDA37F60, 0x9FF70126, 0xBC5C72F5, 0xC544663B, 0x345BFB7E,
-        0x768B4329, 0xDCCB23C6, 0x68B6EDFC, 0x63B8E4F1, 0xCAD731DC, 0x10426385, 0x40139722, 0x2084C611,
-        0x7D854A24, 0xF8D2BB3D, 0x11AEF932, 0x6DC729A1, 0x4B1D9E2F, 0xF3DCB230, 0xEC0D8652, 0xD077C1E3,
-        0x6C2BB316, 0x99A970B9, 0xFA119448, 0x2247E964, 0xC4A8FC8C, 0x1AA0F03F, 0xD8567D2C, 0xEF223390,
-        0xC787494E, 0xC1D938D1, 0xFE8CCAA2, 0x3698D40B, 0xCFA6F581, 0x28A57ADE, 0x26DAB78E, 0xA43FADBF,
-        0xE42C3A9D, 0x0D507892, 0x9B6A5FCC, 0x62547E46, 0xC2F68D13, 0xE890D8B8, 0x5E2E39F7, 0xF582C3AF,
-        0xBE9F5D80, 0x7C69D093, 0xA96FD52D, 0xB3CF2512, 0x3BC8AC99, 0xA710187D, 0x6EE89C63, 0x7BDB3BBB,
-        0x09CD2678, 0xF46E5918, 0x01EC9AB7, 0xA8834F9A, 0x65E6956E, 0x7EAAFFE6, 0x0821BCCF, 0xE6EF15E8,
-        0xD9BAE79B, 0xCE4A6F36, 0xD4EA9F09, 0xD629B07C, 0xAF31A4B2, 0x312A3F23, 0x30C6A594, 0xC035A266,
-        0x37744EBC, 0xA6FC82CA, 0xB0E090D0, 0x1533A7D8, 0x4AF10498, 0xF741ECDA, 0x0E7FCD50, 0x2F1791F6,
-        0x8D764DD6, 0x4D43EFB0, 0x54CCAA4D, 0xDFE49604, 0xE39ED1B5, 0x1B4C6A88, 0xB8C12C1F, 0x7F466551,
-        0x049D5EEA, 0x5D018C35, 0x73FA8774, 0x2EFB0B41, 0x5AB3671D, 0x5292DBD2, 0x33E91056, 0x136DD647,
-        0x8C9AD761, 0x7A37A10C, 0x8E59F814, 0x89EB133C, 0xEECEA927, 0x35B761C9, 0xEDE11CE5, 0x3C7A47B1,
-        0x599CD2DF, 0x3F55F273, 0x791814CE, 0xBF73C737, 0xEA53F7CD, 0x5B5FFDAA, 0x14DF3D6F, 0x867844DB,
-        0x81CAAFF3, 0x3EB968C4, 0x2C382434, 0x5FC2A340, 0x72161DC3, 0x0CBCE225, 0x8B283C49, 0x41FF0D95,
-        0x7139A801, 0xDE080CB3, 0x9CD8B4E4, 0x906456C1, 0x617BCB84, 0x70D532B6, 0x74486C5C, 0x42D0B857
-    );
-
-    /**
-     * Precomputed invMixColumns table
-     *
-     * @see Crypt_Rijndael:_encryptBlock()
-     * @see Crypt_Rijndael:_decryptBlock()
-     * @var Array
-     * @access private
-     */
-    var $dt2 = array(
-        0xA75051F4, 0x65537E41, 0xA4C31A17, 0x5E963A27, 0x6BCB3BAB, 0x45F11F9D, 0x58ABACFA, 0x03934BE3,
-        0xFA552030, 0x6DF6AD76, 0x769188CC, 0x4C25F502, 0xD7FC4FE5, 0xCBD7C52A, 0x44802635, 0xA38FB562,
-        0x5A49DEB1, 0x1B6725BA, 0x0E9845EA, 0xC0E15DFE, 0x7502C32F, 0xF012814C, 0x97A38D46, 0xF9C66BD3,
-        0x5FE7038F, 0x9C951592, 0x7AEBBF6D, 0x59DA9552, 0x832DD4BE, 0x21D35874, 0x692949E0, 0xC8448EC9,
-        0x896A75C2, 0x7978F48E, 0x3E6B9958, 0x71DD27B9, 0x4FB6BEE1, 0xAD17F088, 0xAC66C920, 0x3AB47DCE,
-        0x4A1863DF, 0x3182E51A, 0x33609751, 0x7F456253, 0x77E0B164, 0xAE84BB6B, 0xA01CFE81, 0x2B94F908,
-        0x68587048, 0xFD198F45, 0x6C8794DE, 0xF8B7527B, 0xD323AB73, 0x02E2724B, 0x8F57E31F, 0xAB2A6655,
-        0x2807B2EB, 0xC2032FB5, 0x7B9A86C5, 0x08A5D337, 0x87F23028, 0xA5B223BF, 0x6ABA0203, 0x825CED16,
-        0x1C2B8ACF, 0xB492A779, 0xF2F0F307, 0xE2A14E69, 0xF4CD65DA, 0xBED50605, 0x621FD134, 0xFE8AC4A6,
-        0x539D342E, 0x55A0A2F3, 0xE132058A, 0xEB75A4F6, 0xEC390B83, 0xEFAA4060, 0x9F065E71, 0x1051BD6E,
-        0x8AF93E21, 0x063D96DD, 0x05AEDD3E, 0xBD464DE6, 0x8DB59154, 0x5D0571C4, 0xD46F0406, 0x15FF6050,
-        0xFB241998, 0xE997D6BD, 0x43CC8940, 0x9E7767D9, 0x42BDB0E8, 0x8B880789, 0x5B38E719, 0xEEDB79C8,
-        0x0A47A17C, 0x0FE97C42, 0x1EC9F884, 0x00000000, 0x86830980, 0xED48322B, 0x70AC1E11, 0x724E6C5A,
-        0xFFFBFD0E, 0x38560F85, 0xD51E3DAE, 0x3927362D, 0xD9640A0F, 0xA621685C, 0x54D19B5B, 0x2E3A2436,
-        0x67B10C0A, 0xE70F9357, 0x96D2B4EE, 0x919E1B9B, 0xC54F80C0, 0x20A261DC, 0x4B695A77, 0x1A161C12,
-        0xBA0AE293, 0x2AE5C0A0, 0xE0433C22, 0x171D121B, 0x0D0B0E09, 0xC7ADF28B, 0xA8B92DB6, 0xA9C8141E,
-        0x198557F1, 0x074CAF75, 0xDDBBEE99, 0x60FDA37F, 0x269FF701, 0xF5BC5C72, 0x3BC54466, 0x7E345BFB,
-        0x29768B43, 0xC6DCCB23, 0xFC68B6ED, 0xF163B8E4, 0xDCCAD731, 0x85104263, 0x22401397, 0x112084C6,
-        0x247D854A, 0x3DF8D2BB, 0x3211AEF9, 0xA16DC729, 0x2F4B1D9E, 0x30F3DCB2, 0x52EC0D86, 0xE3D077C1,
-        0x166C2BB3, 0xB999A970, 0x48FA1194, 0x642247E9, 0x8CC4A8FC, 0x3F1AA0F0, 0x2CD8567D, 0x90EF2233,
-        0x4EC78749, 0xD1C1D938, 0xA2FE8CCA, 0x0B3698D4, 0x81CFA6F5, 0xDE28A57A, 0x8E26DAB7, 0xBFA43FAD,
-        0x9DE42C3A, 0x920D5078, 0xCC9B6A5F, 0x4662547E, 0x13C2F68D, 0xB8E890D8, 0xF75E2E39, 0xAFF582C3,
-        0x80BE9F5D, 0x937C69D0, 0x2DA96FD5, 0x12B3CF25, 0x993BC8AC, 0x7DA71018, 0x636EE89C, 0xBB7BDB3B,
-        0x7809CD26, 0x18F46E59, 0xB701EC9A, 0x9AA8834F, 0x6E65E695, 0xE67EAAFF, 0xCF0821BC, 0xE8E6EF15,
-        0x9BD9BAE7, 0x36CE4A6F, 0x09D4EA9F, 0x7CD629B0, 0xB2AF31A4, 0x23312A3F, 0x9430C6A5, 0x66C035A2,
-        0xBC37744E, 0xCAA6FC82, 0xD0B0E090, 0xD81533A7, 0x984AF104, 0xDAF741EC, 0x500E7FCD, 0xF62F1791,
-        0xD68D764D, 0xB04D43EF, 0x4D54CCAA, 0x04DFE496, 0xB5E39ED1, 0x881B4C6A, 0x1FB8C12C, 0x517F4665,
-        0xEA049D5E, 0x355D018C, 0x7473FA87, 0x412EFB0B, 0x1D5AB367, 0xD25292DB, 0x5633E910, 0x47136DD6,
-        0x618C9AD7, 0x0C7A37A1, 0x148E59F8, 0x3C89EB13, 0x27EECEA9, 0xC935B761, 0xE5EDE11C, 0xB13C7A47,
-        0xDF599CD2, 0x733F55F2, 0xCE791814, 0x37BF73C7, 0xCDEA53F7, 0xAA5B5FFD, 0x6F14DF3D, 0xDB867844,
-        0xF381CAAF, 0xC43EB968, 0x342C3824, 0x405FC2A3, 0xC372161D, 0x250CBCE2, 0x498B283C, 0x9541FF0D,
-        0x017139A8, 0xB3DE080C, 0xE49CD8B4, 0xC1906456, 0x84617BCB, 0xB670D532, 0x5C74486C, 0x5742D0B8
-    );
-
-    /**
-     * Precomputed invMixColumns table
-     *
-     * @see Crypt_Rijndael:_encryptBlock()
-     * @see Crypt_Rijndael:_decryptBlock()
-     * @var Array
-     * @access private
-     */
-    var $dt3 = array(
-        0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
-        0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
-        0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
-        0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
-        0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
-        0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
-        0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
-        0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
-        0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
-        0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
-        0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
-        0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
-        0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
-        0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
-        0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
-        0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
-        0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
-        0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
-        0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
-        0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
-        0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
-        0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
-        0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
-        0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
-        0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
-        0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
-        0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
-        0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
-        0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
-        0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
-        0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
-        0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
-    );
-
-    /**
-     * The SubByte S-Box
-     *
-     * @see Crypt_Rijndael::_encryptBlock()
-     * @var Array
-     * @access private
-     */
-    var $sbox = array(
-        0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
-        0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
-        0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
-        0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
-        0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
-        0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
-        0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
-        0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
-        0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
-        0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
-        0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
-        0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
-        0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
-        0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
-        0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
-        0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
-    );
-
-    /**
-     * The inverse SubByte S-Box
-     *
-     * @see Crypt_Rijndael::_decryptBlock()
-     * @var Array
-     * @access private
-     */
-    var $isbox = array(
-        0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
-        0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
-        0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
-        0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
-        0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
-        0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
-        0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
-        0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
-        0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
-        0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
-        0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
-        0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
-        0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
-        0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
-        0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
-        0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
-    );
-
     /**
      * Sets the key.
      *
@@ -688,14 +254,12 @@ class Crypt_Rijndael extends Crypt_Base
      * Note: 160/224-bit keys must explicitly set by setKeyLength(), otherwise they will be round/pad up to 192/256 bits.
      *
      * @see Crypt_Base:setKey()
-     * @see setKeyLength()
+     * @see self::setKeyLength()
      * @access public
-     * @param String $key
+     * @param string $key
      */
     function setKey($key)
     {
-        parent::setKey($key);
-
         if (!$this->explicit_key_length) {
             $length = strlen($key);
             switch (true) {
@@ -714,8 +278,8 @@ class Crypt_Rijndael extends Crypt_Base
                 default:
                     $this->key_size = 32;
             }
-            $this->_setupEngine();
         }
+        parent::setKey($key);
     }
 
     /**
@@ -736,30 +300,28 @@ class Crypt_Rijndael extends Crypt_Base
      *             This results then in slower encryption.
      *
      * @access public
-     * @param Integer $length
+     * @param int $length
      */
     function setKeyLength($length)
     {
         switch (true) {
-            case $length == 160:
-                $this->key_size = 20;
-                break;
-            case $length == 224:
-                $this->key_size = 28;
-                break;
             case $length <= 128:
-                $this->key_size = 16;
+                $this->key_length = 16;
+                break;
+            case $length <= 160:
+                $this->key_length = 20;
                 break;
             case $length <= 192:
-                $this->key_size = 24;
+                $this->key_length = 24;
+                break;
+            case $length <= 224:
+                $this->key_length = 28;
                 break;
             default:
-                $this->key_size = 32;
+                $this->key_length = 32;
         }
 
-        $this->explicit_key_length = true;
-        $this->changed = true;
-        $this->_setupEngine();
+        parent::setKeyLength($length);
     }
 
     /**
@@ -769,110 +331,71 @@ class Crypt_Rijndael extends Crypt_Base
      * 128.  If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
      *
      * @access public
-     * @param Integer $length
+     * @param int $length
      */
     function setBlockLength($length)
     {
         $length >>= 5;
         if ($length > 8) {
             $length = 8;
-        } else if ($length < 4) {
+        } elseif ($length < 4) {
             $length = 4;
         }
         $this->Nb = $length;
         $this->block_size = $length << 2;
         $this->changed = true;
-        $this->_setupEngine();
+        $this->_setEngine();
     }
 
     /**
-     * Setup the fastest possible $engine
+     * Test for engine validity
      *
-     * Determines if the mcrypt (MODE_MCRYPT) $engine available
-     * and usable for the current $block_size and $key_size.
+     * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
      *
-     * If not, the slower MODE_INTERNAL $engine will be set.
-     *
-     * @see setKey()
-     * @see setKeyLength()
-     * @see setBlockLength()
-     * @access private
+     * @see Crypt_Base::Crypt_Base()
+     * @param int $engine
+     * @access public
+     * @return bool
      */
-    function _setupEngine()
+    function isValidEngine($engine)
     {
-        if (constant('CRYPT_' . $this->const_namespace . '_MODE') == CRYPT_MODE_INTERNAL) {
-            // No mcrypt support at all for rijndael
-            return;
-        }
-
-        // The required mcrypt module name for the current $block_size of rijndael
-        $cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
-
-        // Determining the availibility/usability of $cipher_name_mcrypt
-        switch (true) {
-            case $this->key_size % 8: // mcrypt is not usable for 160/224-bit keys, only for 128/192/256-bit keys
-            case !in_array($cipher_name_mcrypt, mcrypt_list_algorithms()): // $cipher_name_mcrypt is not available for the current $block_size
-                $engine = CRYPT_MODE_INTERNAL;
+        switch ($engine) {
+            case CRYPT_ENGINE_OPENSSL:
+                if ($this->block_size != 16) {
+                    return false;
+                }
+                $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb';
+                $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode();
                 break;
-            default:
-                $engine = CRYPT_MODE_MCRYPT;
-        }
-
-        if ($this->engine == $engine && $this->cipher_name_mcrypt == $cipher_name_mcrypt) {
-            // allready set, so we not unnecessary close $this->enmcrypt/demcrypt/ecb
-            return;
-        }
-
-        // Set the $engine
-        $this->engine = $engine;
-        $this->cipher_name_mcrypt = $cipher_name_mcrypt;
-
-        if ($this->enmcrypt) {
-            // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed,
-            // (re)open them with the module named in $this->cipher_name_mcrypt
-            mcrypt_module_close($this->enmcrypt);
-            mcrypt_module_close($this->demcrypt);
-            $this->enmcrypt = null;
-            $this->demcrypt = null;
-
-            if ($this->ecb) {
-                mcrypt_module_close($this->ecb);
-                $this->ecb = null;
-            }
+            case CRYPT_ENGINE_MCRYPT:
+                $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
+                if ($this->key_length % 8) { // is it a 160/224-bit key?
+                    // mcrypt is not usable for them, only for 128/192/256-bit keys
+                    return false;
+                }
         }
-    }
 
-    /**
-     * Setup the CRYPT_MODE_MCRYPT $engine
-     *
-     * @see Crypt_Base::_setupMcrypt()
-     * @access private
-     */
-    function _setupMcrypt()
-    {
-        $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, "\0");
-        parent::_setupMcrypt();
+        return parent::isValidEngine($engine);
     }
 
     /**
      * Encrypts a block
      *
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
      */
     function _encryptBlock($in)
     {
-        static $t0, $t1, $t2, $t3, $sbox;
-        if (!$t0) {
-            for ($i = 0; $i < 256; ++$i) {
-                $t0[] = (int)$this->t0[$i];
-                $t1[] = (int)$this->t1[$i];
-                $t2[] = (int)$this->t2[$i];
-                $t3[] = (int)$this->t3[$i];
-                $sbox[] = (int)$this->sbox[$i];
-            }
+        static $tables;
+        if (empty($tables)) {
+            $tables = &$this->_getTables();
         }
+        $t0   = $tables[0];
+        $t1   = $tables[1];
+        $t2   = $tables[2];
+        $t3   = $tables[3];
+        $sbox = $tables[4];
 
         $state = array();
         $words = unpack('N*', $in);
@@ -883,9 +406,9 @@ class Crypt_Rijndael extends Crypt_Base
         $Nr = $this->Nr;
 
         // addRoundKey
-        $i = -1;
+        $wc = $Nb - 1;
         foreach ($words as $word) {
-            $state[] = $word ^ $w[0][++$i];
+            $state[] = $word ^ $w[++$wc];
         }
 
         // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components -
@@ -908,7 +431,7 @@ class Crypt_Rijndael extends Crypt_Base
                             $t1[$state[$j] >> 16 & 0x000000FF] ^
                             $t2[$state[$k] >>  8 & 0x000000FF] ^
                             $t3[$state[$l]       & 0x000000FF] ^
-                            $w[$round][$i];
+                            $w[++$wc];
                 ++$i;
                 $j = ($j + 1) % $Nb;
                 $k = ($k + 1) % $Nb;
@@ -935,7 +458,7 @@ class Crypt_Rijndael extends Crypt_Base
                         ($state[$j] & 0x00FF0000) ^
                         ($state[$k] & 0x0000FF00) ^
                         ($state[$l] & 0x000000FF) ^
-                         $w[$Nr][$i];
+                         $w[$i];
             ++$i;
             $j = ($j + 1) % $Nb;
             $k = ($k + 1) % $Nb;
@@ -960,21 +483,20 @@ class Crypt_Rijndael extends Crypt_Base
      * Decrypts a block
      *
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
      */
     function _decryptBlock($in)
     {
-        static $dt0, $dt1, $dt2, $dt3, $isbox;
-        if (!$dt0) {
-            for ($i = 0; $i < 256; ++$i) {
-                $dt0[] = (int)$this->dt0[$i];
-                $dt1[] = (int)$this->dt1[$i];
-                $dt2[] = (int)$this->dt2[$i];
-                $dt3[] = (int)$this->dt3[$i];
-                $isbox[] = (int)$this->isbox[$i];
-            }
+        static $invtables;
+        if (empty($invtables)) {
+            $invtables = &$this->_getInvTables();
         }
+        $dt0   = $invtables[0];
+        $dt1   = $invtables[1];
+        $dt2   = $invtables[2];
+        $dt3   = $invtables[3];
+        $isbox = $invtables[4];
 
         $state = array();
         $words = unpack('N*', $in);
@@ -985,9 +507,9 @@ class Crypt_Rijndael extends Crypt_Base
         $Nr = $this->Nr;
 
         // addRoundKey
-        $i = -1;
+        $wc = $Nb - 1;
         foreach ($words as $word) {
-            $state[] = $word ^ $dw[$Nr][++$i];
+            $state[] = $word ^ $dw[++$wc];
         }
 
         $temp = array();
@@ -1002,7 +524,7 @@ class Crypt_Rijndael extends Crypt_Base
                             $dt1[$state[$j] >> 16 & 0x000000FF] ^
                             $dt2[$state[$k] >>  8 & 0x000000FF] ^
                             $dt3[$state[$l]       & 0x000000FF] ^
-                            $dw[$round][$i];
+                            $dw[++$wc];
                 ++$i;
                 $j = ($j + 1) % $Nb;
                 $k = ($k + 1) % $Nb;
@@ -1023,10 +545,10 @@ class Crypt_Rijndael extends Crypt_Base
                     ($state[$k] & 0x0000FF00) |
                     ($state[$l] & 0x000000FF);
 
-            $temp[$i] = $dw[0][$i] ^ ($isbox[$word       & 0x000000FF]        |
-                                     ($isbox[$word >>  8 & 0x000000FF] <<  8) |
-                                     ($isbox[$word >> 16 & 0x000000FF] << 16) |
-                                     ($isbox[$word >> 24 & 0x000000FF] << 24));
+            $temp[$i] = $dw[$i] ^ ($isbox[$word       & 0x000000FF]        |
+                                  ($isbox[$word >>  8 & 0x000000FF] <<  8) |
+                                  ($isbox[$word >> 16 & 0x000000FF] << 16) |
+                                  ($isbox[$word >> 24 & 0x000000FF] << 24));
             ++$i;
             $j = ($j + 1) % $Nb;
             $k = ($k + 1) % $Nb;
@@ -1066,15 +588,13 @@ class Crypt_Rijndael extends Crypt_Base
             0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
         );
 
-        $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, "\0");
-
-        if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_size === $this->kl['key_size'] && $this->block_size === $this->kl['block_size']) {
+        if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) {
             // already expanded
             return;
         }
-        $this->kl = array('key' => $this->key, 'key_size' => $this->key_size, 'block_size' => $this->block_size);
+        $this->kl = array('key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size);
 
-        $this->Nk = $this->key_size >> 2;
+        $this->Nk = $this->key_length >> 2;
         // see Rijndael-ammended.pdf#page=44
         $this->Nr = max($this->Nk, $this->Nb) + 6;
 
@@ -1107,7 +627,7 @@ class Crypt_Rijndael extends Crypt_Base
                 // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
                 $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
                 $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
-            } else if ($this->Nk > 6 && $i % $this->Nk == 4) {
+            } elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
                 $temp = $this->_subWord($temp);
             }
             $w[$i] = $w[$i - $this->Nk] ^ $temp;
@@ -1120,6 +640,7 @@ class Crypt_Rijndael extends Crypt_Base
         //        1. Apply the Key Expansion.
         //        2. Apply InvMixColumn to all Round Keys except the first and the last one."
         // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
+        list($dt0, $dt1, $dt2, $dt3) = $this->_getInvTables();
         $temp = $this->w = $this->dw = array();
         for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
             if ($col == $this->Nb) {
@@ -1130,10 +651,10 @@ class Crypt_Rijndael extends Crypt_Base
                     $j = 0;
                     while ($j < $this->Nb) {
                         $dw = $this->_subWord($this->w[$row][$j]);
-                        $temp[$j] = $this->dt0[$dw >> 24 & 0x000000FF] ^
-                                    $this->dt1[$dw >> 16 & 0x000000FF] ^
-                                    $this->dt2[$dw >>  8 & 0x000000FF] ^
-                                    $this->dt3[$dw       & 0x000000FF];
+                        $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^
+                                    $dt1[$dw >> 16 & 0x000000FF] ^
+                                    $dt2[$dw >>  8 & 0x000000FF] ^
+                                    $dt3[$dw       & 0x000000FF];
                         $j++;
                     }
                     $this->dw[$row] = $temp;
@@ -1147,31 +668,32 @@ class Crypt_Rijndael extends Crypt_Base
 
         $this->dw[$row] = $this->w[$row];
 
-        // In case of $this->use_inline_crypt === true we have to use 1-dim key arrays (both ascending)
-        if ($this->use_inline_crypt) {
-            $this->dw = array_reverse($this->dw);
-            $w  = array_pop($this->w);
-            $dw = array_pop($this->dw);
-            foreach ($this->w as $r => $wr) {
-                foreach ($wr as $c => $wc) {
-                    $w[]  = $wc;
-                    $dw[] = $this->dw[$r][$c];
-                }
+        // Converting to 1-dim key arrays (both ascending)
+        $this->dw = array_reverse($this->dw);
+        $w  = array_pop($this->w);
+        $dw = array_pop($this->dw);
+        foreach ($this->w as $r => $wr) {
+            foreach ($wr as $c => $wc) {
+                $w[]  = $wc;
+                $dw[] = $this->dw[$r][$c];
             }
-            $this->w  = $w;
-            $this->dw = $dw;
         }
+        $this->w  = $w;
+        $this->dw = $dw;
     }
 
     /**
      * Performs S-Box substitutions
      *
      * @access private
-     * @param Integer $word
+     * @param int $word
      */
     function _subWord($word)
     {
-        $sbox = $this->sbox;
+        static $sbox;
+        if (empty($sbox)) {
+            list(, , , , $sbox) = $this->_getTables();
+        }
 
         return  $sbox[$word       & 0x000000FF]        |
                ($sbox[$word >>  8 & 0x000000FF] <<  8) |
@@ -1179,6 +701,179 @@ class Crypt_Rijndael extends Crypt_Base
                ($sbox[$word >> 24 & 0x000000FF] << 24);
     }
 
+    /**
+     * Provides the mixColumns and sboxes tables
+     *
+     * @see Crypt_Rijndael:_encryptBlock()
+     * @see Crypt_Rijndael:_setupInlineCrypt()
+     * @see Crypt_Rijndael:_subWord()
+     * @access private
+     * @return array &$tables
+     */
+    function &_getTables()
+    {
+        static $tables;
+        if (empty($tables)) {
+            // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
+            // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
+            // those are the names we'll use.
+            $t3 = array_map('intval', array(
+                // with array_map('intval', ...) we ensure we have only int's and not
+                // some slower floats converted by php automatically on high values
+                0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
+                0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
+                0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
+                0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
+                0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
+                0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
+                0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
+                0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
+                0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
+                0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
+                0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
+                0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
+                0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
+                0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
+                0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
+                0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
+                0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
+                0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
+                0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
+                0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
+                0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
+                0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
+                0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
+                0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
+                0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
+                0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
+                0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
+                0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
+                0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
+                0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
+                0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
+                0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
+            ));
+
+            foreach ($t3 as $t3i) {
+                $t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >>  8) & 0x00FFFFFF);
+                $t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF);
+                $t2[] = (($t3i <<  8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF);
+            }
+
+            $tables = array(
+                // The Precomputed mixColumns tables t0 - t3
+                $t0,
+                $t1,
+                $t2,
+                $t3,
+                // The SubByte S-Box
+                array(
+                    0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+                    0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+                    0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+                    0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+                    0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+                    0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+                    0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+                    0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+                    0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+                    0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+                    0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+                    0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+                    0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+                    0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+                    0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+                    0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+                )
+            );
+        }
+        return $tables;
+    }
+
+    /**
+     * Provides the inverse mixColumns and inverse sboxes tables
+     *
+     * @see Crypt_Rijndael:_decryptBlock()
+     * @see Crypt_Rijndael:_setupInlineCrypt()
+     * @see Crypt_Rijndael:_setupKey()
+     * @access private
+     * @return array &$tables
+     */
+    function &_getInvTables()
+    {
+        static $tables;
+        if (empty($tables)) {
+            $dt3 = array_map('intval', array(
+                0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
+                0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
+                0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
+                0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
+                0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
+                0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
+                0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
+                0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
+                0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
+                0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
+                0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
+                0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
+                0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
+                0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
+                0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
+                0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
+                0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
+                0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
+                0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
+                0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
+                0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
+                0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
+                0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
+                0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
+                0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
+                0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
+                0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
+                0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
+                0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
+                0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
+                0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
+                0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
+            ));
+
+            foreach ($dt3 as $dt3i) {
+                $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >>  8) & 0x00FFFFFF);
+                $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF);
+                $dt2[] = (($dt3i <<  8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF);
+            };
+
+            $tables = array(
+                // The Precomputed inverse mixColumns tables dt0 - dt3
+                $dt0,
+                $dt1,
+                $dt2,
+                $dt3,
+                // The inverse SubByte S-Box
+                array(
+                    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+                    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+                    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+                    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+                    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+                    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+                    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+                    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+                    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+                    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+                    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+                    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+                    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+                    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+                    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+                    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+                )
+            );
+        }
+        return $tables;
+    }
+
     /**
      * Setup the performance-optimized function for de/encrypt()
      *
@@ -1193,42 +888,50 @@ class Crypt_Rijndael extends Crypt_Base
 
         $lambda_functions =& Crypt_Rijndael::_getLambdaFunctions();
 
-        // The first 10 generated $lambda_functions will use the key-words hardcoded for better performance.
-        // For memory reason we limit those ultra-optimized functions.
-        // After that, we use pure (extracted) integer vars for the key-words which is faster than accessing them via array.
-        if (count($lambda_functions) < 10) {
-            $w  = $this->w;
-            $dw = $this->dw;
-            $init_encrypt = '';
-            $init_decrypt = '';
-        } else {
-            for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
-                $w[]  = '$w['  . $i . ']';
-                $dw[] = '$dw[' . $i . ']';
-            }
-            $init_encrypt = '$w = $self->w;';
-            $init_decrypt = '$dw = $self->dw;';
-        }
+        // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
+        // (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit)
+        // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
+        $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
 
-        $code_hash = md5(str_pad("Crypt_Rijndael, {$this->mode}, {$this->block_size}, ", 32, "\0") . implode(',', $w));
+        // Generation of a uniqe hash for our generated code
+        $code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}";
+        if ($gen_hi_opt_code) {
+            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+        }
 
         if (!isset($lambda_functions[$code_hash])) {
+            switch (true) {
+                case $gen_hi_opt_code:
+                    // The hi-optimized $lambda_functions will use the key-words hardcoded for better performance.
+                    $w  = $this->w;
+                    $dw = $this->dw;
+                    $init_encrypt = '';
+                    $init_decrypt = '';
+                    break;
+                default:
+                    for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
+                        $w[]  = '$w['  . $i . ']';
+                        $dw[] = '$dw[' . $i . ']';
+                    }
+                    $init_encrypt = '$w  = $self->w;';
+                    $init_decrypt = '$dw = $self->dw;';
+            }
+
             $Nr = $this->Nr;
             $Nb = $this->Nb;
             $c  = $this->c;
 
             // Generating encrypt code:
             $init_encrypt.= '
-                static $t0, $t1, $t2, $t3, $sbox;
-                if (!$t0) {
-                    for ($i = 0; $i < 256; ++$i) {
-                        $t0[$i]    = (int)$self->t0[$i];
-                        $t1[$i]    = (int)$self->t1[$i];
-                        $t2[$i]    = (int)$self->t2[$i];
-                        $t3[$i]    = (int)$self->t3[$i];
-                        $sbox[$i]  = (int)$self->sbox[$i];
-                    }
+                static $tables;
+                if (empty($tables)) {
+                    $tables = &$self->_getTables();
                 }
+                $t0   = $tables[0];
+                $t1   = $tables[1];
+                $t2   = $tables[2];
+                $t3   = $tables[3];
+                $sbox = $tables[4];
             ';
 
             $s  = 'e';
@@ -1267,26 +970,25 @@ class Crypt_Rijndael extends Crypt_Base
             $encrypt_block .= '$in = pack("N*"'."\n";
             for ($i = 0; $i < $Nb; ++$i) {
                 $encrypt_block.= ',
-                    ($'.$e.$i                  .' & 0xFF000000) ^
-                    ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000) ^
-                    ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00) ^
-                    ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF) ^
+                    ($'.$e.$i                  .' & '.((int)0xFF000000).') ^
+                    ($'.$e.(($i + $c[1]) % $Nb).' &         0x00FF0000   ) ^
+                    ($'.$e.(($i + $c[2]) % $Nb).' &         0x0000FF00   ) ^
+                    ($'.$e.(($i + $c[3]) % $Nb).' &         0x000000FF   ) ^
                     '.$w[$i]."\n";
             }
             $encrypt_block .= ');';
 
             // Generating decrypt code:
             $init_decrypt.= '
-                static $dt0, $dt1, $dt2, $dt3, $isbox;
-                if (!$dt0) {
-                    for ($i = 0; $i < 256; ++$i) {
-                        $dt0[$i]   = (int)$self->dt0[$i];
-                        $dt1[$i]   = (int)$self->dt1[$i];
-                        $dt2[$i]   = (int)$self->dt2[$i];
-                        $dt3[$i]   = (int)$self->dt3[$i];
-                        $isbox[$i] = (int)$self->isbox[$i];
-                    }
+                static $invtables;
+                if (empty($invtables)) {
+                    $invtables = &$self->_getInvTables();
                 }
+                $dt0   = $invtables[0];
+                $dt1   = $invtables[1];
+                $dt2   = $invtables[2];
+                $dt3   = $invtables[3];
+                $isbox = $invtables[4];
             ';
 
             $s  = 'e';
@@ -1325,10 +1027,10 @@ class Crypt_Rijndael extends Crypt_Base
             $decrypt_block .= '$in = pack("N*"'."\n";
             for ($i = 0; $i < $Nb; ++$i) {
                 $decrypt_block.= ',
-                    ($'.$e.$i.                        ' & 0xFF000000) ^
-                    ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000) ^
-                    ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00) ^
-                    ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF) ^
+                    ($'.$e.$i.                        ' & '.((int)0xFF000000).') ^
+                    ($'.$e.(($Nb + $i - $c[1]) % $Nb).' &         0x00FF0000   ) ^
+                    ($'.$e.(($Nb + $i - $c[2]) % $Nb).' &         0x0000FF00   ) ^
+                    ($'.$e.(($Nb + $i - $c[3]) % $Nb).' &         0x000000FF   ) ^
                     '.$dw[$i]."\n";
             }
             $decrypt_block .= ');';
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
index 06ea09b1eedd34ff3441ad010bf5dab373b3b966..4c0b67708b01ed3c75840085adbec913a1c4f76c 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
@@ -59,19 +59,31 @@ if (!class_exists('Crypt_DES')) {
     include_once 'DES.php';
 }
 
+/**#@+
+ * @access public
+ * @see self::Crypt_TripleDES()
+ */
 /**
  * Encrypt / decrypt using inner chaining
  *
  * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).
  */
+define('CRYPT_MODE_3CBC', -2);
+/**
+ * BC version of the above.
+ */
 define('CRYPT_DES_MODE_3CBC', -2);
-
 /**
  * Encrypt / decrypt using outer chaining
  *
  * Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.
  */
-define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC);
+define('CRYPT_MODE_CBC3', CRYPT_MODE_CBC);
+/**
+ * BC version of the above.
+ */
+define('CRYPT_DES_MODE_CBC3', CRYPT_MODE_CBC3);
+/**#@-*/
 
 /**
  * Pure-PHP implementation of Triple DES.
@@ -83,22 +95,20 @@ define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC);
 class Crypt_TripleDES extends Crypt_DES
 {
     /**
-     * The default password key_size used by setPassword()
+     * Key Length (in bytes)
      *
-     * @see Crypt_DES::password_key_size
-     * @see Crypt_Base::password_key_size
-     * @see Crypt_Base::setPassword()
-     * @var Integer
+     * @see Crypt_TripleDES::setKeyLength()
+     * @var int
      * @access private
      */
-    var $password_key_size = 24;
+    var $key_length = 24;
 
     /**
      * The default salt used by setPassword()
      *
      * @see Crypt_Base::password_default_salt
      * @see Crypt_Base::setPassword()
-     * @var String
+     * @var string
      * @access private
      */
     var $password_default_salt = 'phpseclib';
@@ -108,7 +118,7 @@ class Crypt_TripleDES extends Crypt_DES
      *
      * @see Crypt_DES::const_namespace
      * @see Crypt_Base::const_namespace
-     * @var String
+     * @var string
      * @access private
      */
     var $const_namespace = 'DES';
@@ -118,7 +128,7 @@ class Crypt_TripleDES extends Crypt_DES
      *
      * @see Crypt_DES::cipher_name_mcrypt
      * @see Crypt_Base::cipher_name_mcrypt
-     * @var String
+     * @var string
      * @access private
      */
     var $cipher_name_mcrypt = 'tripledes';
@@ -127,7 +137,7 @@ class Crypt_TripleDES extends Crypt_DES
      * Optimizing value while CFB-encrypting
      *
      * @see Crypt_Base::cfb_init_len
-     * @var Integer
+     * @var int
      * @access private
      */
     var $cfb_init_len = 750;
@@ -135,17 +145,17 @@ class Crypt_TripleDES extends Crypt_DES
     /**
      * max possible size of $key
      *
-     * @see Crypt_TripleDES::setKey()
+     * @see self::setKey()
      * @see Crypt_DES::setKey()
-     * @var String
+     * @var string
      * @access private
      */
-    var $key_size_max = 24;
+    var $key_length_max = 24;
 
     /**
      * Internal flag whether using CRYPT_DES_MODE_3CBC or not
      *
-     * @var Boolean
+     * @var bool
      * @access private
      */
     var $mode_3cbc;
@@ -155,7 +165,7 @@ class Crypt_TripleDES extends Crypt_DES
      *
      * Used only if $mode_3cbc === true
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $des;
@@ -183,23 +193,23 @@ class Crypt_TripleDES extends Crypt_DES
      *
      * @see Crypt_DES::Crypt_DES()
      * @see Crypt_Base::Crypt_Base()
-     * @param optional Integer $mode
+     * @param int $mode
      * @access public
      */
-    function Crypt_TripleDES($mode = CRYPT_DES_MODE_CBC)
+    function __construct($mode = CRYPT_MODE_CBC)
     {
         switch ($mode) {
             // In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC
             // and additional flag us internally as 3CBC
             case CRYPT_DES_MODE_3CBC:
-                parent::Crypt_Base(CRYPT_DES_MODE_CBC);
+                parent::Crypt_Base(CRYPT_MODE_CBC);
                 $this->mode_3cbc = true;
 
                 // This three $des'es will do the 3CBC work (if $key > 64bits)
                 $this->des = array(
-                    new Crypt_DES(CRYPT_DES_MODE_CBC),
-                    new Crypt_DES(CRYPT_DES_MODE_CBC),
-                    new Crypt_DES(CRYPT_DES_MODE_CBC),
+                    new Crypt_DES(CRYPT_MODE_CBC),
+                    new Crypt_DES(CRYPT_MODE_CBC),
+                    new Crypt_DES(CRYPT_MODE_CBC),
                 );
 
                 // we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
@@ -209,10 +219,43 @@ class Crypt_TripleDES extends Crypt_DES
                 break;
             // If not 3CBC, we init as usual
             default:
-                parent::Crypt_Base($mode);
+                parent::__construct($mode);
         }
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @param int $mode
+     * @access public
+     */
+    function Crypt_TripleDES($mode = CRYPT_MODE_CBC)
+    {
+        $this->__construct($mode);
+    }
+
+    /**
+     * Test for engine validity
+     *
+     * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
+     *
+     * @see Crypt_Base::Crypt_Base()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        if ($engine == CRYPT_ENGINE_OPENSSL) {
+            $this->cipher_name_openssl_ecb = 'des-ede3';
+            $mode = $this->_openssl_translate_mode();
+            $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode;
+        }
+
+        return parent::isValidEngine($engine);
+    }
+
     /**
      * Sets the initialization vector. (optional)
      *
@@ -221,7 +264,7 @@ class Crypt_TripleDES extends Crypt_DES
      *
      * @see Crypt_Base::setIV()
      * @access public
-     * @param String $iv
+     * @param string $iv
      */
     function setIV($iv)
     {
@@ -233,6 +276,32 @@ class Crypt_TripleDES extends Crypt_DES
         }
     }
 
+    /**
+     * Sets the key length.
+     *
+     * Valid key lengths are 64, 128 and 192
+     *
+     * @see Crypt_Base:setKeyLength()
+     * @access public
+     * @param int $length
+     */
+    function setKeyLength($length)
+    {
+        $length >>= 3;
+        switch (true) {
+            case $length <= 8:
+                $this->key_length = 8;
+                break;
+            case $length <= 16:
+                $this->key_length = 16;
+                break;
+            default:
+                $this->key_length = 24;
+        }
+
+        parent::setKeyLength($length);
+    }
+
     /**
      * Sets the key.
      *
@@ -246,16 +315,16 @@ class Crypt_TripleDES extends Crypt_DES
      * @access public
      * @see Crypt_DES::setKey()
      * @see Crypt_Base::setKey()
-     * @param String $key
+     * @param string $key
      */
     function setKey($key)
     {
-        $length = strlen($key);
+        $length = $this->explicit_key_length ? $this->key_length : strlen($key);
         if ($length > 8) {
             $key = str_pad(substr($key, 0, 24), 24, chr(0));
             // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
             // http://php.net/function.mcrypt-encrypt#47973
-            //$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
+            $key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
         } else {
             $key = str_pad($key, 8, chr(0));
         }
@@ -277,13 +346,13 @@ class Crypt_TripleDES extends Crypt_DES
      *
      * @see Crypt_Base::encrypt()
      * @access public
-     * @param String $plaintext
-     * @return String $cipertext
+     * @param string $plaintext
+     * @return string $cipertext
      */
     function encrypt($plaintext)
     {
         // parent::en/decrypt() is able to do all the work for all modes and keylengths,
-        // except for: CRYPT_DES_MODE_3CBC (inner chaining CBC) with a key > 64bits
+        // except for: CRYPT_MODE_3CBC (inner chaining CBC) with a key > 64bits
 
         // if the key is smaller then 8, do what we'd normally do
         if ($this->mode_3cbc && strlen($this->key) > 8) {
@@ -304,8 +373,8 @@ class Crypt_TripleDES extends Crypt_DES
      *
      * @see Crypt_Base::decrypt()
      * @access public
-     * @param String $ciphertext
-     * @return String $plaintext
+     * @param string $ciphertext
+     * @return string $plaintext
      */
     function decrypt($ciphertext)
     {
@@ -359,7 +428,7 @@ class Crypt_TripleDES extends Crypt_DES
      * however, they are also less intuitive and more likely to cause you problems.
      *
      * @see Crypt_Base::enableContinuousBuffer()
-     * @see Crypt_TripleDES::disableContinuousBuffer()
+     * @see self::disableContinuousBuffer()
      * @access public
      */
     function enableContinuousBuffer()
@@ -378,7 +447,7 @@ class Crypt_TripleDES extends Crypt_DES
      * The default behavior.
      *
      * @see Crypt_Base::disableContinuousBuffer()
-     * @see Crypt_TripleDES::enableContinuousBuffer()
+     * @see self::enableContinuousBuffer()
      * @access public
      */
     function disableContinuousBuffer()
@@ -425,4 +494,24 @@ class Crypt_TripleDES extends Crypt_DES
         // setup our key
         parent::_setupKey();
     }
+
+    /**
+     * Sets the internal crypt engine
+     *
+     * @see Crypt_Base::Crypt_Base()
+     * @see Crypt_Base::setPreferredEngine()
+     * @param int $engine
+     * @access public
+     * @return int
+     */
+    function setPreferredEngine($engine)
+    {
+        if ($this->mode_3cbc) {
+            $this->des[0]->setPreferredEngine($engine);
+            $this->des[1]->setPreferredEngine($engine);
+            $this->des[2]->setPreferredEngine($engine);
+        }
+
+        return parent::setPreferredEngine($engine);
+    }
 }
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
index 8dd7933a800afb5dc8f9bd965cc26a182db621a3..7125f6a099882efe82e5936a331bfed6dae6c67f 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
@@ -64,8 +64,8 @@ if (!class_exists('Crypt_Base')) {
 
 /**#@+
  * @access public
- * @see Crypt_Twofish::encrypt()
- * @see Crypt_Twofish::decrypt()
+ * @see self::encrypt()
+ * @see self::decrypt()
  */
 /**
  * Encrypt / decrypt using the Counter mode.
@@ -101,20 +101,6 @@ define('CRYPT_TWOFISH_MODE_CFB', CRYPT_MODE_CFB);
 define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB);
 /**#@-*/
 
-/**#@+
- * @access private
- * @see Crypt_Base::Crypt_Base()
- */
-/**
- * Toggles the internal implementation
- */
-define('CRYPT_TWOFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
-/**
- * Toggles the mcrypt implementation
- */
-define('CRYPT_TWOFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
-/**#@-*/
-
 /**
  * Pure-PHP implementation of Twofish.
  *
@@ -129,7 +115,7 @@ class Crypt_Twofish extends Crypt_Base
      * The namespace used by the cipher for its constants.
      *
      * @see Crypt_Base::const_namespace
-     * @var String
+     * @var string
      * @access private
      */
     var $const_namespace = 'TWOFISH';
@@ -138,7 +124,7 @@ class Crypt_Twofish extends Crypt_Base
      * The mcrypt specific name of the cipher
      *
      * @see Crypt_Base::cipher_name_mcrypt
-     * @var String
+     * @var string
      * @access private
      */
     var $cipher_name_mcrypt = 'twofish';
@@ -147,7 +133,7 @@ class Crypt_Twofish extends Crypt_Base
      * Optimizing value while CFB-encrypting
      *
      * @see Crypt_Base::cfb_init_len
-     * @var Integer
+     * @var int
      * @access private
      */
     var $cfb_init_len = 800;
@@ -155,10 +141,10 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * Q-Table
      *
-     * @var Array
+     * @var array
      * @access private
      */
-    var $q0 = array (
+    var $q0 = array(
         0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
         0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
         0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
@@ -196,10 +182,10 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * Q-Table
      *
-     * @var Array
+     * @var array
      * @access private
      */
-    var $q1 = array (
+    var $q1 = array(
         0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
         0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
         0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
@@ -237,10 +223,10 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * M-Table
      *
-     * @var Array
+     * @var array
      * @access private
      */
-    var $m0 = array (
+    var $m0 = array(
         0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
         0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
         0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
@@ -278,10 +264,10 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * M-Table
      *
-     * @var Array
+     * @var array
      * @access private
      */
-    var $m1 = array (
+    var $m1 = array(
         0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
         0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
         0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
@@ -319,10 +305,10 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * M-Table
      *
-     * @var Array
+     * @var array
      * @access private
      */
-    var $m2 = array (
+    var $m2 = array(
         0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
         0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
         0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
@@ -360,10 +346,10 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * M-Table
      *
-     * @var Array
+     * @var array
      * @access private
      */
-    var $m3 = array (
+    var $m3 = array(
         0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
         0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
         0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
@@ -401,7 +387,7 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * The Key Schedule Array
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $K = array();
@@ -409,7 +395,7 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * The Key depended S-Table 0
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $S0 = array();
@@ -417,7 +403,7 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * The Key depended S-Table 1
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $S1 = array();
@@ -425,7 +411,7 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * The Key depended S-Table 2
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $S2 = array();
@@ -433,7 +419,7 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * The Key depended S-Table 3
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $S3 = array();
@@ -441,41 +427,42 @@ class Crypt_Twofish extends Crypt_Base
     /**
      * Holds the last used key
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $kl;
 
     /**
-     * Sets the key.
+     * The Key Length (in bytes)
      *
-     * Keys can be of any length. Twofish, itself, requires the use of a key that's 128, 192 or 256-bits long.
-     * If the key is less than 256-bits we round the length up to the closest valid key length,
-     * padding $key with null bytes. If the key is more than 256-bits, we trim the excess bits.
+     * @see Crypt_Twofish::setKeyLength()
+     * @var int
+     * @access private
+     */
+    var $key_length = 16;
+
+    /**
+     * Sets the key length.
      *
-     * If the key is not explicitly set, it'll be assumed a 128 bits key to be all null bytes.
+     * Valid key lengths are 128, 192 or 256 bits
      *
      * @access public
-     * @see Crypt_Base::setKey()
-     * @param String $key
+     * @param int $length
      */
-    function setKey($key)
+    function setKeyLength($length)
     {
-        $keylength = strlen($key);
         switch (true) {
-            case $keylength <= 16:
-                $key = str_pad($key, 16, "\0");
-                break;
-            case $keylength <= 24:
-                $key = str_pad($key, 24, "\0");
+            case $length <= 128:
+                $this->key_length = 16;
                 break;
-            case $keylength < 32:
-                $key = str_pad($key, 32, "\0");
+            case $length <= 192:
+                $this->key_length = 24;
                 break;
-            case $keylength > 32:
-                $key = substr($key, 0, 32);
+            default:
+                $this->key_length = 32;
         }
-        parent::setKey($key);
+
+        parent::setKeyLength($length);
     }
 
     /**
@@ -506,9 +493,9 @@ class Crypt_Twofish extends Crypt_Base
 
         switch (strlen($this->key)) {
             case 16:
-                list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
-                list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
-                for ($i = 0, $j = 1; $i < 40; $i+= 2,$j+= 2) {
+                list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
+                list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
+                for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
                     $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
                          $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
                          $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
@@ -529,9 +516,9 @@ class Crypt_Twofish extends Crypt_Base
                 }
                 break;
             case 24:
-                list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
-                list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
-                list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
+                list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
+                list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
+                list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
                 for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
                     $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
                          $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
@@ -553,10 +540,10 @@ class Crypt_Twofish extends Crypt_Base
                 }
                 break;
             default: // 32
-                list ($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
-                list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
-                list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
-                list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
+                list($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
+                list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
+                list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
+                list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
                 for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
                     $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
                          $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
@@ -589,9 +576,9 @@ class Crypt_Twofish extends Crypt_Base
      * _mdsrem function using by the twofish cipher algorithm
      *
      * @access private
-     * @param String $A
-     * @param String $B
-     * @return Array
+     * @param string $A
+     * @param string $B
+     * @return array
      */
     function _mdsrem($A, $B)
     {
@@ -618,7 +605,9 @@ class Crypt_Twofish extends Crypt_Base
             $u^= 0x7fffffff & ($t >> 1);
 
             // Add the modular polynomial on underflow.
-            if ($t & 0x01) $u^= 0xa6 ;
+            if ($t & 0x01) {
+                $u^= 0xa6 ;
+            }
 
             // Remove t * (a + 1/a) * (x^3 + x).
             $B^= ($u << 24) | ($u << 8);
@@ -635,8 +624,8 @@ class Crypt_Twofish extends Crypt_Base
      * Encrypts a block
      *
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
      */
     function _encryptBlock($in)
     {
@@ -691,8 +680,8 @@ class Crypt_Twofish extends Crypt_Base
      * Decrypts a block
      *
      * @access private
-     * @param String $in
-     * @return String
+     * @param string $in
+     * @return string
      */
     function _decryptBlock($in)
     {
@@ -754,21 +743,19 @@ class Crypt_Twofish extends Crypt_Base
         $lambda_functions =& Crypt_Twofish::_getLambdaFunctions();
 
         // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
-        $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
+        // (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
+        $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
 
-        switch (true) {
-            case $gen_hi_opt_code:
-                $code_hash = md5(str_pad("Crypt_Twofish, {$this->mode}, ", 32, "\0") . $this->key);
-                break;
-            default:
-                $code_hash = "Crypt_Twofish, {$this->mode}";
+        // Generation of a unique hash for our generated code
+        $code_hash = "Crypt_Twofish, {$this->mode}";
+        if ($gen_hi_opt_code) {
+            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
         }
 
         if (!isset($lambda_functions[$code_hash])) {
             switch (true) {
                 case $gen_hi_opt_code:
                     $K = $this->K;
-
                     $init_crypt = '
                         static $S0, $S1, $S2, $S3;
                         if (!$S0) {
@@ -786,7 +773,6 @@ class Crypt_Twofish extends Crypt_Base
                     for ($i = 0; $i < 40; ++$i) {
                         $K[] = '$K_' . $i;
                     }
-
                     $init_crypt = '
                         $S0 = $self->S0;
                         $S1 = $self->S1;
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php
index 3ff1b7d4bf6fdbfc9f9d8ab4d1124a4ac6ed6553..989537befef05dd25cf6749f838da96375a78219 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php
@@ -48,7 +48,7 @@ class File_ANSI
     /**
      * Max Width
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $max_x;
@@ -56,7 +56,7 @@ class File_ANSI
     /**
      * Max Height
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $max_y;
@@ -64,7 +64,7 @@ class File_ANSI
     /**
      * Max History
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $max_history;
@@ -72,7 +72,7 @@ class File_ANSI
     /**
      * History
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $history;
@@ -80,7 +80,7 @@ class File_ANSI
     /**
      * History Attributes
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $history_attrs;
@@ -88,7 +88,7 @@ class File_ANSI
     /**
      * Current Column
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $x;
@@ -96,7 +96,7 @@ class File_ANSI
     /**
      * Current Row
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $y;
@@ -104,7 +104,7 @@ class File_ANSI
     /**
      * Old Column
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $old_x;
@@ -112,109 +112,98 @@ class File_ANSI
     /**
      * Old Row
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $old_y;
 
     /**
-     * An empty attribute row
-     *
-     * @var Array
-     * @access private
-     */
-    var $attr_row;
-
-    /**
-     * The current screen text
+     * An empty attribute cell
      *
-     * @var Array
+     * @var object
      * @access private
      */
-    var $screen;
+    var $base_attr_cell;
 
     /**
-     * The current screen attributes
+     * The current attribute cell
      *
-     * @var Array
+     * @var object
      * @access private
      */
-    var $attrs;
+    var $attr_cell;
 
     /**
-     * The current foreground color
-     *
-     * @var String
-     * @access private
-     */
-    var $foreground;
-
-    /**
-     * The current background color
+     * An empty attribute row
      *
-     * @var String
+     * @var array
      * @access private
      */
-    var $background;
+    var $attr_row;
 
     /**
-     * Bold flag
+     * The current screen text
      *
-     * @var Boolean
+     * @var array
      * @access private
      */
-    var $bold;
+    var $screen;
 
     /**
-     * Underline flag
+     * The current screen attributes
      *
-     * @var Boolean
+     * @var array
      * @access private
      */
-    var $underline;
+    var $attrs;
 
     /**
-     * Blink flag
+     * Current ANSI code
      *
-     * @var Boolean
+     * @var string
      * @access private
      */
-    var $blink;
+    var $ansi;
 
     /**
-     * Reverse flag
+     * Tokenization
      *
-     * @var Boolean
+     * @var array
      * @access private
      */
-    var $reverse;
+    var $tokenization;
 
     /**
-     * Color flag
+     * Default Constructor.
      *
-     * @var Boolean
-     * @access private
+     * @return File_ANSI
+     * @access public
      */
-    var $color;
+    function __construct()
+    {
+        $attr_cell = new stdClass();
+        $attr_cell->bold = false;
+        $attr_cell->underline = false;
+        $attr_cell->blink = false;
+        $attr_cell->background = 'black';
+        $attr_cell->foreground = 'white';
+        $attr_cell->reverse = false;
+        $this->base_attr_cell = clone($attr_cell);
+        $this->attr_cell = clone($attr_cell);
 
-    /**
-     * Current ANSI code
-     *
-     * @var String
-     * @access private
-     */
-    var $ansi;
+        $this->setHistory(200);
+        $this->setDimensions(80, 24);
+    }
 
     /**
-     * Default Constructor.
+     * PHP4 compatible Default Constructor.
      *
-     * @return File_ANSI
+     * @see self::__construct()
      * @access public
      */
     function File_ANSI()
     {
-        $this->setHistory(200);
-        $this->setDimensions(80, 24);
+        $this->__construct($mode);
     }
 
     /**
@@ -222,8 +211,8 @@ class File_ANSI
      *
      * Resets the screen as well
      *
-     * @param Integer $x
-     * @param Integer $y
+     * @param int $x
+     * @param int $y
      * @access public
      */
     function setDimensions($x, $y)
@@ -232,25 +221,17 @@ class File_ANSI
         $this->max_y = $y - 1;
         $this->x = $this->y = 0;
         $this->history = $this->history_attrs = array();
-        $this->attr_row = array_fill(0, $this->max_x + 1, '');
+        $this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell);
         $this->screen = array_fill(0, $this->max_y + 1, '');
         $this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row);
-        $this->foreground = 'white';
-        $this->background = 'black';
-        $this->bold = false;
-        $this->underline = false;
-        $this->blink = false;
-        $this->reverse = false;
-        $this->color = false;
-
         $this->ansi = '';
     }
 
     /**
      * Set the number of lines that should be logged past the terminal height
      *
-     * @param Integer $x
-     * @param Integer $y
+     * @param int $x
+     * @param int $y
      * @access public
      */
     function setHistory($history)
@@ -261,7 +242,7 @@ class File_ANSI
     /**
      * Load a string
      *
-     * @param String $source
+     * @param string $source
      * @access public
      */
     function loadString($source)
@@ -273,11 +254,12 @@ class File_ANSI
     /**
      * Appdend a string
      *
-     * @param String $source
+     * @param string $source
      * @access public
      */
     function appendString($source)
     {
+        $this->tokenization = array('');
         for ($i = 0; $i < strlen($source); $i++) {
             if (strlen($this->ansi)) {
                 $this->ansi.= $source[$i];
@@ -294,6 +276,8 @@ class File_ANSI
                     default:
                         continue 2;
                 }
+                $this->tokenization[] = $this->ansi;
+                $this->tokenization[] = '';
                 // http://ascii-table.com/ansi-escape-sequences-vt-100.php
                 switch ($this->ansi) {
                     case "\x1B[H": // Move cursor to upper left corner
@@ -315,7 +299,7 @@ class File_ANSI
                     case "\x1B[K": // Clear screen from cursor right
                         $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
 
-                        array_splice($this->attrs[$this->y], $this->x + 1);
+                        array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - $this->x - 1, $this->base_attr_cell));
                         break;
                     case "\x1B[2K": // Clear entire line
                         $this->screen[$this->y] = str_repeat(' ', $this->x);
@@ -323,6 +307,7 @@ class File_ANSI
                         break;
                     case "\x1B[?1h": // set cursor key to application
                     case "\x1B[?25h": // show the cursor
+                    case "\x1B(B": // set united states g0 character set
                         break;
                     case "\x1BE": // Move to next line
                         $this->_newLine();
@@ -330,6 +315,10 @@ class File_ANSI
                         break;
                     default:
                         switch (true) {
+                            case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines
+                                $this->old_y = $this->y;
+                                $this->y+= $match[1];
+                                break;
                             case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h
                                 $this->old_x = $this->x;
                                 $this->old_y = $this->y;
@@ -338,65 +327,44 @@ class File_ANSI
                                 break;
                             case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines
                                 $this->old_x = $this->x;
-                                $x = $match[1] - 1;
+                                $this->x+= $match[1];
+                                break;
+                            case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
+                                $this->old_x = $this->x;
+                                $this->x-= $match[1];
                                 break;
                             case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
                                 break;
                             case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes
+                                $attr_cell = &$this->attr_cell;
                                 $mods = explode(';', $match[1]);
                                 foreach ($mods as $mod) {
                                     switch ($mod) {
                                         case 0: // Turn off character attributes
-                                            $this->attrs[$this->y][$this->x] = '';
-
-                                            if ($this->bold) $this->attrs[$this->y][$this->x].= '</b>';
-                                            if ($this->underline) $this->attrs[$this->y][$this->x].= '</u>';
-                                            if ($this->blink) $this->attrs[$this->y][$this->x].= '</blink>';
-                                            if ($this->color) $this->attrs[$this->y][$this->x].= '</span>';
-
-                                            if ($this->reverse) {
-                                                $temp = $this->background;
-                                                $this->background = $this->foreground;
-                                                $this->foreground = $temp;
-                                            }
-
-                                            $this->bold = $this->underline = $this->blink = $this->color = $this->reverse = false;
+                                            $attr_cell = clone($this->base_attr_cell);
                                             break;
                                         case 1: // Turn bold mode on
-                                            if (!$this->bold) {
-                                                $this->attrs[$this->y][$this->x] = '<b>';
-                                                $this->bold = true;
-                                            }
+                                            $attr_cell->bold = true;
                                             break;
                                         case 4: // Turn underline mode on
-                                            if (!$this->underline) {
-                                                $this->attrs[$this->y][$this->x] = '<u>';
-                                                $this->underline = true;
-                                            }
+                                            $attr_cell->underline = true;
                                             break;
                                         case 5: // Turn blinking mode on
-                                            if (!$this->blink) {
-                                                $this->attrs[$this->y][$this->x] = '<blink>';
-                                                $this->blink = true;
-                                            }
+                                            $attr_cell->blink = true;
                                             break;
                                         case 7: // Turn reverse video on
-                                            $this->reverse = !$this->reverse;
-                                            $temp = $this->background;
-                                            $this->background = $this->foreground;
-                                            $this->foreground = $temp;
-                                            $this->attrs[$this->y][$this->x] = '<span style="color: ' . $this->foreground . '; background: ' . $this->background . '">';
-                                            if ($this->color) {
-                                                $this->attrs[$this->y][$this->x] = '</span>' . $this->attrs[$this->y][$this->x];
-                                            }
-                                            $this->color = true;
+                                            $attr_cell->reverse = !$attr_cell->reverse;
+                                            $temp = $attr_cell->background;
+                                            $attr_cell->background = $attr_cell->foreground;
+                                            $attr_cell->foreground = $temp;
                                             break;
                                         default: // set colors
-                                            //$front = $this->reverse ? &$this->background : &$this->foreground;
-                                            $front = &$this->{ $this->reverse ? 'background' : 'foreground' };
-                                            //$back = $this->reverse ? &$this->foreground : &$this->background;
-                                            $back = &$this->{ $this->reverse ? 'foreground' : 'background' };
+                                            //$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground;
+                                            $front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' };
+                                            //$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background;
+                                            $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' };
                                             switch ($mod) {
+                                                // @codingStandardsIgnoreStart
                                                 case 30: $front = 'black'; break;
                                                 case 31: $front = 'red'; break;
                                                 case 32: $front = 'green'; break;
@@ -414,30 +382,25 @@ class File_ANSI
                                                 case 45: $back = 'magenta'; break;
                                                 case 46: $back = 'cyan'; break;
                                                 case 47: $back = 'white'; break;
+                                                // @codingStandardsIgnoreEnd
 
                                                 default:
-                                                    user_error('Unsupported attribute: ' . $mod);
+                                                    //user_error('Unsupported attribute: ' . $mod);
                                                     $this->ansi = '';
                                                     break 2;
                                             }
-
-                                            unset($temp);
-                                            $this->attrs[$this->y][$this->x] = '<span style="color: ' . $this->foreground . '; background: ' . $this->background . '">';
-                                            if ($this->color) {
-                                                $this->attrs[$this->y][$this->x] = '</span>' . $this->attrs[$this->y][$this->x];
-                                            }
-                                            $this->color = true;
                                     }
                                 }
                                 break;
                             default:
-                                user_error("{$this->ansi} unsupported\r\n");
+                                //user_error("{$this->ansi} is unsupported\r\n");
                         }
                 }
                 $this->ansi = '';
                 continue;
             }
 
+            $this->tokenization[count($this->tokenization) - 1].= $source[$i];
             switch ($source[$i]) {
                 case "\r":
                     $this->x = 0;
@@ -445,12 +408,32 @@ class File_ANSI
                 case "\n":
                     $this->_newLine();
                     break;
+                case "\x08": // backspace
+                    if ($this->x) {
+                        $this->x--;
+                        $this->attrs[$this->y][$this->x] = clone($this->base_attr_cell);
+                        $this->screen[$this->y] = substr_replace(
+                            $this->screen[$this->y],
+                            $source[$i],
+                            $this->x,
+                            1
+                        );
+                    }
+                    break;
                 case "\x0F": // shift
                     break;
                 case "\x1B": // start ANSI escape code
+                    $this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1);
+                    //if (!strlen($this->tokenization[count($this->tokenization) - 1])) {
+                    //    array_pop($this->tokenization);
+                    //}
                     $this->ansi.= "\x1B";
                     break;
                 default:
+                    $this->attrs[$this->y][$this->x] = clone($this->attr_cell);
+                    if ($this->x > strlen($this->screen[$this->y])) {
+                        $this->screen[$this->y] = str_repeat(' ', $this->x);
+                    }
                     $this->screen[$this->y] = substr_replace(
                         $this->screen[$this->y],
                         $source[$i],
@@ -498,26 +481,84 @@ class File_ANSI
         $this->y++;
     }
 
+    /**
+     * Returns the current coordinate without preformating
+     *
+     * @access private
+     * @return string
+     */
+    function _processCoordinate($last_attr, $cur_attr, $char)
+    {
+        $output = '';
+
+        if ($last_attr != $cur_attr) {
+            $close = $open = '';
+            if ($last_attr->foreground != $cur_attr->foreground) {
+                if ($cur_attr->foreground != 'white') {
+                    $open.= '<span style="color: ' . $cur_attr->foreground . '">';
+                }
+                if ($last_attr->foreground != 'white') {
+                    $close = '</span>' . $close;
+                }
+            }
+            if ($last_attr->background != $cur_attr->background) {
+                if ($cur_attr->background != 'black') {
+                    $open.= '<span style="background: ' . $cur_attr->background . '">';
+                }
+                if ($last_attr->background != 'black') {
+                    $close = '</span>' . $close;
+                }
+            }
+            if ($last_attr->bold != $cur_attr->bold) {
+                if ($cur_attr->bold) {
+                    $open.= '<b>';
+                } else {
+                    $close = '</b>' . $close;
+                }
+            }
+            if ($last_attr->underline != $cur_attr->underline) {
+                if ($cur_attr->underline) {
+                    $open.= '<u>';
+                } else {
+                    $close = '</u>' . $close;
+                }
+            }
+            if ($last_attr->blink != $cur_attr->blink) {
+                if ($cur_attr->blink) {
+                    $open.= '<blink>';
+                } else {
+                    $close = '</blink>' . $close;
+                }
+            }
+            $output.= $close . $open;
+        }
+
+        $output.= htmlspecialchars($char);
+
+        return $output;
+    }
+
     /**
      * Returns the current screen without preformating
      *
      * @access private
-     * @return String
+     * @return string
      */
     function _getScreen()
     {
         $output = '';
+        $last_attr = $this->base_attr_cell;
         for ($i = 0; $i <= $this->max_y; $i++) {
-            for ($j = 0; $j <= $this->max_x + 1; $j++) {
-                if (isset($this->attrs[$i][$j])) {
-                    $output.= $this->attrs[$i][$j];
-                }
-                if (isset($this->screen[$i][$j])) {
-                    $output.= htmlspecialchars($this->screen[$i][$j]);
-                }
+            for ($j = 0; $j <= $this->max_x; $j++) {
+                $cur_attr = $this->attrs[$i][$j];
+                $output.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : '');
+                $last_attr = $this->attrs[$i][$j];
             }
             $output.= "\r\n";
         }
+        $output = substr($output, 0, -2);
+        // close any remaining open tags
+        $output.= $this->_processCoordinate($last_attr, $this->base_attr_cell, '');
         return rtrim($output);
     }
 
@@ -525,35 +566,36 @@ class File_ANSI
      * Returns the current screen
      *
      * @access public
-     * @return String
+     * @return string
      */
     function getScreen()
     {
-        return '<pre style="color: white; background: black" width="' . ($this->max_x + 1) . '">' . $this->_getScreen() . '</pre>';
+        return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $this->_getScreen() . '</pre>';
     }
 
     /**
      * Returns the current screen and the x previous lines
      *
      * @access public
-     * @return String
+     * @return string
      */
     function getHistory()
     {
         $scrollback = '';
+        $last_attr = $this->base_attr_cell;
         for ($i = 0; $i < count($this->history); $i++) {
             for ($j = 0; $j <= $this->max_x + 1; $j++) {
-                if (isset($this->history_attrs[$i][$j])) {
-                    $scrollback.= $this->history_attrs[$i][$j];
-                }
-                if (isset($this->history[$i][$j])) {
-                    $scrollback.= htmlspecialchars($this->history[$i][$j]);
-                }
+                $cur_attr = $this->history_attrs[$i][$j];
+                $scrollback.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : '');
+                $last_attr = $this->history_attrs[$i][$j];
             }
             $scrollback.= "\r\n";
         }
+        $base_attr_cell = $this->base_attr_cell;
+        $this->base_attr_cell = $last_attr;
         $scrollback.= $this->_getScreen();
+        $this->base_attr_cell = $base_attr_cell;
 
-        return '<pre style="color: white; background: black" width="' . ($this->max_x + 1) . '">' . $scrollback . '</pre>';
+        return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $scrollback . '</span></pre>';
     }
 }
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
index 1d66793a13000ab75b353b21f9b053ed001d3362..2fd2339ea1b3421fc38766d58124761445ab4734 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
@@ -119,7 +119,7 @@ class File_ASN1_Element
     /**
      * Raw element value
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $element;
@@ -127,14 +127,26 @@ class File_ASN1_Element
     /**
      * Constructor
      *
-     * @param String $encoded
+     * @param string $encoded
      * @return File_ASN1_Element
      * @access public
      */
-    function File_ASN1_Element($encoded)
+    function __construct($encoded)
     {
         $this->element = $encoded;
     }
+
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @param int $mode
+     * @access public
+     */
+    function File_ASN1_Element($encoded)
+    {
+        $this->__construct($encoded);
+    }
 }
 
 /**
@@ -149,7 +161,7 @@ class File_ASN1
     /**
      * ASN.1 object identifier
      *
-     * @var Array
+     * @var array
      * @access private
      * @link http://en.wikipedia.org/wiki/Object_identifier
      */
@@ -158,7 +170,7 @@ class File_ASN1
     /**
      * Default date format
      *
-     * @var String
+     * @var string
      * @access private
      * @link http://php.net/class.datetime
      */
@@ -167,10 +179,10 @@ class File_ASN1
     /**
      * Default date format
      *
-     * @var Array
+     * @var array
      * @access private
-     * @see File_ASN1::setTimeFormat()
-     * @see File_ASN1::asn1map()
+     * @see self::setTimeFormat()
+     * @see self::asn1map()
      * @link http://php.net/class.datetime
      */
     var $encoded;
@@ -180,9 +192,9 @@ class File_ASN1
      *
      * If the mapping type is FILE_ASN1_TYPE_ANY what do we actually encode it as?
      *
-     * @var Array
+     * @var array
      * @access private
-     * @see File_ASN1::_encode_der()
+     * @see self::_encode_der()
      */
     var $filters;
 
@@ -193,7 +205,7 @@ class File_ASN1
      * Unambiguous types get the direct mapping (int/real/bool).
      * Others are mapped as a choice, with an extra indexing level.
      *
-     * @var Array
+     * @var array
      * @access public
      */
     var $ANYmap = array(
@@ -227,7 +239,7 @@ class File_ASN1
      * Non-convertable types are absent from this table.
      * size == 0 indicates variable length encoding.
      *
-     * @var Array
+     * @var array
      * @access public
      */
     var $stringTypeSize = array(
@@ -245,7 +257,7 @@ class File_ASN1
      *
      * @access public
      */
-    function File_ASN1()
+    function __construct()
     {
         static $static_init = null;
         if (!$static_init) {
@@ -256,13 +268,24 @@ class File_ASN1
         }
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @access public
+     */
+    function File_ASN1()
+    {
+        $this->__construct($mode);
+    }
+
     /**
      * Parse BER-encoding
      *
      * Serves a similar purpose to openssl's asn1parse
      *
-     * @param String $encoded
-     * @return Array
+     * @param string $encoded
+     * @return array
      * @access public
      */
     function decodeBER($encoded)
@@ -283,16 +306,17 @@ class File_ASN1
      * $encoded is passed by reference for the recursive calls done for FILE_ASN1_TYPE_BIT_STRING and
      * FILE_ASN1_TYPE_OCTET_STRING. In those cases, the indefinite length is used.
      *
-     * @param String $encoded
-     * @param Integer $start
-     * @return Array
+     * @param string $encoded
+     * @param int $start
+     * @param int $encoded_pos
+     * @return array
      * @access private
      */
-    function _decode_ber($encoded, $start = 0)
+    function _decode_ber($encoded, $start = 0, $encoded_pos = 0)
     {
         $current = array('start' => $start);
 
-        $type = ord($this->_string_shift($encoded));
+        $type = ord($encoded[$encoded_pos++]);
         $start++;
 
         $constructed = ($type >> 5) & 1;
@@ -304,23 +328,24 @@ class File_ASN1
             do {
                 $loop = ord($encoded[0]) >> 7;
                 $tag <<= 7;
-                $tag |= ord($this->_string_shift($encoded)) & 0x7F;
+                $tag |= ord($encoded[$encoded_pos++]) & 0x7F;
                 $start++;
-            } while ( $loop );
+            } while ($loop);
         }
 
         // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13
-        $length = ord($this->_string_shift($encoded));
+        $length = ord($encoded[$encoded_pos++]);
         $start++;
-        if ( $length == 0x80 ) { // indefinite length
+        if ($length == 0x80) { // indefinite length
             // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all
             //  immediately available." -- paragraph 8.1.3.2.c
-            $length = strlen($encoded);
-        } elseif ( $length & 0x80 ) { // definite length, long form
+            $length = strlen($encoded) - $encoded_pos;
+        } elseif ($length & 0x80) { // definite length, long form
             // technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only
             // support it up to four.
             $length&= 0x7F;
-            $temp = $this->_string_shift($encoded, $length);
+            $temp = substr($encoded, $encoded_pos, $length);
+            $encoded_pos += $length;
             // tags of indefinte length don't really have a header length; this length includes the tag
             $current+= array('headerlength' => $length + 2);
             $start+= $length;
@@ -329,7 +354,12 @@ class File_ASN1
             $current+= array('headerlength' => 2);
         }
 
-        $content = $this->_string_shift($encoded, $length);
+        if ($length > (strlen($encoded) - $encoded_pos)) {
+            return false;
+        }
+
+        $content = substr($encoded, $encoded_pos, $length);
+        $content_pos = 0;
 
         // at this point $length can be overwritten. it's only accurate for definite length things as is
 
@@ -357,14 +387,21 @@ class File_ASN1
                 }
 
                 $newcontent = array();
-                if (strlen($content)) {
-                    $newcontent = $this->_decode_ber($content, $start);
-                    $length = $newcontent['length'];
-                    if (substr($content, $length, 2) == "\0\0") {
+                $remainingLength = $length;
+                while ($remainingLength > 0) {
+                    $temp = $this->_decode_ber($content, $start, $content_pos);
+                    $length = $temp['length'];
+                    // end-of-content octets - see paragraph 8.1.5
+                    if (substr($content, $content_pos + $length, 2) == "\0\0") {
                         $length+= 2;
+                        $start+= $length;
+                        $newcontent[] = $temp;
+                        break;
                     }
                     $start+= $length;
-                    $newcontent = array($newcontent);
+                    $remainingLength-= $length;
+                    $newcontent[] = $temp;
+                    $content_pos += $length;
                 }
 
                 return array(
@@ -388,11 +425,11 @@ class File_ASN1
                 //if (strlen($content) != 1) {
                 //    return false;
                 //}
-                $current['content'] = (bool) ord($content[0]);
+                $current['content'] = (bool) ord($content[$content_pos]);
                 break;
             case FILE_ASN1_TYPE_INTEGER:
             case FILE_ASN1_TYPE_ENUMERATED:
-                $current['content'] = new Math_BigInteger($content, -256);
+                $current['content'] = new Math_BigInteger(substr($content, $content_pos), -256);
                 break;
             case FILE_ASN1_TYPE_REAL: // not currently supported
                 return false;
@@ -401,10 +438,10 @@ class File_ASN1
                 // the number of unused bits in the final subsequent octet. The number shall be in the range zero to
                 // seven.
                 if (!$constructed) {
-                    $current['content'] = $content;
+                    $current['content'] = substr($content, $content_pos);
                 } else {
-                    $temp = $this->_decode_ber($content, $start);
-                    $length-= strlen($content);
+                    $temp = $this->_decode_ber($content, $start, $content_pos);
+                    $length-= (strlen($content) - $content_pos);
                     $last = count($temp) - 1;
                     for ($i = 0; $i < $last; $i++) {
                         // all subtags should be bit strings
@@ -422,13 +459,13 @@ class File_ASN1
                 break;
             case FILE_ASN1_TYPE_OCTET_STRING:
                 if (!$constructed) {
-                    $current['content'] = $content;
+                    $current['content'] = substr($content, $content_pos);
                 } else {
                     $current['content'] = '';
                     $length = 0;
-                    while (substr($content, 0, 2) != "\0\0") {
-                        $temp = $this->_decode_ber($content, $length + $start);
-                        $this->_string_shift($content, $temp['length']);
+                    while (substr($content, $content_pos, 2) != "\0\0") {
+                        $temp = $this->_decode_ber($content, $length + $start, $content_pos);
+                        $content_pos += $temp['length'];
                         // all subtags should be octet strings
                         //if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) {
                         //    return false;
@@ -436,7 +473,7 @@ class File_ASN1
                         $current['content'].= $temp['content'];
                         $length+= $temp['length'];
                     }
-                    if (substr($content, 0, 2) == "\0\0") {
+                    if (substr($content, $content_pos, 2) == "\0\0") {
                         $length+= 2; // +2 for the EOC
                     }
                 }
@@ -451,26 +488,28 @@ class File_ASN1
             case FILE_ASN1_TYPE_SET:
                 $offset = 0;
                 $current['content'] = array();
-                while (strlen($content)) {
+                $content_len = strlen($content);
+                while ($content_pos < $content_len) {
                     // if indefinite length construction was used and we have an end-of-content string next
                     // see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2
-                    if (!isset($current['headerlength']) && substr($content, 0, 2) == "\0\0") {
+                    if (!isset($current['headerlength']) && substr($content, $content_pos, 2) == "\0\0") {
                         $length = $offset + 2; // +2 for the EOC
                         break 2;
                     }
-                    $temp = $this->_decode_ber($content, $start + $offset);
-                    $this->_string_shift($content, $temp['length']);
+                    $temp = $this->_decode_ber($content, $start + $offset, $content_pos);
+                    $content_pos += $temp['length'];
                     $current['content'][] = $temp;
                     $offset+= $temp['length'];
                 }
                 break;
             case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
-                $temp = ord($this->_string_shift($content));
+                $temp = ord($content[$content_pos++]);
                 $current['content'] = sprintf('%d.%d', floor($temp / 40), $temp % 40);
                 $valuen = 0;
                 // process septets
-                while (strlen($content)) {
-                    $temp = ord($this->_string_shift($content));
+                $content_len = strlen($content);
+                while ($content_pos < $content_len) {
+                    $temp = ord($content[$content_pos++]);
                     $valuen <<= 7;
                     $valuen |= $temp & 0x7F;
                     if (~$temp & 0x80) {
@@ -511,11 +550,11 @@ class File_ASN1
             case FILE_ASN1_TYPE_UTF8_STRING:
                 // ????
             case FILE_ASN1_TYPE_BMP_STRING:
-                $current['content'] = $content;
+                $current['content'] = substr($content, $content_pos);
                 break;
             case FILE_ASN1_TYPE_UTC_TIME:
             case FILE_ASN1_TYPE_GENERALIZED_TIME:
-                $current['content'] = $this->_decodeTime($content, $tag);
+                $current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag);
             default:
         }
 
@@ -532,10 +571,10 @@ class File_ASN1
      *
      * "Special" mappings may be applied on a per tag-name basis via $special.
      *
-     * @param Array $decoded
-     * @param Array $mapping
-     * @param Array $special
-     * @return Array
+     * @param array $decoded
+     * @param array $mapping
+     * @param array $special
+     * @return array
      * @access public
      */
     function asn1map($decoded, $mapping, $special = array())
@@ -547,7 +586,7 @@ class File_ASN1
         switch (true) {
             case $mapping['type'] == FILE_ASN1_TYPE_ANY:
                 $intype = $decoded['type'];
-                if (isset($decoded['constant']) || !isset($this->ANYmap[$intype]) || ($this->encoded[$decoded['start']] & 0x20)) {
+                if (isset($decoded['constant']) || !isset($this->ANYmap[$intype]) || (ord($this->encoded[$decoded['start']]) & 0x20)) {
                     return new File_ASN1_Element(substr($this->encoded, $decoded['start'], $decoded['length']));
                 }
                 $inmap = $this->ANYmap[$intype];
@@ -666,7 +705,7 @@ class File_ASN1
                 }
 
                 // Fail mapping if all input items have not been consumed.
-                return $i < $n? null: $map;
+                return $i < $n ? null: $map;
 
             // the main diff between sets and sequences is the encapsulation of the foreach in another for loop
             case FILE_ASN1_TYPE_SET:
@@ -824,10 +863,10 @@ class File_ASN1
      *
      * "Special" mappings can be applied via $special.
      *
-     * @param String $source
-     * @param String $mapping
-     * @param Integer $idx
-     * @return String
+     * @param string $source
+     * @param string $mapping
+     * @param int $idx
+     * @return string
      * @access public
      */
     function encodeDER($source, $mapping, $special = array())
@@ -839,10 +878,10 @@ class File_ASN1
     /**
      * ASN.1 Encode (Helper function)
      *
-     * @param String $source
-     * @param String $mapping
-     * @param Integer $idx
-     * @return String
+     * @param string $source
+     * @param string $mapping
+     * @param int $idx
+     * @return string
      * @access private
      */
     function _encode_der($source, $mapping, $idx = null, $special = array())
@@ -869,10 +908,10 @@ class File_ASN1
             case FILE_ASN1_TYPE_SET:    // Children order is not important, thus process in sequence.
             case FILE_ASN1_TYPE_SEQUENCE:
                 $tag|= 0x20; // set the constructed bit
-                $value = '';
 
                 // ignore the min and max
                 if (isset($mapping['min']) && isset($mapping['max'])) {
+                    $value = array();
                     $child = $mapping['children'];
 
                     foreach ($source as $content) {
@@ -880,13 +919,23 @@ class File_ASN1
                         if ($temp === false) {
                             return false;
                         }
-                        $value.= $temp;
+                        $value[]= $temp;
+                    }
+                    /* "The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared
+                        as octet strings with the shorter components being padded at their trailing end with 0-octets.
+                        NOTE - The padding octets are for comparison purposes only and do not appear in the encodings."
+
+                       -- sec 11.6 of http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf  */
+                    if ($mapping['type'] == FILE_ASN1_TYPE_SET) {
+                        sort($value);
                     }
+                    $value = implode($value, '');
                     break;
                 }
 
+                $value = '';
                 foreach ($mapping['children'] as $key => $child) {
-                    if (!isset($source[$key])) {
+                    if (!array_key_exists($key, $source)) {
                         if (!isset($child['optional'])) {
                             return false;
                         }
@@ -1077,7 +1126,7 @@ class File_ASN1
                         if ($outtype !== false) {
                             return $this->_encode_der($source[$typename], array('type' => $outtype) + $mapping, null, $special);
                         }
-                    }
+                }
 
                 $filters = $this->filters;
                 foreach ($loc as $part) {
@@ -1139,8 +1188,8 @@ class File_ASN1
      * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
      *
      * @access private
-     * @param Integer $length
-     * @return String
+     * @param int $length
+     * @return string
      */
     function _encodeLength($length)
     {
@@ -1158,9 +1207,9 @@ class File_ASN1
      * Called by _decode_ber() and in the case of implicit tags asn1map().
      *
      * @access private
-     * @param String $content
-     * @param Integer $tag
-     * @return String
+     * @param string $content
+     * @param int $tag
+     * @return string
      */
     function _decodeTime($content, $tag)
     {
@@ -1207,7 +1256,7 @@ class File_ASN1
      * Sets the time / date format for asn1map().
      *
      * @access public
-     * @param String $format
+     * @param string $format
      */
     function setTimeFormat($format)
     {
@@ -1220,7 +1269,7 @@ class File_ASN1
      * Load the relevant OIDs for a particular ASN.1 semantic mapping.
      *
      * @access public
-     * @param Array $oids
+     * @param array $oids
      */
     function loadOIDs($oids)
     {
@@ -1233,7 +1282,7 @@ class File_ASN1
      * See File_X509, etc, for an example.
      *
      * @access public
-     * @param Array $filters
+     * @param array $filters
      */
     function loadFilters($filters)
     {
@@ -1245,9 +1294,9 @@ class File_ASN1
      *
      * Inspired by array_shift
      *
-     * @param String $string
-     * @param optional Integer $index
-     * @return String
+     * @param string $string
+     * @param int $index
+     * @return string
      * @access private
      */
     function _string_shift(&$string, $index = 1)
@@ -1263,10 +1312,10 @@ class File_ASN1
      * This is a lazy conversion, dealing only with character size.
      * No real conversion table is used.
      *
-     * @param String $in
-     * @param optional Integer $from
-     * @param optional Integer $to
-     * @return String
+     * @param string $in
+     * @param int $from
+     * @param int $to
+     * @return string
      * @access public
      */
     function convert($in, $from = FILE_ASN1_TYPE_UTF8_STRING, $to = FILE_ASN1_TYPE_UTF8_STRING)
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
index 36a6287b97525ec45071a0ed207e686b31c31928..040551f027622776a79958fcfa9250f9c75ec2d6 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
@@ -60,7 +60,7 @@ define('FILE_X509_VALIDATE_SIGNATURE_BY_CA', 1);
 
 /**#@+
  * @access public
- * @see File_X509::getDN()
+ * @see self::getDN()
  */
 /**
  * Return internal array representation
@@ -90,9 +90,9 @@ define('FILE_X509_DN_HASH', 5);
 
 /**#@+
  * @access public
- * @see File_X509::saveX509()
- * @see File_X509::saveCSR()
- * @see File_X509::saveCRL()
+ * @see self::saveX509()
+ * @see self::saveCSR()
+ * @see self::saveCRL()
  */
 /**
  * Save as PEM
@@ -110,6 +110,12 @@ define('FILE_X509_FORMAT_DER', 1);
  * Only works on CSRs. Not currently supported.
  */
 define('FILE_X509_FORMAT_SPKAC', 2);
+/**
+ * Auto-detect the format
+ *
+ * Used only by the load*() functions
+ */
+define('FILE_X509_FORMAT_AUTO_DETECT', 3);
 /**#@-*/
 
 /**
@@ -132,7 +138,7 @@ class File_X509
     /**
      * ASN.1 syntax for X.509 certificates
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $Certificate;
@@ -155,6 +161,7 @@ class File_X509
     var $CertificatePolicies;
     var $AuthorityInfoAccessSyntax;
     var $SubjectAltName;
+    var $SubjectDirectoryAttributes;
     var $PrivateKeyUsagePeriod;
     var $IssuerAltName;
     var $PolicyMappings;
@@ -178,10 +185,18 @@ class File_X509
     var $SignedPublicKeyAndChallenge;
     /**#@-*/
 
+    /**#@+
+     * ASN.1 syntax for various DN attributes
+     *
+     * @access private
+     */
+    var $PostalAddress;
+    /**#@-*/
+
     /**
      * ASN.1 syntax for Certificate Signing Requests (RFC2986)
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $CertificationRequest;
@@ -189,7 +204,7 @@ class File_X509
     /**
      * ASN.1 syntax for Certificate Revocation Lists (RFC5280)
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $CertificateList;
@@ -197,7 +212,7 @@ class File_X509
     /**
      * Distinguished Name
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $dn;
@@ -205,7 +220,7 @@ class File_X509
     /**
      * Public key
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $publicKey;
@@ -213,7 +228,7 @@ class File_X509
     /**
      * Private key
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $privateKey;
@@ -221,7 +236,7 @@ class File_X509
     /**
      * Object identifiers for X.509 certificates
      *
-     * @var Array
+     * @var array
      * @access private
      * @link http://en.wikipedia.org/wiki/Object_identifier
      */
@@ -230,7 +245,7 @@ class File_X509
     /**
      * The certificate authorities
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $CAs;
@@ -238,7 +253,7 @@ class File_X509
     /**
      * The currently loaded certificate
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $currentCert;
@@ -246,10 +261,10 @@ class File_X509
     /**
      * The signature subject
      *
-     * There's no guarantee File_X509 is going to reencode an X.509 cert in the same way it was originally
+     * There's no guarantee File_X509 is going to re-encode an X.509 cert in the same way it was originally
      * encoded so we take save the portion of the original cert that the signature would have made for.
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $signatureSubject;
@@ -257,7 +272,7 @@ class File_X509
     /**
      * Certificate Start Date
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $startDate;
@@ -265,7 +280,7 @@ class File_X509
     /**
      * Certificate End Date
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $endDate;
@@ -273,7 +288,7 @@ class File_X509
     /**
      * Serial Number
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $serialNumber;
@@ -284,7 +299,7 @@ class File_X509
      * See {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.1 RFC5280#section-4.2.1.1} and
      * {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.2 RFC5280#section-4.2.1.2}.
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $currentKeyIdentifier;
@@ -292,7 +307,7 @@ class File_X509
     /**
      * CA Flag
      *
-     * @var Boolean
+     * @var bool
      * @access private
      */
     var $caFlag = false;
@@ -300,7 +315,7 @@ class File_X509
     /**
      * SPKAC Challenge
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $challenge;
@@ -311,7 +326,7 @@ class File_X509
      * @return File_X509
      * @access public
      */
-    function File_X509()
+    function __construct()
     {
         if (!class_exists('Math_BigInteger')) {
             include_once 'Math/BigInteger.php';
@@ -1084,6 +1099,13 @@ class File_X509
             )
         );
 
+        $this->SubjectDirectoryAttributes = array(
+            'type'     => FILE_ASN1_TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $Attribute
+        );
+
         // adapted from <http://tools.ietf.org/html/rfc2986>
 
         $Attributes = array(
@@ -1251,6 +1273,14 @@ class File_X509
             )
         );
 
+        $this->PostalAddress = array(
+            'type'     => FILE_ASN1_TYPE_SEQUENCE,
+            'optional' => true,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $this->DirectoryString
+        );
+
         // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2
         $this->oids = array(
             '1.3.6.1.5.5.7' => 'id-pkix',
@@ -1285,6 +1315,7 @@ class File_X509
             '2.5.4.9' => 'id-at-streetAddress',
             '2.5.4.45' => 'id-at-uniqueIdentifier',
             '2.5.4.72' => 'id-at-role',
+            '2.5.4.16' => 'id-at-postalAddress',
 
             '0.9.2342.19200300.100.1.25' => 'id-domainComponent',
             '1.2.840.113549.1.9' => 'pkcs-9',
@@ -1417,16 +1448,28 @@ class File_X509
         );
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @access public
+     */
+    function File_X509()
+    {
+        $this->__construct();
+    }
+
     /**
      * Load X.509 certificate
      *
      * Returns an associative array describing the X.509 cert or a false if the cert failed to load
      *
-     * @param String $cert
+     * @param string $cert
+     * @param int $mode
      * @access public
-     * @return Mixed
+     * @return mixed
      */
-    function loadX509($cert)
+    function loadX509($cert, $mode = FILE_X509_FORMAT_AUTO_DETECT)
     {
         if (is_array($cert) && isset($cert['tbsCertificate'])) {
             unset($this->currentCert);
@@ -1447,7 +1490,13 @@ class File_X509
 
         $asn1 = new File_ASN1();
 
-        $cert = $this->_extractBER($cert);
+        if ($mode != FILE_X509_FORMAT_DER) {
+            $newcert = $this->_extractBER($cert);
+            if ($mode == FILE_X509_FORMAT_PEM && $cert == $newcert) {
+                return false;
+            }
+            $cert = $newcert;
+        }
 
         if ($cert === false) {
             $this->currentCert = false;
@@ -1467,7 +1516,11 @@ class File_X509
 
         $this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
 
-        $this->_mapInExtensions($x509, 'tbsCertificate/extensions', $asn1);
+        if ($this->_isSubArrayValid($x509, 'tbsCertificate/extensions')) {
+            $this->_mapInExtensions($x509, 'tbsCertificate/extensions', $asn1);
+        }
+        $this->_mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence', $asn1);
+        $this->_mapInDNs($x509, 'tbsCertificate/subject/rdnSequence', $asn1);
 
         $key = &$x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'];
         $key = $this->_reformatKey($x509['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $key);
@@ -1484,10 +1537,10 @@ class File_X509
     /**
      * Save X.509 certificate
      *
-     * @param Array $cert
-     * @param Integer $format optional
+     * @param array $cert
+     * @param int $format optional
      * @access public
-     * @return String
+     * @return string
      */
     function saveX509($cert, $format = FILE_X509_FORMAT_PEM)
     {
@@ -1505,6 +1558,16 @@ class File_X509
                     case 'rsaEncryption':
                         $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']
                             = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])));
+                        /* "[For RSA keys] the parameters field MUST have ASN.1 type NULL for this algorithm identifier."
+                           -- https://tools.ietf.org/html/rfc3279#section-2.3.1
+
+                           given that and the fact that RSA keys appear ot be the only key type for which the parameters field can be blank,
+                           it seems like perhaps the ASN.1 description ought not say the parameters field is OPTIONAL, but whatever.
+                         */
+                        $cert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = null;
+                        // https://tools.ietf.org/html/rfc3279#section-2.2.1
+                        $cert['signatureAlgorithm']['parameters'] = null;
+                        $cert['tbsCertificate']['signature']['parameters'] = null;
                 }
         }
 
@@ -1534,6 +1597,8 @@ class File_X509
         $asn1->loadFilters($filters);
 
         $this->_mapOutExtensions($cert, 'tbsCertificate/extensions', $asn1);
+        $this->_mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence', $asn1);
+        $this->_mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence', $asn1);
 
         $cert = $asn1->encodeDER($cert, $this->Certificate);
 
@@ -1550,16 +1615,16 @@ class File_X509
      * Map extension values from octet string to extension-specific internal
      *   format.
      *
-     * @param Array ref $root
-     * @param String $path
-     * @param Object $asn1
+     * @param array ref $root
+     * @param string $path
+     * @param object $asn1
      * @access private
      */
     function _mapInExtensions(&$root, $path, $asn1)
     {
-        $extensions = &$this->_subArray($root, $path);
+        $extensions = &$this->_subArrayUnchecked($root, $path);
 
-        if (is_array($extensions)) {
+        if ($extensions) {
             for ($i = 0; $i < count($extensions); $i++) {
                 $id = $extensions[$i]['extnId'];
                 $value = &$extensions[$i]['extnValue'];
@@ -1589,7 +1654,7 @@ class File_X509
                             }
                         }
                     }
-                } elseif ($map) {
+                } else {
                     $value = base64_encode($value);
                 }
             }
@@ -1600,9 +1665,9 @@ class File_X509
      * Map extension values from extension-specific internal format to
      *   octet string.
      *
-     * @param Array ref $root
-     * @param String $path
-     * @param Object $asn1
+     * @param array ref $root
+     * @param string $path
+     * @param object $asn1
      * @access private
      */
     function _mapOutExtensions(&$root, $path, $asn1)
@@ -1612,6 +1677,10 @@ class File_X509
         if (is_array($extensions)) {
             $size = count($extensions);
             for ($i = 0; $i < $size; $i++) {
+                if (is_object($extensions[$i]) && strtolower(get_class($extensions[$i])) == 'file_asn1_element') {
+                    continue;
+                }
+
                 $id = $extensions[$i]['extnId'];
                 $value = &$extensions[$i]['extnValue'];
 
@@ -1662,9 +1731,9 @@ class File_X509
      * Map attribute values from ANY type to attribute-specific internal
      *   format.
      *
-     * @param Array ref $root
-     * @param String $path
-     * @param Object $asn1
+     * @param array ref $root
+     * @param string $path
+     * @param object $asn1
      * @access private
      */
     function _mapInAttributes(&$root, $path, $asn1)
@@ -1687,7 +1756,7 @@ class File_X509
                             if ($mapped !== false) {
                                 $values[$j] = $mapped;
                             }
-                            if ($id == 'pkcs-9-at-extensionRequest') {
+                            if ($id == 'pkcs-9-at-extensionRequest' && $this->_isSubArrayValid($values, $j)) {
                                 $this->_mapInExtensions($values, $j, $asn1);
                             }
                         } elseif ($map) {
@@ -1703,9 +1772,9 @@ class File_X509
      * Map attribute values from attribute-specific internal format to
      *   ANY type.
      *
-     * @param Array ref $root
-     * @param String $path
-     * @param Object $asn1
+     * @param array ref $root
+     * @param string $path
+     * @param object $asn1
      * @access private
      */
     function _mapOutAttributes(&$root, $path, $asn1)
@@ -1742,12 +1811,74 @@ class File_X509
         }
     }
 
+    /**
+     * Map DN values from ANY type to DN-specific internal
+     *   format.
+     *
+     * @param array ref $root
+     * @param string $path
+     * @param object $asn1
+     * @access private
+     */
+    function _mapInDNs(&$root, $path, $asn1)
+    {
+        $dns = &$this->_subArray($root, $path);
+
+        if (is_array($dns)) {
+            for ($i = 0; $i < count($dns); $i++) {
+                for ($j = 0; $j < count($dns[$i]); $j++) {
+                    $type = $dns[$i][$j]['type'];
+                    $value = &$dns[$i][$j]['value'];
+                    if (is_object($value) && strtolower(get_class($value)) == 'file_asn1_element') {
+                        $map = $this->_getMapping($type);
+                        if (!is_bool($map)) {
+                            $decoded = $asn1->decodeBER($value);
+                            $value = $asn1->asn1map($decoded[0], $map);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Map DN values from DN-specific internal format to
+     *   ANY type.
+     *
+     * @param array ref $root
+     * @param string $path
+     * @param object $asn1
+     * @access private
+     */
+    function _mapOutDNs(&$root, $path, $asn1)
+    {
+        $dns = &$this->_subArray($root, $path);
+
+        if (is_array($dns)) {
+            $size = count($dns);
+            for ($i = 0; $i < $size; $i++) {
+                for ($j = 0; $j < count($dns[$i]); $j++) {
+                    $type = $dns[$i][$j]['type'];
+                    $value = &$dns[$i][$j]['value'];
+                    if (is_object($value) && strtolower(get_class($value)) == 'file_asn1_element') {
+                        continue;
+                    }
+
+                    $map = $this->_getMapping($type);
+                    if (!is_bool($map)) {
+                        $value = new File_ASN1_Element($asn1->encodeDER($value, $map));
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Associate an extension ID to an extension mapping
      *
-     * @param String $extnId
+     * @param string $extnId
      * @access private
-     * @return Mixed
+     * @return mixed
      */
     function _getMapping($extnId)
     {
@@ -1774,6 +1905,8 @@ class File_X509
                 return $this->AuthorityInfoAccessSyntax;
             case 'id-ce-subjectAltName':
                 return $this->SubjectAltName;
+            case 'id-ce-subjectDirectoryAttributes':
+                return $this->SubjectDirectoryAttributes;
             case 'id-ce-privateKeyUsagePeriod':
                 return $this->PrivateKeyUsagePeriod;
             case 'id-ce-issuerAltName':
@@ -1833,6 +1966,8 @@ class File_X509
                 return $this->CertificateIssuer;
             case 'id-ce-holdInstructionCode':
                 return $this->HoldInstructionCode;
+            case 'id-at-postalAddress':
+                return $this->PostalAddress;
         }
 
         return false;
@@ -1841,9 +1976,9 @@ class File_X509
     /**
      * Load an X.509 certificate as a certificate authority
      *
-     * @param String $cert
+     * @param string $cert
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function loadCA($cert)
     {
@@ -1908,9 +2043,9 @@ class File_X509
      * component or component fragment. E.g., *.a.com matches foo.a.com but
      * not bar.foo.a.com. f*.com matches foo.com but not bar.com.
      *
-     * @param String $url
+     * @param string $url
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function validateURL($url)
     {
@@ -1966,7 +2101,7 @@ class File_X509
      *
      * If $date isn't defined it is assumed to be the current date.
      *
-     * @param Integer $date optional
+     * @param int $date optional
      * @access public
      */
     function validateDate($date = null)
@@ -2005,9 +2140,9 @@ class File_X509
      *
      * The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}.
      *
-     * @param Boolean $caonly optional
+     * @param bool $caonly optional
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function validateSignature($caonly = true)
     {
@@ -2024,14 +2159,16 @@ class File_X509
         switch (true) {
             case isset($this->currentCert['tbsCertificate']):
                 // self-signed cert
-                if ($this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']) {
-                    $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
-                    $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
-                    switch (true) {
-                        case !is_array($authorityKey):
-                        case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
-                            $signingCert = $this->currentCert; // working cert
-                    }
+                switch (true) {
+                    case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']:
+                    case defined('FILE_X509_IGNORE_TYPE') && $this->getIssuerDN(FILE_X509_DN_STRING) === $this->getDN(FILE_X509_DN_STRING):
+                        $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
+                        $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
+                        switch (true) {
+                            case !is_array($authorityKey):
+                            case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+                                $signingCert = $this->currentCert; // working cert
+                        }
                 }
 
                 if (!empty($this->CAs)) {
@@ -2039,15 +2176,17 @@ class File_X509
                         // even if the cert is a self-signed one we still want to see if it's a CA;
                         // if not, we'll conditionally return an error
                         $ca = $this->CAs[$i];
-                        if ($this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) {
-                            $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
-                            $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
-                            switch (true) {
-                                case !is_array($authorityKey):
-                                case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
-                                    $signingCert = $ca; // working cert
-                                    break 2;
-                            }
+                        switch (true) {
+                            case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']:
+                            case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(FILE_X509_DN_STRING, $this->currentCert['tbsCertificate']['issuer']) === $this->getDN(FILE_X509_DN_STRING, $ca['tbsCertificate']['subject']):
+                                $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
+                                $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
+                                switch (true) {
+                                    case !is_array($authorityKey):
+                                    case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+                                        $signingCert = $ca; // working cert
+                                        break 3;
+                                }
                         }
                     }
                     if (count($this->CAs) == $i && $caonly) {
@@ -2083,15 +2222,17 @@ class File_X509
                 if (!empty($this->CAs)) {
                     for ($i = 0; $i < count($this->CAs); $i++) {
                         $ca = $this->CAs[$i];
-                        if ($this->currentCert['tbsCertList']['issuer'] === $ca['tbsCertificate']['subject']) {
-                            $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
-                            $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
-                            switch (true) {
-                                case !is_array($authorityKey):
-                                case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
-                                    $signingCert = $ca; // working cert
-                                    break 2;
-                            }
+                        switch (true) {
+                            case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertList']['issuer'] === $ca['tbsCertificate']['subject']:
+                            case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(FILE_X509_DN_STRING, $this->currentCert['tbsCertList']['issuer']) === $this->getDN(FILE_X509_DN_STRING, $ca['tbsCertificate']['subject']):
+                                $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
+                                $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
+                                switch (true) {
+                                    case !is_array($authorityKey):
+                                    case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+                                        $signingCert = $ca; // working cert
+                                        break 3;
+                                }
                         }
                     }
                 }
@@ -2115,13 +2256,13 @@ class File_X509
      *
      * Returns true if the signature is verified, false if it is not correct or null on error
      *
-     * @param String $publicKeyAlgorithm
-     * @param String $publicKey
-     * @param String $signatureAlgorithm
-     * @param String $signature
-     * @param String $signatureSubject
+     * @param string $publicKeyAlgorithm
+     * @param string $publicKey
+     * @param string $signatureAlgorithm
+     * @param string $signature
+     * @param string $signatureSubject
      * @access private
-     * @return Integer
+     * @return int
      */
     function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject)
     {
@@ -2163,10 +2304,10 @@ class File_X509
      *
      * Reformats a public key to a format supported by phpseclib (if applicable)
      *
-     * @param String $algorithm
-     * @param String $key
+     * @param string $algorithm
+     * @param string $key
      * @access private
-     * @return String
+     * @return string
      */
     function _reformatKey($algorithm, $key)
     {
@@ -2189,9 +2330,9 @@ class File_X509
      *
      * Takes in a base64 encoded "blob" and returns a human readable IP address
      *
-     * @param String $ip
+     * @param string $ip
      * @access private
-     * @return String
+     * @return string
      */
     function _decodeIP($ip)
     {
@@ -2205,9 +2346,9 @@ class File_X509
      *
      * Takes a human readable IP address into a base64-encoded "blob"
      *
-     * @param String $ip
+     * @param string $ip
      * @access private
-     * @return String
+     * @return string
      */
     function _encodeIP($ip)
     {
@@ -2217,9 +2358,9 @@ class File_X509
     /**
      * "Normalizes" a Distinguished Name property
      *
-     * @param String $propName
+     * @param string $propName
      * @access private
-     * @return Mixed
+     * @return mixed
      */
     function _translateDNProp($propName)
     {
@@ -2298,6 +2439,9 @@ class File_X509
             case 'uniqueidentifier':
             case 'x500uniqueidentifier':
                 return 'id-at-uniqueIdentifier';
+            case 'postaladdress':
+            case 'id-at-postaladdress':
+                return 'id-at-postalAddress';
             default:
                 return false;
         }
@@ -2306,11 +2450,11 @@ class File_X509
     /**
      * Set a Distinguished Name property
      *
-     * @param String $propName
-     * @param Mixed $propValue
-     * @param String $type optional
+     * @param string $propName
+     * @param mixed $propValue
+     * @param string $type optional
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function setDNProp($propName, $propValue, $type = 'utf8String')
     {
@@ -2340,7 +2484,7 @@ class File_X509
     /**
      * Remove Distinguished Name properties
      *
-     * @param String $propName
+     * @param string $propName
      * @access public
      */
     function removeDNProp($propName)
@@ -2367,10 +2511,10 @@ class File_X509
     /**
      * Get Distinguished Name properties
      *
-     * @param String $propName
-     * @param Array $dn optional
-     * @param Boolean $withType optional
-     * @return Mixed
+     * @param string $propName
+     * @param array $dn optional
+     * @param bool $withType optional
+     * @return mixed
      * @access public
      */
     function getDNProp($propName, $dn = null, $withType = false)
@@ -2387,25 +2531,38 @@ class File_X509
             return false;
         }
 
+        $asn1 = new File_ASN1();
+        $asn1->loadOIDs($this->oids);
+        $filters = array();
+        $filters['value'] = array('type' => FILE_ASN1_TYPE_UTF8_STRING);
+        $asn1->loadFilters($filters);
+        $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
         $dn = $dn['rdnSequence'];
         $result = array();
-        $asn1 = new File_ASN1();
         for ($i = 0; $i < count($dn); $i++) {
             if ($dn[$i][0]['type'] == $propName) {
                 $v = $dn[$i][0]['value'];
-                if (!$withType && is_array($v)) {
-                    foreach ($v as $type => $s) {
-                        $type = array_search($type, $asn1->ANYmap, true);
-                        if ($type !== false && isset($asn1->stringTypeSize[$type])) {
-                            $s = $asn1->convert($s, $type);
-                            if ($s !== false) {
-                                $v = $s;
-                                break;
+                if (!$withType) {
+                    if (is_array($v)) {
+                        foreach ($v as $type => $s) {
+                            $type = array_search($type, $asn1->ANYmap, true);
+                            if ($type !== false && isset($asn1->stringTypeSize[$type])) {
+                                $s = $asn1->convert($s, $type);
+                                if ($s !== false) {
+                                    $v = $s;
+                                    break;
+                                }
                             }
                         }
-                    }
-                    if (is_array($v)) {
-                        $v = array_pop($v); // Always strip data type.
+                        if (is_array($v)) {
+                            $v = array_pop($v); // Always strip data type.
+                        }
+                    } elseif (is_object($v) && strtolower(get_class($v)) == 'file_asn1_element') {
+                        $map = $this->_getMapping($propName);
+                        if (!is_bool($map)) {
+                            $decoded = $asn1->decodeBER($v);
+                            $v = $asn1->asn1map($decoded[0], $map);
+                        }
                     }
                 }
                 $result[] = $v;
@@ -2418,11 +2575,11 @@ class File_X509
     /**
      * Set a Distinguished Name
      *
-     * @param Mixed $dn
-     * @param Boolean $merge optional
-     * @param String $type optional
+     * @param mixed $dn
+     * @param bool $merge optional
+     * @param string $type optional
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function setDN($dn, $merge = false, $type = 'utf8String')
     {
@@ -2446,7 +2603,7 @@ class File_X509
         }
 
         // handles everything else
-        $results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE);
+        $results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=|postalAddress=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE);
         for ($i = 1; $i < count($results); $i+=2) {
             $prop = trim($results[$i], ', =/');
             $value = $results[$i + 1];
@@ -2461,10 +2618,10 @@ class File_X509
     /**
      * Get the Distinguished Name for a certificates subject
      *
-     * @param Mixed $format optional
-     * @param Array $dn optional
+     * @param mixed $format optional
+     * @param array $dn optional
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function getDN($format = FILE_X509_DN_ARRAY, $dn = null)
     {
@@ -2481,35 +2638,21 @@ class File_X509
                 $filters = array();
                 $filters['rdnSequence']['value'] = array('type' => FILE_ASN1_TYPE_UTF8_STRING);
                 $asn1->loadFilters($filters);
+                $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
                 return $asn1->encodeDER($dn, $this->Name);
-            case FILE_X509_DN_OPENSSL:
-                $dn = $this->getDN(FILE_X509_DN_STRING, $dn);
-                if ($dn === false) {
-                    return false;
-                }
-                $attrs = preg_split('#((?:^|, *|/)[a-z][a-z0-9]*=)#i', $dn, -1, PREG_SPLIT_DELIM_CAPTURE);
-                $dn = array();
-                for ($i = 1; $i < count($attrs); $i += 2) {
-                    $prop = trim($attrs[$i], ', =/');
-                    $value = $attrs[$i + 1];
-                    if (!isset($dn[$prop])) {
-                        $dn[$prop] = $value;
-                    } else {
-                        $dn[$prop] = array_merge((array) $dn[$prop], array($value));
-                    }
-                }
-                return $dn;
             case FILE_X509_DN_CANON:
                 //  No SEQUENCE around RDNs and all string values normalized as
-                // trimmed lowercase UTF-8 with all spacing  as one blank.
+                // trimmed lowercase UTF-8 with all spacing as one blank.
+                // constructed RDNs will not be canonicalized
                 $asn1 = new File_ASN1();
                 $asn1->loadOIDs($this->oids);
                 $filters = array();
                 $filters['value'] = array('type' => FILE_ASN1_TYPE_UTF8_STRING);
                 $asn1->loadFilters($filters);
                 $result = '';
+                $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
                 foreach ($dn['rdnSequence'] as $rdn) {
-                    foreach ($rdn as $i=>$attr) {
+                    foreach ($rdn as $i => $attr) {
                         $attr = &$rdn[$i];
                         if (is_array($attr['value'])) {
                             foreach ($attr['value'] as $type => $v) {
@@ -2542,7 +2685,13 @@ class File_X509
         // Default is to return a string.
         $start = true;
         $output = '';
+        $result = array();
         $asn1 = new File_ASN1();
+        $asn1->loadOIDs($this->oids);
+        $filters = array();
+        $filters['rdnSequence']['value'] = array('type' => FILE_ASN1_TYPE_UTF8_STRING);
+        $asn1->loadFilters($filters);
+        $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
         foreach ($dn['rdnSequence'] as $field) {
             $prop = $field[0]['type'];
             $value = $field[0]['value'];
@@ -2550,33 +2699,37 @@ class File_X509
             $delim = ', ';
             switch ($prop) {
                 case 'id-at-countryName':
-                    $desc = 'C=';
+                    $desc = 'C';
                     break;
                 case 'id-at-stateOrProvinceName':
-                    $desc = 'ST=';
+                    $desc = 'ST';
                     break;
                 case 'id-at-organizationName':
-                    $desc = 'O=';
+                    $desc = 'O';
                     break;
                 case 'id-at-organizationalUnitName':
-                    $desc = 'OU=';
+                    $desc = 'OU';
                     break;
                 case 'id-at-commonName':
-                    $desc = 'CN=';
+                    $desc = 'CN';
                     break;
                 case 'id-at-localityName':
-                    $desc = 'L=';
+                    $desc = 'L';
                     break;
                 case 'id-at-surname':
-                    $desc = 'SN=';
+                    $desc = 'SN';
                     break;
                 case 'id-at-uniqueIdentifier':
                     $delim = '/';
-                    $desc = 'x500UniqueIdentifier=';
+                    $desc = 'x500UniqueIdentifier';
+                    break;
+                case 'id-at-postalAddress':
+                    $delim = '/';
+                    $desc = 'postalAddress';
                     break;
                 default:
                     $delim = '/';
-                    $desc = preg_replace('#.+-([^-]+)$#', '$1',  $prop) . '=';
+                    $desc = preg_replace('#.+-([^-]+)$#', '$1', $prop);
             }
 
             if (!$start) {
@@ -2596,20 +2749,26 @@ class File_X509
                 if (is_array($value)) {
                     $value = array_pop($value); // Always strip data type.
                 }
+            } elseif (is_object($value) && strtolower(get_class($value)) == 'file_asn1_element') {
+                $callback = create_function('$x', 'return "\x" . bin2hex($x[0]);');
+                $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element));
             }
-            $output.= $desc . $value;
+            $output.= $desc . '=' . $value;
+            $result[$desc] = isset($result[$desc]) ?
+                array_merge((array) $dn[$prop], array($value)) :
+                $value;
             $start = false;
         }
 
-        return $output;
+        return $format == FILE_X509_DN_OPENSSL ? $result : $output;
     }
 
     /**
      * Get the Distinguished Name for a certificate/crl issuer
      *
-     * @param Integer $format optional
+     * @param int $format optional
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function getIssuerDN($format = FILE_X509_DN_ARRAY)
     {
@@ -2629,9 +2788,9 @@ class File_X509
      * Get the Distinguished Name for a certificate/csr subject
      * Alias of getDN()
      *
-     * @param Integer $format optional
+     * @param int $format optional
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function getSubjectDN($format = FILE_X509_DN_ARRAY)
     {
@@ -2652,10 +2811,10 @@ class File_X509
     /**
      * Get an individual Distinguished Name property for a certificate/crl issuer
      *
-     * @param String $propName
-     * @param Boolean $withType optional
+     * @param string $propName
+     * @param bool $withType optional
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function getIssuerDNProp($propName, $withType = false)
     {
@@ -2674,10 +2833,10 @@ class File_X509
     /**
      * Get an individual Distinguished Name property for a certificate/csr subject
      *
-     * @param String $propName
-     * @param Boolean $withType optional
+     * @param string $propName
+     * @param bool $withType optional
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function getSubjectDNProp($propName, $withType = false)
     {
@@ -2699,7 +2858,7 @@ class File_X509
      * Get the certificate chain for the current cert
      *
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function getChain()
     {
@@ -2733,7 +2892,7 @@ class File_X509
                 break;
             }
         }
-        foreach ($chain as $key=>$value) {
+        foreach ($chain as $key => $value) {
             $chain[$key] = new File_X509();
             $chain[$key]->loadX509($value);
         }
@@ -2745,9 +2904,9 @@ class File_X509
      *
      * Key needs to be a Crypt_RSA object
      *
-     * @param Object $key
+     * @param object $key
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function setPublicKey($key)
     {
@@ -2760,7 +2919,7 @@ class File_X509
      *
      * Key needs to be a Crypt_RSA object
      *
-     * @param Object $key
+     * @param object $key
      * @access public
      */
     function setPrivateKey($key)
@@ -2773,7 +2932,7 @@ class File_X509
      *
      * Used for SPKAC CSR's
      *
-     * @param String $challenge
+     * @param string $challenge
      * @access public
      */
     function setChallenge($challenge)
@@ -2787,7 +2946,7 @@ class File_X509
      * Returns a Crypt_RSA object or a false.
      *
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function getPublicKey()
     {
@@ -2828,11 +2987,11 @@ class File_X509
     /**
      * Load a Certificate Signing Request
      *
-     * @param String $csr
+     * @param string $csr
      * @access public
-     * @return Mixed
+     * @return mixed
      */
-    function loadCSR($csr)
+    function loadCSR($csr, $mode = FILE_X509_FORMAT_AUTO_DETECT)
     {
         if (is_array($csr) && isset($csr['certificationRequestInfo'])) {
             unset($this->currentCert);
@@ -2851,7 +3010,13 @@ class File_X509
 
         $asn1 = new File_ASN1();
 
-        $csr = $this->_extractBER($csr);
+        if ($mode != FILE_X509_FORMAT_DER) {
+            $newcsr = $this->_extractBER($csr);
+            if ($mode == FILE_X509_FORMAT_PEM && $csr == $newcsr) {
+                return false;
+            }
+            $csr = $newcsr;
+        }
         $orig = $csr;
 
         if ($csr === false) {
@@ -2873,8 +3038,10 @@ class File_X509
             return false;
         }
 
-        $this->dn = $csr['certificationRequestInfo']['subject'];
         $this->_mapInAttributes($csr, 'certificationRequestInfo/attributes', $asn1);
+        $this->_mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1);
+
+        $this->dn = $csr['certificationRequestInfo']['subject'];
 
         $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
 
@@ -2904,10 +3071,10 @@ class File_X509
     /**
      * Save CSR request
      *
-     * @param Array $csr
-     * @param Integer $format optional
+     * @param array $csr
+     * @param int $format optional
      * @access public
-     * @return String
+     * @return string
      */
     function saveCSR($csr, $format = FILE_X509_FORMAT_PEM)
     {
@@ -2917,13 +3084,16 @@ class File_X509
 
         switch (true) {
             case !($algorithm = $this->_subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')):
-            case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']);
+            case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']):
                 break;
             default:
                 switch ($algorithm) {
                     case 'rsaEncryption':
                         $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']
                             = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])));
+                        $csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['parameters'] = null;
+                        $csr['signatureAlgorithm']['parameters'] = null;
+                        $csr['certificationRequestInfo']['signature']['parameters'] = null;
                 }
         }
 
@@ -2937,6 +3107,7 @@ class File_X509
 
         $asn1->loadFilters($filters);
 
+        $this->_mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1);
         $this->_mapOutAttributes($csr, 'certificationRequestInfo/attributes', $asn1);
         $csr = $asn1->encodeDER($csr, $this->CertificationRequest);
 
@@ -2956,9 +3127,9 @@ class File_X509
      *
      * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen
      *
-     * @param String $csr
+     * @param string $csr
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function loadSPKAC($spkac)
     {
@@ -2974,7 +3145,7 @@ class File_X509
 
         $asn1 = new File_ASN1();
 
-        // OpenSSL produces SPKAC's that are preceeded by the string SPKAC=
+        // OpenSSL produces SPKAC's that are preceded by the string SPKAC=
         $temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac);
         $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
         if ($temp != false) {
@@ -3030,10 +3201,10 @@ class File_X509
     /**
      * Save a SPKAC CSR request
      *
-     * @param Array $csr
-     * @param Integer $format optional
+     * @param array $csr
+     * @param int $format optional
      * @access public
-     * @return String
+     * @return string
      */
     function saveSPKAC($spkac, $format = FILE_X509_FORMAT_PEM)
     {
@@ -3044,7 +3215,7 @@ class File_X509
         $algorithm = $this->_subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm');
         switch (true) {
             case !$algorithm:
-            case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']);
+            case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']):
                 break;
             default:
                 switch ($algorithm) {
@@ -3064,7 +3235,7 @@ class File_X509
                 return $spkac;
             // case FILE_X509_FORMAT_PEM:
             default:
-                // OpenSSL's implementation of SPKAC requires the SPKAC be preceeded by SPKAC= and since there are pretty much
+                // OpenSSL's implementation of SPKAC requires the SPKAC be preceded by SPKAC= and since there are pretty much
                 // no other SPKAC decoders phpseclib will use that same format
                 return 'SPKAC=' . base64_encode($spkac);
         }
@@ -3073,11 +3244,11 @@ class File_X509
     /**
      * Load a Certificate Revocation List
      *
-     * @param String $crl
+     * @param string $crl
      * @access public
-     * @return Mixed
+     * @return mixed
      */
-    function loadCRL($crl)
+    function loadCRL($crl, $mode = FILE_X509_FORMAT_AUTO_DETECT)
     {
         if (is_array($crl) && isset($crl['tbsCertList'])) {
             $this->currentCert = $crl;
@@ -3087,7 +3258,13 @@ class File_X509
 
         $asn1 = new File_ASN1();
 
-        $crl = $this->_extractBER($crl);
+        if ($mode != FILE_X509_FORMAT_DER) {
+            $newcrl = $this->_extractBER($crl);
+            if ($mode == FILE_X509_FORMAT_PEM && $crl == $newcrl) {
+                return false;
+            }
+            $crl = $newcrl;
+        }
         $orig = $crl;
 
         if ($crl === false) {
@@ -3111,11 +3288,19 @@ class File_X509
 
         $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
 
-        $this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
-        $rclist = &$this->_subArray($crl, 'tbsCertList/revokedCertificates');
-        if (is_array($rclist)) {
-            foreach ($rclist as $i => $extension) {
-                $this->_mapInExtensions($rclist, "$i/crlEntryExtensions", $asn1);
+        $this->_mapInDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1);
+        if ($this->_isSubArrayValid($crl, 'tbsCertList/crlExtensions')) {
+            $this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
+        }
+        if ($this->_isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) {
+            $rclist_ref = &$this->_subArrayUnchecked($crl, 'tbsCertList/revokedCertificates');
+            if ($rclist_ref) {
+                $rclist = $crl['tbsCertList']['revokedCertificates'];
+                foreach ($rclist as $i => $extension) {
+                    if ($this->_isSubArrayValid($rclist, "$i/crlEntryExtensions", $asn1)) {
+                        $this->_mapInExtensions($rclist_ref, "$i/crlEntryExtensions", $asn1);
+                    }
+                }
             }
         }
 
@@ -3128,10 +3313,10 @@ class File_X509
     /**
      * Save Certificate Revocation List.
      *
-     * @param Array $crl
-     * @param Integer $format optional
+     * @param array $crl
+     * @param int $format optional
      * @access public
-     * @return String
+     * @return string
      */
     function saveCRL($crl, $format = FILE_X509_FORMAT_PEM)
     {
@@ -3163,6 +3348,7 @@ class File_X509
 
         $asn1->loadFilters($filters);
 
+        $this->_mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1);
         $this->_mapOutExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
         $rclist = &$this->_subArray($crl, 'tbsCertList/revokedCertificates');
         if (is_array($rclist)) {
@@ -3190,17 +3376,17 @@ class File_X509
      *  - 5.1.2.6 Revoked Certificates
      * by choosing utcTime iff year of date given is before 2050 and generalTime else.
      *
-     * @param String $date in format date('D, d M Y H:i:s O')
+     * @param string $date in format date('D, d M Y H:i:s O')
      * @access private
-     * @return Array
+     * @return array
      */
     function _timeField($date)
     {
         $year = @gmdate("Y", @strtotime($date)); // the same way ASN1.php parses this
         if ($year < 2050) {
-           return array('utcTime' => $date);
+            return array('utcTime' => $date);
         } else {
-           return array('generalTime' => $date);
+            return array('generalTime' => $date);
         }
     }
 
@@ -3213,9 +3399,9 @@ class File_X509
      *
      * @param File_X509 $issuer
      * @param File_X509 $subject
-     * @param String $signatureAlgorithm optional
+     * @param string $signatureAlgorithm optional
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption')
     {
@@ -3254,7 +3440,7 @@ class File_X509
             if (isset($subject->domains)) {
                 $this->removeExtension('id-ce-subjectAltName');
             }
-        } else if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) {
+        } elseif (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) {
             return false;
         } else {
             if (!isset($subject->publicKey)) {
@@ -3263,7 +3449,21 @@ class File_X509
 
             $startDate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
             $endDate = !empty($this->endDate) ? $this->endDate : @date('D, d M Y H:i:s O', strtotime('+1 year'));
-            $serialNumber = !empty($this->serialNumber) ? $this->serialNumber : new Math_BigInteger();
+            if (!empty($this->serialNumber)) {
+                $serialNumber = $this->serialNumber;
+            } else {
+                if (!function_exists('crypt_random_string')) {
+                    include_once 'Crypt/Random.php';
+                }
+                /* "The serial number MUST be a positive integer"
+                   "Conforming CAs MUST NOT use serialNumber values longer than 20 octets."
+                    -- https://tools.ietf.org/html/rfc5280#section-4.1.2.2
+
+                   for the integer to be positive the leading bit needs to be 0 hence the
+                   application of a bitmap
+                */
+                $serialNumber = new Math_BigInteger(crypt_random_string(20) & ("\x7F" . str_repeat("\xFF", 19)), 256);
+            }
 
             $this->currentCert = array(
                 'tbsCertificate' =>
@@ -3279,8 +3479,8 @@ class File_X509
                         'subject' => $subject->dn,
                         'subjectPublicKeyInfo' => $subjectPublicKey
                     ),
-                'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
-                'signature'          => false // this is going to be overwritten later
+                    'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+                    'signature'          => false // this is going to be overwritten later
             );
 
             // Copy extensions from CSR.
@@ -3301,8 +3501,7 @@ class File_X509
                     //    )
                     //),
                     'keyIdentifier' => $issuer->currentKeyIdentifier
-                )
-            );
+                ));
             //$extensions = &$this->currentCert['tbsCertificate']['extensions'];
             //if (isset($issuer->serialNumber)) {
             //    $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber;
@@ -3345,7 +3544,8 @@ class File_X509
                 $keyUsage = array();
             }
 
-            $this->setExtension('id-ce-keyUsage',
+            $this->setExtension(
+                'id-ce-keyUsage',
                 array_values(array_unique(array_merge($keyUsage, array('cRLSign', 'keyCertSign'))))
             );
 
@@ -3354,8 +3554,11 @@ class File_X509
                 $basicConstraints = array();
             }
 
-            $this->setExtension('id-ce-basicConstraints',
-                array_unique(array_merge(array('cA' => true), $basicConstraints)), true);
+            $this->setExtension(
+                'id-ce-basicConstraints',
+                array_unique(array_merge(array('cA' => true), $basicConstraints)),
+                true
+            );
 
             if (!isset($subject->currentKeyIdentifier)) {
                 $this->setExtension('id-ce-subjectKeyIdentifier', base64_encode($this->computeKeyIdentifier($this->currentCert)), false, false);
@@ -3380,7 +3583,7 @@ class File_X509
      * Sign a CSR
      *
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function signCSR($signatureAlgorithm = 'sha1WithRSAEncryption')
     {
@@ -3415,8 +3618,8 @@ class File_X509
                         'subject' => $this->dn,
                         'subjectPKInfo' => $publicKey
                     ),
-                'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
-                'signature'          => false // this is going to be overwritten later
+                    'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+                    'signature'          => false // this is going to be overwritten later
             );
         }
 
@@ -3438,7 +3641,7 @@ class File_X509
      * Sign a SPKAC
      *
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function signSPKAC($signatureAlgorithm = 'sha1WithRSAEncryption')
     {
@@ -3480,8 +3683,8 @@ class File_X509
                         // crypt_random_string(8) & str_repeat("\x7F", 8)
                         'challenge' => !empty($this->challenge) ? $this->challenge : ''
                     ),
-                'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
-                'signature'          => false // this is going to be overwritten later
+                    'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+                    'signature'          => false // this is going to be overwritten later
             );
         }
 
@@ -3506,9 +3709,9 @@ class File_X509
      *
      * @param File_X509 $issuer
      * @param File_X509 $crl
-     * @param String $signatureAlgorithm optional
+     * @param string $signatureAlgorithm optional
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function signCRL($issuer, $crl, $signatureAlgorithm = 'sha1WithRSAEncryption')
     {
@@ -3533,8 +3736,8 @@ class File_X509
                         'issuer' => false, // this is going to be overwritten later
                         'thisUpdate' => $this->_timeField($thisUpdate) // $this->setStartDate()
                     ),
-                'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
-                'signature'          => false // this is going to be overwritten later
+                    'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+                    'signature'          => false // this is going to be overwritten later
             );
         }
 
@@ -3552,6 +3755,11 @@ class File_X509
             $crlNumber = $this->serialNumber;
         } else {
             $crlNumber = $this->getExtension('id-ce-cRLNumber');
+            // "The CRL number is a non-critical CRL extension that conveys a
+            //  monotonically increasing sequence number for a given CRL scope and
+            //  CRL issuer.  This extension allows users to easily determine when a
+            //  particular CRL supersedes another CRL."
+            // -- https://tools.ietf.org/html/rfc5280#section-5.2.3
             $crlNumber = $crlNumber !== false ? $crlNumber->add(new Math_BigInteger(1)) : null;
         }
 
@@ -3590,8 +3798,7 @@ class File_X509
                         //    )
                         //),
                         'keyIdentifier' => $issuer->currentKeyIdentifier
-                    )
-                );
+                    ));
                 //$extensions = &$tbsCertList['crlExtensions'];
                 //if (isset($issuer->serialNumber)) {
                 //    $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber;
@@ -3629,11 +3836,11 @@ class File_X509
     /**
      * X.509 certificate signing helper function.
      *
-     * @param Object $key
+     * @param object $key
      * @param File_X509 $subject
-     * @param String $signatureAlgorithm
+     * @param string $signatureAlgorithm
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function _sign($key, $signatureAlgorithm)
     {
@@ -3661,7 +3868,7 @@ class File_X509
     /**
      * Set certificate start date
      *
-     * @param String $date
+     * @param string $date
      * @access public
      */
     function setStartDate($date)
@@ -3672,7 +3879,7 @@ class File_X509
     /**
      * Set certificate end date
      *
-     * @param String $date
+     * @param string $date
      * @access public
      */
     function setEndDate($date)
@@ -3697,7 +3904,7 @@ class File_X509
     /**
      * Set Serial Number
      *
-     * @param String $serial
+     * @param string $serial
      * @param $base optional
      * @access public
      */
@@ -3716,14 +3923,82 @@ class File_X509
         $this->caFlag = true;
     }
 
+    /**
+     * Check for validity of subarray
+     *
+     * This is intended for use in conjunction with _subArrayUnchecked(),
+     * implementing the checks included in _subArray() but without copying
+     * a potentially large array by passing its reference by-value to is_array().
+     *
+     * @param array $root
+     * @param string $path
+     * @return boolean
+     * @access private
+     */
+    function _isSubArrayValid($root, $path)
+    {
+        if (!is_array($root)) {
+            return false;
+        }
+
+        foreach (explode('/', $path) as $i) {
+            if (!is_array($root)) {
+                return false;
+            }
+
+            if (!isset($root[$i])) {
+                return true;
+            }
+
+            $root = $root[$i];
+        }
+
+        return true;
+    }
+
+    /**
+     * Get a reference to a subarray
+     *
+     * This variant of _subArray() does no is_array() checking,
+     * so $root should be checked with _isSubArrayValid() first.
+     *
+     * This is here for performance reasons:
+     * Passing a reference (i.e. $root) by-value (i.e. to is_array())
+     * creates a copy. If $root is an especially large array, this is expensive.
+     *
+     * @param array $root
+     * @param string $path  absolute path with / as component separator
+     * @param bool $create optional
+     * @access private
+     * @return array|false
+     */
+    function &_subArrayUnchecked(&$root, $path, $create = false)
+    {
+        $false = false;
+
+        foreach (explode('/', $path) as $i) {
+            if (!isset($root[$i])) {
+                if (!$create) {
+                    return $false;
+                }
+
+                $root[$i] = array();
+            }
+
+            $root = &$root[$i];
+        }
+
+        return $root;
+    }
+
     /**
      * Get a reference to a subarray
      *
      * @param array $root
-     * @param String $path  absolute path with / as component separator
-     * @param Boolean $create optional
+     * @param string $path  absolute path with / as component separator
+     * @param bool $create optional
      * @access private
-     * @return array item ref or false
+     * @return array|false
      */
     function &_subArray(&$root, $path, $create = false)
     {
@@ -3756,10 +4031,10 @@ class File_X509
      * Get a reference to an extension subarray
      *
      * @param array $root
-     * @param String $path optional absolute path with / as component separator
-     * @param Boolean $create optional
+     * @param string $path optional absolute path with / as component separator
+     * @param bool $create optional
      * @access private
-     * @return array ref or false
+     * @return array|false
      */
     function &_extensions(&$root, $path = null, $create = false)
     {
@@ -3810,10 +4085,10 @@ class File_X509
     /**
      * Remove an Extension
      *
-     * @param String $id
-     * @param String $path optional
+     * @param string $id
+     * @param string $path optional
      * @access private
-     * @return Boolean
+     * @return bool
      */
     function _removeExtension($id, $path = null)
     {
@@ -3840,11 +4115,11 @@ class File_X509
      *
      * Returns the extension if it exists and false if not
      *
-     * @param String $id
-     * @param Array $cert optional
-     * @param String $path optional
+     * @param string $id
+     * @param array $cert optional
+     * @param string $path optional
      * @access private
-     * @return Mixed
+     * @return mixed
      */
     function _getExtension($id, $cert = null, $path = null)
     {
@@ -3867,9 +4142,9 @@ class File_X509
      * Returns a list of all extensions in use
      *
      * @param array $cert optional
-     * @param String $path optional
+     * @param string $path optional
      * @access private
-     * @return Array
+     * @return array
      */
     function _getExtensions($cert = null, $path = null)
     {
@@ -3888,13 +4163,13 @@ class File_X509
     /**
      * Set an Extension
      *
-     * @param String $id
-     * @param Mixed $value
-     * @param Boolean $critical optional
-     * @param Boolean $replace optional
-     * @param String $path optional
+     * @param string $id
+     * @param mixed $value
+     * @param bool $critical optional
+     * @param bool $replace optional
+     * @param string $path optional
      * @access private
-     * @return Boolean
+     * @return bool
      */
     function _setExtension($id, $value, $critical = false, $replace = true, $path = null)
     {
@@ -3924,9 +4199,9 @@ class File_X509
     /**
      * Remove a certificate, CSR or CRL Extension
      *
-     * @param String $id
+     * @param string $id
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function removeExtension($id)
     {
@@ -3938,10 +4213,10 @@ class File_X509
      *
      * Returns the extension if it exists and false if not
      *
-     * @param String $id
-     * @param Array $cert optional
+     * @param string $id
+     * @param array $cert optional
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function getExtension($id, $cert = null)
     {
@@ -3953,7 +4228,7 @@ class File_X509
      *
      * @param array $cert optional
      * @access public
-     * @return Array
+     * @return array
      */
     function getExtensions($cert = null)
     {
@@ -3963,12 +4238,12 @@ class File_X509
     /**
      * Set a certificate, CSR or CRL Extension
      *
-     * @param String $id
-     * @param Mixed $value
-     * @param Boolean $critical optional
-     * @param Boolean $replace optional
+     * @param string $id
+     * @param mixed $value
+     * @param bool $critical optional
+     * @param bool $replace optional
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function setExtension($id, $value, $critical = false, $replace = true)
     {
@@ -3978,10 +4253,10 @@ class File_X509
     /**
      * Remove a CSR attribute.
      *
-     * @param String $id
-     * @param Integer $disposition optional
+     * @param string $id
+     * @param int $disposition optional
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function removeAttribute($id, $disposition = FILE_X509_ATTR_ALL)
     {
@@ -4028,11 +4303,11 @@ class File_X509
      *
      * Returns the attribute if it exists and false if not
      *
-     * @param String $id
-     * @param Integer $disposition optional
-     * @param Array $csr optional
+     * @param string $id
+     * @param int $disposition optional
+     * @param array $csr optional
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function getAttribute($id, $disposition = FILE_X509_ATTR_ALL, $csr = null)
     {
@@ -4072,7 +4347,7 @@ class File_X509
      *
      * @param array $csr optional
      * @access public
-     * @return Array
+     * @return array
      */
     function getAttributes($csr = null)
     {
@@ -4095,11 +4370,11 @@ class File_X509
     /**
      * Set a CSR attribute
      *
-     * @param String $id
-     * @param Mixed $value
-     * @param Boolean $disposition optional
+     * @param string $id
+     * @param mixed $value
+     * @param bool $disposition optional
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function setAttribute($id, $value, $disposition = FILE_X509_ATTR_ALL)
     {
@@ -4124,7 +4399,7 @@ class File_X509
                     case $disposition == FILE_X509_ATTR_APPEND:
                         $last = $key;
                         break;
-                    case $disposition >= $n;
+                    case $disposition >= $n:
                         $disposition -= $n;
                         break;
                     default:
@@ -4153,7 +4428,7 @@ class File_X509
      *
      * This is used by the id-ce-authorityKeyIdentifier and the id-ce-subjectKeyIdentifier extensions.
      *
-     * @param String $value
+     * @param string $value
      * @access public
      */
     function setKeyIdentifier($value)
@@ -4178,10 +4453,10 @@ class File_X509
      * - File_ASN1_Element object
      * - PEM or DER string
      *
-     * @param Mixed $key optional
-     * @param Integer $method optional
+     * @param mixed $key optional
+     * @param int $method optional
      * @access public
-     * @return String binary key identifier
+     * @return string binary key identifier
      */
     function computeKeyIdentifier($key = null, $method = 1)
     {
@@ -4261,7 +4536,7 @@ class File_X509
      * Format a public key as appropriate
      *
      * @access private
-     * @return Array
+     * @return array
      */
     function _formatSubjectPublicKey()
     {
@@ -4287,7 +4562,7 @@ class File_X509
      * Set the domain name's which the cert is to be valid for
      *
      * @access public
-     * @return Array
+     * @return array
      */
     function setDomain()
     {
@@ -4300,7 +4575,7 @@ class File_X509
      * Set the IP Addresses's which the cert is to be valid for
      *
      * @access public
-     * @param String $ipAddress optional
+     * @param string $ipAddress optional
      */
     function setIPAddress()
     {
@@ -4317,8 +4592,8 @@ class File_X509
      * Helper function to build domain array
      *
      * @access private
-     * @param String $domain
-     * @return Array
+     * @param string $domain
+     * @return array
      */
     function _dnsName($domain)
     {
@@ -4331,8 +4606,8 @@ class File_X509
      * (IPv6 is not currently supported)
      *
      * @access private
-     * @param String $address
-     * @return Array
+     * @param string $address
+     * @return array
      */
     function _iPAddress($address)
     {
@@ -4343,10 +4618,10 @@ class File_X509
      * Get the index of a revoked certificate.
      *
      * @param array $rclist
-     * @param String $serial
-     * @param Boolean $create optional
+     * @param string $serial
+     * @param bool $create optional
      * @access private
-     * @return Integer or false
+     * @return int|false
      */
     function _revokedCertificate(&$rclist, $serial, $create = false)
     {
@@ -4371,10 +4646,10 @@ class File_X509
     /**
      * Revoke a certificate.
      *
-     * @param String $serial
-     * @param String $date optional
+     * @param string $serial
+     * @param string $date optional
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function revoke($serial, $date = null)
     {
@@ -4382,7 +4657,6 @@ class File_X509
             if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) {
                 if ($this->_revokedCertificate($rclist, $serial) === false) { // If not yet revoked
                     if (($i = $this->_revokedCertificate($rclist, $serial, true)) !== false) {
-
                         if (!empty($date)) {
                             $rclist[$i]['revocationDate'] = $this->_timeField($date);
                         }
@@ -4399,9 +4673,9 @@ class File_X509
     /**
      * Unrevoke a certificate.
      *
-     * @param String $serial
+     * @param string $serial
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function unrevoke($serial)
     {
@@ -4419,9 +4693,9 @@ class File_X509
     /**
      * Get a revoked certificate.
      *
-     * @param String $serial
+     * @param string $serial
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function getRevoked($serial)
     {
@@ -4465,10 +4739,10 @@ class File_X509
     /**
      * Remove a Revoked Certificate Extension
      *
-     * @param String $serial
-     * @param String $id
+     * @param string $serial
+     * @param string $id
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function removeRevokedCertificateExtension($serial, $id)
     {
@@ -4486,11 +4760,11 @@ class File_X509
      *
      * Returns the extension if it exists and false if not
      *
-     * @param String $serial
-     * @param String $id
-     * @param Array $crl optional
+     * @param string $serial
+     * @param string $id
+     * @param array $crl optional
      * @access public
-     * @return Mixed
+     * @return mixed
      */
     function getRevokedCertificateExtension($serial, $id, $crl = null)
     {
@@ -4500,7 +4774,7 @@ class File_X509
 
         if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) {
             if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
-                return $this->_getExtension($id, $crl,  "tbsCertList/revokedCertificates/$i/crlEntryExtensions");
+                return $this->_getExtension($id, $crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions");
             }
         }
 
@@ -4510,10 +4784,10 @@ class File_X509
     /**
      * Returns a list of all extensions in use for a given revoked certificate
      *
-     * @param String $serial
+     * @param string $serial
      * @param array $crl optional
      * @access public
-     * @return Array
+     * @return array
      */
     function getRevokedCertificateExtensions($serial, $crl = null)
     {
@@ -4533,13 +4807,13 @@ class File_X509
     /**
      * Set a Revoked Certificate Extension
      *
-     * @param String $serial
-     * @param String $id
-     * @param Mixed $value
-     * @param Boolean $critical optional
-     * @param Boolean $replace optional
+     * @param string $serial
+     * @param string $id
+     * @param mixed $value
+     * @param bool $critical optional
+     * @param bool $replace optional
      * @access public
-     * @return Boolean
+     * @return bool
      */
     function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true)
     {
@@ -4558,8 +4832,8 @@ class File_X509
      * Extract raw BER from Base64 encoding
      *
      * @access private
-     * @param String $str
-     * @return String
+     * @param string $str
+     * @return string
      */
     function _extractBER($str)
     {
@@ -4572,7 +4846,7 @@ class File_X509
          * subject=/O=organization/OU=org unit/CN=common name
          * issuer=/O=organization/CN=common name
          */
-        $temp = preg_replace('#.*?^-+[^-]+-+#ms', '', $str, 1);
+        $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
         // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
         $temp = preg_replace('#-+[^-]+-+#', '', $temp);
         // remove new lines
@@ -4580,4 +4854,31 @@ class File_X509
         $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
         return $temp != false ? $temp : $str;
     }
+
+    /**
+     * Returns the OID corresponding to a name
+     *
+     * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if
+     * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version
+     * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able
+     * to work from version to version.
+     *
+     * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that
+     * what's being passed to it already is an OID and return that instead. A few examples.
+     *
+     * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1'
+     * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1'
+     * getOID('zzz') == 'zzz'
+     *
+     * @access public
+     * @return string
+     */
+    function getOID($name)
+    {
+        static $reverseMap;
+        if (!isset($reverseMap)) {
+            $reverseMap = array_flip($this->oids);
+        }
+        return isset($reverseMap[$name]) ? $reverseMap[$name] : $name;
+    }
 }
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
index 8e54f741e98ea4436ae92ee13d3e7d61454e86fe..192ce82f34c3efe6bf37a55e589f66a2a3581a7a 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
@@ -72,27 +72,27 @@
  * Reduction constants
  *
  * @access private
- * @see Math_BigInteger::_reduce()
+ * @see self::_reduce()
  */
 /**
- * @see Math_BigInteger::_montgomery()
- * @see Math_BigInteger::_prepMontgomery()
+ * @see self::_montgomery()
+ * @see self::_prepMontgomery()
  */
 define('MATH_BIGINTEGER_MONTGOMERY', 0);
 /**
- * @see Math_BigInteger::_barrett()
+ * @see self::_barrett()
  */
 define('MATH_BIGINTEGER_BARRETT', 1);
 /**
- * @see Math_BigInteger::_mod2()
+ * @see self::_mod2()
  */
 define('MATH_BIGINTEGER_POWEROF2', 2);
 /**
- * @see Math_BigInteger::_remainder()
+ * @see self::_remainder()
  */
 define('MATH_BIGINTEGER_CLASSIC', 3);
 /**
- * @see Math_BigInteger::__clone()
+ * @see self::__clone()
  */
 define('MATH_BIGINTEGER_NONE', 4);
 /**#@-*/
@@ -117,8 +117,8 @@ define('MATH_BIGINTEGER_SIGN', 1);
 
 /**#@+
  * @access private
- * @see Math_BigInteger::_montgomery()
- * @see Math_BigInteger::_barrett()
+ * @see self::_montgomery()
+ * @see self::_barrett()
  */
 /**
  * Cache constants
@@ -136,7 +136,7 @@ define('MATH_BIGINTEGER_DATA', 1);
  * Mode constants.
  *
  * @access private
- * @see Math_BigInteger::Math_BigInteger()
+ * @see self::Math_BigInteger()
  */
 /**
  * To use the pure-PHP implementation
@@ -178,7 +178,7 @@ class Math_BigInteger
     /**
      * Holds the BigInteger's value.
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $value;
@@ -186,23 +186,15 @@ class Math_BigInteger
     /**
      * Holds the BigInteger's magnitude.
      *
-     * @var Boolean
+     * @var bool
      * @access private
      */
     var $is_negative = false;
 
-    /**
-     * Random number generator function
-     *
-     * @see setRandomGenerator()
-     * @access private
-     */
-    var $generator = 'mt_rand';
-
     /**
      * Precision
      *
-     * @see setPrecision()
+     * @see self::setPrecision()
      * @access private
      */
     var $precision = -1;
@@ -210,7 +202,7 @@ class Math_BigInteger
     /**
      * Precision Bitmask
      *
-     * @see setPrecision()
+     * @see self::setPrecision()
      * @access private
      */
     var $bitmask = false;
@@ -222,9 +214,9 @@ class Math_BigInteger
      * a variable that'll be serializable regardless of whether or not extensions are being used.  Unlike $this->value,
      * however, $this->hex is only calculated when $this->__sleep() is called.
      *
-     * @see __sleep()
-     * @see __wakeup()
-     * @var String
+     * @see self::__sleep()
+     * @see self::__wakeup()
+     * @var string
      * @access private
      */
     var $hex;
@@ -246,14 +238,14 @@ class Math_BigInteger
      * ?>
      * </code>
      *
-     * @param optional $x base-10 number or base-$base number if $base set.
-     * @param optional integer $base
+     * @param $x base-10 number or base-$base number if $base set.
+     * @param int $base
      * @return Math_BigInteger
      * @access public
      */
-    function Math_BigInteger($x = 0, $base = 10)
+    function __construct($x = 0, $base = 10)
     {
-        if ( !defined('MATH_BIGINTEGER_MODE') ) {
+        if (!defined('MATH_BIGINTEGER_MODE')) {
             switch (true) {
                 case extension_loaded('gmp'):
                     define('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_GMP);
@@ -266,7 +258,7 @@ class Math_BigInteger
             }
         }
 
-        if (function_exists('openssl_public_encrypt') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
+        if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
             // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
             ob_start();
             @phpinfo();
@@ -294,6 +286,7 @@ class Math_BigInteger
                 case !isset($versions['Header']):
                 case !isset($versions['Library']):
                 case $versions['Header'] == $versions['Library']:
+                case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0:
                     define('MATH_BIGINTEGER_OPENSSL_ENABLED', true);
                     break;
                 default:
@@ -334,7 +327,7 @@ class Math_BigInteger
             }
         }
 
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 switch (true) {
                     case is_resource($x) && get_resource_type($x) == 'GMP integer':
@@ -364,8 +357,8 @@ class Math_BigInteger
                     $x = ~$x;
                     $this->is_negative = true;
                 }
-            case  256:
-                switch ( MATH_BIGINTEGER_MODE ) {
+            case 256:
+                switch (MATH_BIGINTEGER_MODE) {
                     case MATH_BIGINTEGER_MODE_GMP:
                         $sign = $this->is_negative ? '-' : '';
                         $this->value = gmp_init($sign . '0x' . bin2hex($x));
@@ -401,7 +394,7 @@ class Math_BigInteger
                     $this->value = $temp->value;
                 }
                 break;
-            case  16:
+            case 16:
             case -16:
                 if ($base > 0 && $x[0] == '-') {
                     $this->is_negative = true;
@@ -416,20 +409,20 @@ class Math_BigInteger
                     $x = bin2hex(~pack('H*', $x));
                 }
 
-                switch ( MATH_BIGINTEGER_MODE ) {
+                switch (MATH_BIGINTEGER_MODE) {
                     case MATH_BIGINTEGER_MODE_GMP:
                         $temp = $this->is_negative ? '-0x' . $x : '0x' . $x;
                         $this->value = gmp_init($temp);
                         $this->is_negative = false;
                         break;
                     case MATH_BIGINTEGER_MODE_BCMATH:
-                        $x = ( strlen($x) & 1 ) ? '0' . $x : $x;
+                        $x = (strlen($x) & 1) ? '0' . $x : $x;
                         $temp = new Math_BigInteger(pack('H*', $x), 256);
                         $this->value = $this->is_negative ? '-' . $temp->value : $temp->value;
                         $this->is_negative = false;
                         break;
                     default:
-                        $x = ( strlen($x) & 1 ) ? '0' . $x : $x;
+                        $x = (strlen($x) & 1) ? '0' . $x : $x;
                         $temp = new Math_BigInteger(pack('H*', $x), 256);
                         $this->value = $temp->value;
                 }
@@ -439,14 +432,14 @@ class Math_BigInteger
                     $this->value = $temp->value;
                 }
                 break;
-            case  10:
+            case 10:
             case -10:
                 // (?<!^)(?:-).*: find any -'s that aren't at the beginning and then any characters that follow that
                 // (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
                 // [^-0-9].*: find any non-numeric characters and then any characters that follow that
                 $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
 
-                switch ( MATH_BIGINTEGER_MODE ) {
+                switch (MATH_BIGINTEGER_MODE) {
                     case MATH_BIGINTEGER_MODE_GMP:
                         $this->value = gmp_init($x);
                         break;
@@ -476,7 +469,7 @@ class Math_BigInteger
                         $this->value = $temp->value;
                 }
                 break;
-            case  2: // base-2 support originally implemented by Lluis Pamies - thanks!
+            case 2: // base-2 support originally implemented by Lluis Pamies - thanks!
             case -2:
                 if ($base > 0 && $x[0] == '-') {
                     $this->is_negative = true;
@@ -507,6 +500,19 @@ class Math_BigInteger
         }
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @param $x base-10 number or base-$base number if $base set.
+     * @param int $base
+     * @access public
+     */
+    function Math_BigInteger($x = 0, $base = 10)
+    {
+        $this->__construct($x, $base);
+    }
+
     /**
      * Converts a BigInteger to a byte string (eg. base-256).
      *
@@ -524,8 +530,8 @@ class Math_BigInteger
      * ?>
      * </code>
      *
-     * @param Boolean $twos_compliment
-     * @return String
+     * @param bool $twos_compliment
+     * @return string
      * @access public
      * @internal Converts a base-2**26 number to base-2**8
      */
@@ -551,14 +557,14 @@ class Math_BigInteger
             return $comparison < 0 ? ~$bytes : $bytes;
         }
 
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 if (gmp_cmp($this->value, gmp_init(0)) == 0) {
                     return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
                 }
 
                 $temp = gmp_strval(gmp_abs($this->value), 16);
-                $temp = ( strlen($temp) & 1 ) ? '0' . $temp : $temp;
+                $temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
                 $temp = pack('H*', $temp);
 
                 return $this->precision > 0 ?
@@ -621,8 +627,8 @@ class Math_BigInteger
      * ?>
      * </code>
      *
-     * @param Boolean $twos_compliment
-     * @return String
+     * @param bool $twos_compliment
+     * @return string
      * @access public
      * @internal Converts a base-2**26 number to base-2**8
      */
@@ -648,8 +654,8 @@ class Math_BigInteger
      * ?>
      * </code>
      *
-     * @param Boolean $twos_compliment
-     * @return String
+     * @param bool $twos_compliment
+     * @return string
      * @access public
      * @internal Converts a base-2**26 number to base-2**2
      */
@@ -686,13 +692,13 @@ class Math_BigInteger
      * ?>
      * </code>
      *
-     * @return String
+     * @return string
      * @access public
      * @internal Converts a base-2**26 number to base-10**7 (which is pretty much base-10)
      */
     function toString()
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 return gmp_strval($this->value);
             case MATH_BIGINTEGER_MODE_BCMATH:
@@ -738,7 +744,7 @@ class Math_BigInteger
      * {@link http://php.net/language.oop5.basic#51624}
      *
      * @access public
-     * @see __clone()
+     * @see self::__clone()
      * @return Math_BigInteger
      */
     function copy()
@@ -746,7 +752,6 @@ class Math_BigInteger
         $temp = new Math_BigInteger();
         $temp->value = $this->value;
         $temp->is_negative = $this->is_negative;
-        $temp->generator = $this->generator;
         $temp->precision = $this->precision;
         $temp->bitmask = $this->bitmask;
         return $temp;
@@ -775,7 +780,7 @@ class Math_BigInteger
      * call Math_BigInteger::copy(), instead.
      *
      * @access public
-     * @see copy()
+     * @see self::copy()
      * @return Math_BigInteger
      */
     function __clone()
@@ -788,21 +793,17 @@ class Math_BigInteger
      *
      * Will be called, automatically, when serialize() is called on a Math_BigInteger object.
      *
-     * @see __wakeup()
+     * @see self::__wakeup()
      * @access public
      */
     function __sleep()
     {
         $this->hex = $this->toHex(true);
         $vars = array('hex');
-        if ($this->generator != 'mt_rand') {
-            $vars[] = 'generator';
-        }
         if ($this->precision > 0) {
             $vars[] = 'precision';
         }
         return $vars;
-
     }
 
     /**
@@ -810,7 +811,7 @@ class Math_BigInteger
      *
      * Will be called, automatically, when unserialize() is called on a Math_BigInteger object.
      *
-     * @see __sleep()
+     * @see self::__sleep()
      * @access public
      */
     function __wakeup()
@@ -818,13 +819,45 @@ class Math_BigInteger
         $temp = new Math_BigInteger($this->hex, -16);
         $this->value = $temp->value;
         $this->is_negative = $temp->is_negative;
-        $this->setRandomGenerator($this->generator);
         if ($this->precision > 0) {
             // recalculate $this->bitmask
             $this->setPrecision($this->precision);
         }
     }
 
+    /**
+     *  __debugInfo() magic method
+     *
+     * Will be called, automatically, when print_r() or var_dump() are called
+     *
+     * @access public
+     */
+    function __debugInfo()
+    {
+        $opts = array();
+        switch (MATH_BIGINTEGER_MODE) {
+            case MATH_BIGINTEGER_MODE_GMP:
+                $engine = 'gmp';
+                break;
+            case MATH_BIGINTEGER_MODE_BCMATH:
+                $engine = 'bcmath';
+                break;
+            case MATH_BIGINTEGER_MODE_INTERNAL:
+                $engine = 'internal';
+                $opts[] = PHP_INT_SIZE == 8 ? '64-bit' : '32-bit';
+        }
+        if (MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_GMP && defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
+            $opts[] = 'OpenSSL';
+        }
+        if (!empty($opts)) {
+            $engine.= ' (' . implode($opts, ', ') . ')';
+        }
+        return array(
+            'value' => '0x' . $this->toHex(true),
+            'engine' => $engine
+        );
+    }
+
     /**
      * Adds two BigIntegers.
      *
@@ -849,7 +882,7 @@ class Math_BigInteger
      */
     function add($y)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 $temp = new Math_BigInteger();
                 $temp->value = gmp_add($this->value, $y->value);
@@ -874,11 +907,11 @@ class Math_BigInteger
     /**
      * Performs addition.
      *
-     * @param Array $x_value
-     * @param Boolean $x_negative
-     * @param Array $y_value
-     * @param Boolean $y_negative
-     * @return Array
+     * @param array $x_value
+     * @param bool $x_negative
+     * @param array $y_value
+     * @param bool $y_negative
+     * @return array
      * @access private
      */
     function _add($x_value, $x_negative, $y_value, $y_negative)
@@ -891,7 +924,7 @@ class Math_BigInteger
                 MATH_BIGINTEGER_VALUE => $y_value,
                 MATH_BIGINTEGER_SIGN => $y_negative
             );
-        } else if ($y_size == 0) {
+        } elseif ($y_size == 0) {
             return array(
                 MATH_BIGINTEGER_VALUE => $x_value,
                 MATH_BIGINTEGER_SIGN => $x_negative
@@ -899,8 +932,8 @@ class Math_BigInteger
         }
 
         // subtract, if appropriate
-        if ( $x_negative != $y_negative ) {
-            if ( $x_value == $y_value ) {
+        if ($x_negative != $y_negative) {
+            if ($x_value == $y_value) {
                 return array(
                     MATH_BIGINTEGER_VALUE => array(),
                     MATH_BIGINTEGER_SIGN => false
@@ -980,7 +1013,7 @@ class Math_BigInteger
      */
     function subtract($y)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 $temp = new Math_BigInteger();
                 $temp->value = gmp_sub($this->value, $y->value);
@@ -1005,11 +1038,11 @@ class Math_BigInteger
     /**
      * Performs subtraction.
      *
-     * @param Array $x_value
-     * @param Boolean $x_negative
-     * @param Array $y_value
-     * @param Boolean $y_negative
-     * @return Array
+     * @param array $x_value
+     * @param bool $x_negative
+     * @param array $y_value
+     * @param bool $y_negative
+     * @return array
      * @access private
      */
     function _subtract($x_value, $x_negative, $y_value, $y_negative)
@@ -1022,7 +1055,7 @@ class Math_BigInteger
                 MATH_BIGINTEGER_VALUE => $y_value,
                 MATH_BIGINTEGER_SIGN => !$y_negative
             );
-        } else if ($y_size == 0) {
+        } elseif ($y_size == 0) {
             return array(
                 MATH_BIGINTEGER_VALUE => $x_value,
                 MATH_BIGINTEGER_SIGN => $x_negative
@@ -1030,7 +1063,7 @@ class Math_BigInteger
         }
 
         // add, if appropriate (ie. -$x - +$y or +$x - -$y)
-        if ( $x_negative != $y_negative ) {
+        if ($x_negative != $y_negative) {
             $temp = $this->_add($x_value, false, $y_value, false);
             $temp[MATH_BIGINTEGER_SIGN] = $x_negative;
 
@@ -1039,7 +1072,7 @@ class Math_BigInteger
 
         $diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative);
 
-        if ( !$diff ) {
+        if (!$diff) {
             return array(
                 MATH_BIGINTEGER_VALUE => array(),
                 MATH_BIGINTEGER_SIGN => false
@@ -1047,7 +1080,7 @@ class Math_BigInteger
         }
 
         // switch $x and $y around, if appropriate.
-        if ( (!$x_negative && $diff < 0) || ($x_negative && $diff > 0) ) {
+        if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) {
             $temp = $x_value;
             $x_value = $y_value;
             $y_value = $temp;
@@ -1115,7 +1148,7 @@ class Math_BigInteger
      */
     function multiply($x)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 $temp = new Math_BigInteger();
                 $temp->value = gmp_mul($this->value, $x->value);
@@ -1140,11 +1173,11 @@ class Math_BigInteger
     /**
      * Performs multiplication.
      *
-     * @param Array $x_value
-     * @param Boolean $x_negative
-     * @param Array $y_value
-     * @param Boolean $y_negative
-     * @return Array
+     * @param array $x_value
+     * @param bool $x_negative
+     * @param array $y_value
+     * @param bool $y_negative
+     * @return array
      * @access private
      */
     function _multiply($x_value, $x_negative, $y_value, $y_negative)
@@ -1159,7 +1192,7 @@ class Math_BigInteger
         $x_length = count($x_value);
         $y_length = count($y_value);
 
-        if ( !$x_length || !$y_length ) { // a 0 is being multiplied
+        if (!$x_length || !$y_length) { // a 0 is being multiplied
             return array(
                 MATH_BIGINTEGER_VALUE => array(),
                 MATH_BIGINTEGER_SIGN => false
@@ -1179,9 +1212,9 @@ class Math_BigInteger
      *
      * Modeled after 'multiply' in MutableBigInteger.java.
      *
-     * @param Array $x_value
-     * @param Array $y_value
-     * @return Array
+     * @param array $x_value
+     * @param array $y_value
+     * @return array
      * @access private
      */
     function _regularMultiply($x_value, $y_value)
@@ -1189,11 +1222,11 @@ class Math_BigInteger
         $x_length = count($x_value);
         $y_length = count($y_value);
 
-        if ( !$x_length || !$y_length ) { // a 0 is being multiplied
+        if (!$x_length || !$y_length) { // a 0 is being multiplied
             return array();
         }
 
-        if ( $x_length < $y_length ) {
+        if ($x_length < $y_length) {
             $temp = $x_value;
             $x_value = $y_value;
             $y_value = $temp;
@@ -1243,9 +1276,9 @@ class Math_BigInteger
      * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
      * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}.
      *
-     * @param Array $x_value
-     * @param Array $y_value
-     * @return Array
+     * @param array $x_value
+     * @param array $y_value
+     * @return array
      * @access private
      */
     function _karatsuba($x_value, $y_value)
@@ -1282,8 +1315,8 @@ class Math_BigInteger
     /**
      * Performs squaring
      *
-     * @param Array $x
-     * @return Array
+     * @param array $x
+     * @return array
      * @access private
      */
     function _square($x = false)
@@ -1300,13 +1333,13 @@ class Math_BigInteger
      * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} /
      * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information.
      *
-     * @param Array $value
-     * @return Array
+     * @param array $value
+     * @return array
      * @access private
      */
     function _baseSquare($value)
     {
-        if ( empty($value) ) {
+        if (empty($value)) {
             return array();
         }
         $square_value = $this->_array_repeat(0, 2 * count($value));
@@ -1339,8 +1372,8 @@ class Math_BigInteger
      * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
      * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}.
      *
-     * @param Array $value
-     * @return Array
+     * @param array $value
+     * @return array
      * @access private
      */
     function _karatsubaSquare($value)
@@ -1396,13 +1429,13 @@ class Math_BigInteger
      * </code>
      *
      * @param Math_BigInteger $y
-     * @return Array
+     * @return array
      * @access public
      * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}.
      */
     function divide($y)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 $quotient = new Math_BigInteger();
                 $remainder = new Math_BigInteger();
@@ -1439,7 +1472,7 @@ class Math_BigInteger
         }
 
         static $zero;
-        if ( !isset($zero) ) {
+        if (!isset($zero)) {
             $zero = new Math_BigInteger();
         }
 
@@ -1453,16 +1486,16 @@ class Math_BigInteger
 
         $diff = $x->compare($y);
 
-        if ( !$diff ) {
+        if (!$diff) {
             $temp = new Math_BigInteger();
             $temp->value = array(1);
             $temp->is_negative = $x_sign != $y_sign;
             return array($this->_normalize($temp), $this->_normalize(new Math_BigInteger()));
         }
 
-        if ( $diff < 0 ) {
+        if ($diff < 0) {
             // if $x is negative, "add" $y.
-            if ( $x_sign ) {
+            if ($x_sign) {
                 $x = $y->subtract($x);
             }
             return array($this->_normalize(new Math_BigInteger()), $this->_normalize($x));
@@ -1496,7 +1529,7 @@ class Math_BigInteger
         // $temp = $y << ($x_max - $y_max-1) in base 2**26
         $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);
 
-        while ( $x->compare($temp) >= 0 ) {
+        while ($x->compare($temp) >= 0) {
             // calculate the "common residue"
             ++$quotient_value[$x_max - $y_max];
             $x = $x->subtract($temp);
@@ -1512,7 +1545,7 @@ class Math_BigInteger
             );
             $y_window = array(
                 $y_value[$y_max],
-                ( $y_max > 0 ) ? $y_value[$y_max - 1] : 0
+                ($y_max > 0) ? $y_value[$y_max - 1] : 0
             );
 
             $q_index = $i - $y_max - 1;
@@ -1532,7 +1565,7 @@ class Math_BigInteger
 
             $rhs_value = array($x_window[2], $x_window[1], $x_window[0]);
 
-            while ( $lhs->compare($rhs) > 0 ) {
+            while ($lhs->compare($rhs) > 0) {
                 --$quotient_value[$q_index];
 
                 $lhs->value = array($quotient_value[$q_index]);
@@ -1563,7 +1596,7 @@ class Math_BigInteger
         $quotient->is_negative = $x_sign != $y_sign;
 
         // calculate the "common residue", if appropriate
-        if ( $x_sign ) {
+        if ($x_sign) {
             $y->_rshift($shift);
             $x = $y->subtract($x);
         }
@@ -1576,9 +1609,9 @@ class Math_BigInteger
      *
      * abc / x = a00 / x + b0 / x + c / x
      *
-     * @param Array $dividend
-     * @param Array $divisor
-     * @return Array
+     * @param array $dividend
+     * @param array $divisor
+     * @return array
      * @access private
      */
     function _divide_digit($dividend, $divisor)
@@ -1652,7 +1685,7 @@ class Math_BigInteger
             return $this->_normalize($temp->modPow($e, $n));
         }
 
-        if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP ) {
+        if (MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP) {
             $temp = new Math_BigInteger();
             $temp->value = gmp_powm($this->value, $e->value, $n->value);
 
@@ -1675,17 +1708,23 @@ class Math_BigInteger
                 'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent'])
             );
 
-            $RSAPublicKey = pack('Ca*a*a*',
-                48, $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])),
-                $components['modulus'], $components['publicExponent']
+            $RSAPublicKey = pack(
+                'Ca*a*a*',
+                48,
+                $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])),
+                $components['modulus'],
+                $components['publicExponent']
             );
 
             $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
             $RSAPublicKey = chr(0) . $RSAPublicKey;
             $RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey;
 
-            $encapsulated = pack('Ca*a*',
-                48, $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey
+            $encapsulated = pack(
+                'Ca*a*',
+                48,
+                $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)),
+                $rsaOID . $RSAPublicKey
             );
 
             $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
@@ -1699,25 +1738,25 @@ class Math_BigInteger
             }
         }
 
-        if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH ) {
-                $temp = new Math_BigInteger();
-                $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
+        if (MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH) {
+            $temp = new Math_BigInteger();
+            $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
 
-                return $this->_normalize($temp);
+            return $this->_normalize($temp);
         }
 
-        if ( empty($e->value) ) {
+        if (empty($e->value)) {
             $temp = new Math_BigInteger();
             $temp->value = array(1);
             return $this->_normalize($temp);
         }
 
-        if ( $e->value == array(1) ) {
+        if ($e->value == array(1)) {
             list(, $temp) = $this->divide($n);
             return $this->_normalize($temp);
         }
 
-        if ( $e->value == array(2) ) {
+        if ($e->value == array(2)) {
             $temp = new Math_BigInteger();
             $temp->value = $this->_square($this->value);
             list(, $temp) = $temp->divide($n);
@@ -1732,14 +1771,14 @@ class Math_BigInteger
         // made uncallable
 
         // is the modulo odd?
-        if ( $n->value[0] & 1 ) {
+        if ($n->value[0] & 1) {
             return $this->_normalize($this->_slidingWindow($e, $n, MATH_BIGINTEGER_MONTGOMERY));
         }
         // if it's not, it's even
 
         // find the lowest set bit (eg. the max pow of 2 that divides $n)
         for ($i = 0; $i < count($n->value); ++$i) {
-            if ( $n->value[$i] ) {
+            if ($n->value[$i]) {
                 $temp = decbin($n->value[$i]);
                 $j = strlen($temp) - strrpos($temp, '1') - 1;
                 $j+= 26 * $i;
@@ -1754,7 +1793,7 @@ class Math_BigInteger
         $mod2->value = array(1);
         $mod2->_lshift($j);
 
-        $part1 = ( $mod1->value != array(1) ) ? $this->_slidingWindow($e, $mod1, MATH_BIGINTEGER_MONTGOMERY) : new Math_BigInteger();
+        $part1 = ($mod1->value != array(1)) ? $this->_slidingWindow($e, $mod1, MATH_BIGINTEGER_MONTGOMERY) : new Math_BigInteger();
         $part2 = $this->_slidingWindow($e, $mod2, MATH_BIGINTEGER_POWEROF2);
 
         $y1 = $mod2->modInverse($mod1);
@@ -1797,7 +1836,7 @@ class Math_BigInteger
      *
      * @param Math_BigInteger $e
      * @param Math_BigInteger $n
-     * @param Integer $mode
+     * @param int $mode
      * @return Math_BigInteger
      * @access private
      */
@@ -1817,7 +1856,8 @@ class Math_BigInteger
 
         // calculate the appropriate window size.
         // $window_size == 3 if $window_ranges is between 25 and 81, for example.
-        for ($i = 0, $window_size = 1; $e_length > $window_ranges[$i] && $i < count($window_ranges); ++$window_size, ++$i);
+        for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) {
+        }
 
         $n_value = $n->value;
 
@@ -1837,24 +1877,25 @@ class Math_BigInteger
         $result = array(1);
         $result = $this->_prepareReduce($result, $n_value, $mode);
 
-        for ($i = 0; $i < $e_length; ) {
-            if ( !$e_bits[$i] ) {
+        for ($i = 0; $i < $e_length;) {
+            if (!$e_bits[$i]) {
                 $result = $this->_squareReduce($result, $n_value, $mode);
                 ++$i;
             } else {
                 for ($j = $window_size - 1; $j > 0; --$j) {
-                    if ( !empty($e_bits[$i + $j]) ) {
+                    if (!empty($e_bits[$i + $j])) {
                         break;
                     }
                 }
 
-                for ($k = 0; $k <= $j; ++$k) {// eg. the length of substr($e_bits, $i, $j+1)
+                // eg. the length of substr($e_bits, $i, $j + 1)
+                for ($k = 0; $k <= $j; ++$k) {
                     $result = $this->_squareReduce($result, $n_value, $mode);
                 }
 
                 $result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode);
 
-                $i+=$j + 1;
+                $i += $j + 1;
             }
         }
 
@@ -1869,12 +1910,12 @@ class Math_BigInteger
      *
      * For most $modes this will return the remainder.
      *
-     * @see _slidingWindow()
+     * @see self::_slidingWindow()
      * @access private
-     * @param Array $x
-     * @param Array $n
-     * @param Integer $mode
-     * @return Array
+     * @param array $x
+     * @param array $n
+     * @param int $mode
+     * @return array
      */
     function _reduce($x, $n, $mode)
     {
@@ -1906,12 +1947,12 @@ class Math_BigInteger
     /**
      * Modular reduction preperation
      *
-     * @see _slidingWindow()
+     * @see self::_slidingWindow()
      * @access private
-     * @param Array $x
-     * @param Array $n
-     * @param Integer $mode
-     * @return Array
+     * @param array $x
+     * @param array $n
+     * @param int $mode
+     * @return array
      */
     function _prepareReduce($x, $n, $mode)
     {
@@ -1924,13 +1965,13 @@ class Math_BigInteger
     /**
      * Modular multiply
      *
-     * @see _slidingWindow()
+     * @see self::_slidingWindow()
      * @access private
-     * @param Array $x
-     * @param Array $y
-     * @param Array $n
-     * @param Integer $mode
-     * @return Array
+     * @param array $x
+     * @param array $y
+     * @param array $n
+     * @param int $mode
+     * @return array
      */
     function _multiplyReduce($x, $y, $n, $mode)
     {
@@ -1944,12 +1985,12 @@ class Math_BigInteger
     /**
      * Modular square
      *
-     * @see _slidingWindow()
+     * @see self::_slidingWindow()
      * @access private
-     * @param Array $x
-     * @param Array $n
-     * @param Integer $mode
-     * @return Array
+     * @param array $x
+     * @param array $n
+     * @param int $mode
+     * @return array
      */
     function _squareReduce($x, $n, $mode)
     {
@@ -1965,7 +2006,7 @@ class Math_BigInteger
      * Calculates $x%$n, where $n = 2**$e, for some $e.  Since this is basically the same as doing $x & ($n-1),
      * we'll just use this function as a wrapper for doing that.
      *
-     * @see _slidingWindow()
+     * @see self::_slidingWindow()
      * @access private
      * @param Math_BigInteger
      * @return Math_BigInteger
@@ -1995,11 +2036,11 @@ class Math_BigInteger
      * (x >> 1) + (x >> 1) != x / 2 + x / 2.  If x is even, they're the same, but if x is odd, they're not.  See the in-line
      * comments for details.
      *
-     * @see _slidingWindow()
+     * @see self::_slidingWindow()
      * @access private
-     * @param Array $n
-     * @param Array $m
-     * @return Array
+     * @param array $n
+     * @param array $m
+     * @return array
      */
     function _barrett($n, $m)
     {
@@ -2027,7 +2068,7 @@ class Math_BigInteger
 
         // n = 2 * m.length
 
-        if ( ($key = array_search($m, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {
+        if (($key = array_search($m, $cache[MATH_BIGINTEGER_VARIABLE])) === false) {
             $key = count($cache[MATH_BIGINTEGER_VARIABLE]);
             $cache[MATH_BIGINTEGER_VARIABLE][] = $m;
 
@@ -2092,11 +2133,11 @@ class Math_BigInteger
      * For numbers with more than four digits Math_BigInteger::_barrett() is faster.  The difference between that and this
      * is that this function does not fold the denominator into a smaller form.
      *
-     * @see _slidingWindow()
+     * @see self::_slidingWindow()
      * @access private
-     * @param Array $x
-     * @param Array $n
-     * @return Array
+     * @param array $x
+     * @param array $n
+     * @return array
      */
     function _regularBarrett($x, $n)
     {
@@ -2116,7 +2157,7 @@ class Math_BigInteger
             return $temp->value;
         }
 
-        if ( ($key = array_search($n, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {
+        if (($key = array_search($n, $cache[MATH_BIGINTEGER_VARIABLE])) === false) {
             $key = count($cache[MATH_BIGINTEGER_VARIABLE]);
             $cache[MATH_BIGINTEGER_VARIABLE][] = $n;
             $lhs = new Math_BigInteger();
@@ -2163,13 +2204,13 @@ class Math_BigInteger
      *
      * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved.
      *
-     * @see _regularBarrett()
-     * @param Array $x_value
-     * @param Boolean $x_negative
-     * @param Array $y_value
-     * @param Boolean $y_negative
-     * @param Integer $stop
-     * @return Array
+     * @see self::_regularBarrett()
+     * @param array $x_value
+     * @param bool $x_negative
+     * @param array $y_value
+     * @param bool $y_negative
+     * @param int $stop
+     * @return array
      * @access private
      */
     function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop)
@@ -2177,14 +2218,14 @@ class Math_BigInteger
         $x_length = count($x_value);
         $y_length = count($y_value);
 
-        if ( !$x_length || !$y_length ) { // a 0 is being multiplied
+        if (!$x_length || !$y_length) { // a 0 is being multiplied
             return array(
                 MATH_BIGINTEGER_VALUE => array(),
                 MATH_BIGINTEGER_SIGN => false
             );
         }
 
-        if ( $x_length < $y_length ) {
+        if ($x_length < $y_length) {
             $temp = $x_value;
             $x_value = $y_value;
             $y_value = $temp;
@@ -2244,12 +2285,12 @@ class Math_BigInteger
      * improved upon (basically, by using the comba method).  gcd($n, 2) must be equal to one for this function
      * to work correctly.
      *
-     * @see _prepMontgomery()
-     * @see _slidingWindow()
+     * @see self::_prepMontgomery()
+     * @see self::_slidingWindow()
      * @access private
-     * @param Array $x
-     * @param Array $n
-     * @return Array
+     * @param array $x
+     * @param array $n
+     * @return array
      */
     function _montgomery($x, $n)
     {
@@ -2258,7 +2299,7 @@ class Math_BigInteger
             MATH_BIGINTEGER_DATA => array()
         );
 
-        if ( ($key = array_search($n, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {
+        if (($key = array_search($n, $cache[MATH_BIGINTEGER_VARIABLE])) === false) {
             $key = count($cache[MATH_BIGINTEGER_VARIABLE]);
             $cache[MATH_BIGINTEGER_VARIABLE][] = $x;
             $cache[MATH_BIGINTEGER_DATA][] = $this->_modInverse67108864($n);
@@ -2291,13 +2332,13 @@ class Math_BigInteger
      * Interleaves the montgomery reduction and long multiplication algorithms together as described in
      * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36}
      *
-     * @see _prepMontgomery()
-     * @see _montgomery()
+     * @see self::_prepMontgomery()
+     * @see self::_montgomery()
      * @access private
-     * @param Array $x
-     * @param Array $y
-     * @param Array $m
-     * @return Array
+     * @param array $x
+     * @param array $y
+     * @param array $m
+     * @return array
      */
     function _montgomeryMultiply($x, $y, $m)
     {
@@ -2314,7 +2355,7 @@ class Math_BigInteger
             MATH_BIGINTEGER_DATA => array()
         );
 
-        if ( ($key = array_search($m, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {
+        if (($key = array_search($m, $cache[MATH_BIGINTEGER_VARIABLE])) === false) {
             $key = count($cache[MATH_BIGINTEGER_VARIABLE]);
             $cache[MATH_BIGINTEGER_VARIABLE][] = $m;
             $cache[MATH_BIGINTEGER_DATA][] = $this->_modInverse67108864($m);
@@ -2343,12 +2384,12 @@ class Math_BigInteger
     /**
      * Prepare a number for use in Montgomery Modular Reductions
      *
-     * @see _montgomery()
-     * @see _slidingWindow()
+     * @see self::_montgomery()
+     * @see self::_slidingWindow()
      * @access private
-     * @param Array $x
-     * @param Array $n
-     * @return Array
+     * @param array $x
+     * @param array $n
+     * @return array
      */
     function _prepMontgomery($x, $n)
     {
@@ -2382,10 +2423,10 @@ class Math_BigInteger
      *
      * Thanks to Pedro Gimeno Fortea for input!
      *
-     * @see _montgomery()
+     * @see self::_montgomery()
      * @access private
-     * @param Array $x
-     * @return Integer
+     * @param array $x
+     * @return int
      */
     function _modInverse67108864($x) // 2**26 == 67,108,864
     {
@@ -2423,18 +2464,18 @@ class Math_BigInteger
      * </code>
      *
      * @param Math_BigInteger $n
-     * @return mixed false, if no modular inverse exists, Math_BigInteger, otherwise.
+     * @return Math_BigInteger|false
      * @access public
      * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.
      */
     function modInverse($n)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 $temp = new Math_BigInteger();
                 $temp->value = gmp_invert($this->value, $n->value);
 
-                return ( $temp->value === false ) ? false : $this->_normalize($temp);
+                return ($temp->value === false) ? false : $this->_normalize($temp);
         }
 
         static $zero, $one;
@@ -2468,7 +2509,7 @@ class Math_BigInteger
      *
      * Say you have 693 and 609.  The GCD is 21.  Bezout's identity states that there exist integers x and y such that
      * 693*x + 609*y == 21.  In point of fact, there are actually an infinite number of x and y combinations and which
-     * combination is returned is dependant upon which mode is in use.  See
+     * combination is returned is dependent upon which mode is in use.  See
      * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information.
      *
      * Here's an example:
@@ -2495,7 +2536,7 @@ class Math_BigInteger
      */
     function extendedGCD($n)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 extract(gmp_gcdext($this->value, $n->value));
 
@@ -2545,7 +2586,7 @@ class Math_BigInteger
         $g = new Math_BigInteger();
         $g->value = array(1);
 
-        while ( !(($x->value[0] & 1)|| ($y->value[0] & 1)) ) {
+        while (!(($x->value[0] & 1)|| ($y->value[0] & 1))) {
             $x->_rshift(1);
             $y->_rshift(1);
             $g->_lshift(1);
@@ -2562,10 +2603,10 @@ class Math_BigInteger
         $a->value = $d->value = $g->value = array(1);
         $b->value = $c->value = array();
 
-        while ( !empty($u->value) ) {
-            while ( !($u->value[0] & 1) ) {
+        while (!empty($u->value)) {
+            while (!($u->value[0] & 1)) {
                 $u->_rshift(1);
-                if ( (!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1)) ) {
+                if ((!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1))) {
                     $a = $a->add($y);
                     $b = $b->subtract($x);
                 }
@@ -2573,9 +2614,9 @@ class Math_BigInteger
                 $b->_rshift(1);
             }
 
-            while ( !($v->value[0] & 1) ) {
+            while (!($v->value[0] & 1)) {
                 $v->_rshift(1);
-                if ( (!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1)) ) {
+                if ((!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1))) {
                     $c = $c->add($y);
                     $d = $d->subtract($x);
                 }
@@ -2640,7 +2681,7 @@ class Math_BigInteger
     {
         $temp = new Math_BigInteger();
 
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 $temp->value = gmp_abs($this->value);
                 break;
@@ -2667,14 +2708,14 @@ class Math_BigInteger
      * Note how the same comparison operator is used.  If you want to test for equality, use $x->equals($y).
      *
      * @param Math_BigInteger $y
-     * @return Integer < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal.
+     * @return int < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal.
      * @access public
-     * @see equals()
+     * @see self::equals()
      * @internal Could return $this->subtract($x), but that's not as fast as what we do do.
      */
     function compare($y)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 return gmp_cmp($this->value, $y->value);
             case MATH_BIGINTEGER_MODE_BCMATH:
@@ -2687,24 +2728,24 @@ class Math_BigInteger
     /**
      * Compares two numbers.
      *
-     * @param Array $x_value
-     * @param Boolean $x_negative
-     * @param Array $y_value
-     * @param Boolean $y_negative
-     * @return Integer
-     * @see compare()
+     * @param array $x_value
+     * @param bool $x_negative
+     * @param array $y_value
+     * @param bool $y_negative
+     * @return int
+     * @see self::compare()
      * @access private
      */
     function _compare($x_value, $x_negative, $y_value, $y_negative)
     {
-        if ( $x_negative != $y_negative ) {
-            return ( !$x_negative && $y_negative ) ? 1 : -1;
+        if ($x_negative != $y_negative) {
+            return (!$x_negative && $y_negative) ? 1 : -1;
         }
 
         $result = $x_negative ? -1 : 1;
 
-        if ( count($x_value) != count($y_value) ) {
-            return ( count($x_value) > count($y_value) ) ? $result : -$result;
+        if (count($x_value) != count($y_value)) {
+            return (count($x_value) > count($y_value)) ? $result : -$result;
         }
         $size = max(count($x_value), count($y_value));
 
@@ -2713,7 +2754,7 @@ class Math_BigInteger
 
         for ($i = count($x_value) - 1; $i >= 0; --$i) {
             if ($x_value[$i] != $y_value[$i]) {
-                return ( $x_value[$i] > $y_value[$i] ) ? $result : -$result;
+                return ($x_value[$i] > $y_value[$i]) ? $result : -$result;
             }
         }
 
@@ -2726,13 +2767,13 @@ class Math_BigInteger
      * If you need to see if one number is greater than or less than another number, use Math_BigInteger::compare()
      *
      * @param Math_BigInteger $x
-     * @return Boolean
+     * @return bool
      * @access public
-     * @see compare()
+     * @see self::compare()
      */
     function equals($x)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 return gmp_cmp($this->value, $x->value) == 0;
             default:
@@ -2746,13 +2787,13 @@ class Math_BigInteger
      * Some bitwise operations give different results depending on the precision being used.  Examples include left
      * shift, not, and rotates.
      *
-     * @param Integer $bits
+     * @param int $bits
      * @access public
      */
     function setPrecision($bits)
     {
         $this->precision = $bits;
-        if ( MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_BCMATH ) {
+        if (MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_BCMATH) {
             $this->bitmask = new Math_BigInteger(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256);
         } else {
             $this->bitmask = new Math_BigInteger(bcpow('2', $bits, 0));
@@ -2772,7 +2813,7 @@ class Math_BigInteger
      */
     function bitwise_and($x)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 $temp = new Math_BigInteger();
                 $temp->value = gmp_and($this->value, $x->value);
@@ -2813,7 +2854,7 @@ class Math_BigInteger
      */
     function bitwise_or($x)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 $temp = new Math_BigInteger();
                 $temp->value = gmp_or($this->value, $x->value);
@@ -2853,7 +2894,7 @@ class Math_BigInteger
      */
     function bitwise_xor($x)
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 $temp = new Math_BigInteger();
                 $temp->value = gmp_xor($this->value, $x->value);
@@ -2895,6 +2936,9 @@ class Math_BigInteger
         // calculuate "not" without regard to $this->precision
         // (will always result in a smaller number.  ie. ~1 isn't 1111 1110 - it's 0)
         $temp = $this->toBytes();
+        if ($temp == '') {
+            return '';
+        }
         $pre_msb = decbin(ord($temp[0]));
         $temp = ~$temp;
         $msb = decbin(ord($temp[0]));
@@ -2924,7 +2968,7 @@ class Math_BigInteger
      *
      * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift.
      *
-     * @param Integer $shift
+     * @param int $shift
      * @return Math_BigInteger
      * @access public
      * @internal The only version that yields any speed increases is the internal version.
@@ -2933,7 +2977,7 @@ class Math_BigInteger
     {
         $temp = new Math_BigInteger();
 
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 static $two;
 
@@ -2962,7 +3006,7 @@ class Math_BigInteger
      *
      * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift.
      *
-     * @param Integer $shift
+     * @param int $shift
      * @return Math_BigInteger
      * @access public
      * @internal The only version that yields any speed increases is the internal version.
@@ -2971,7 +3015,7 @@ class Math_BigInteger
     {
         $temp = new Math_BigInteger();
 
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 static $two;
 
@@ -3000,7 +3044,7 @@ class Math_BigInteger
      *
      * Instead of the top x bits being dropped they're appended to the shifted bit string.
      *
-     * @param Integer $shift
+     * @param int $shift
      * @return Math_BigInteger
      * @access public
      */
@@ -3010,7 +3054,7 @@ class Math_BigInteger
 
         if ($this->precision > 0) {
             $precision = $this->precision;
-            if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH ) {
+            if (MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH) {
                 $mask = $this->bitmask->subtract(new Math_BigInteger(1));
                 $mask = $mask->toBytes();
             } else {
@@ -3018,7 +3062,8 @@ class Math_BigInteger
             }
         } else {
             $temp = ord($bits[0]);
-            for ($i = 0; $temp >> $i; ++$i);
+            for ($i = 0; $temp >> $i; ++$i) {
+            }
             $precision = 8 * strlen($bits) - 8 + $i;
             $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3);
         }
@@ -3044,7 +3089,7 @@ class Math_BigInteger
      *
      * Instead of the bottom x bits being dropped they're prepended to the shifted bit string.
      *
-     * @param Integer $shift
+     * @param int $shift
      * @return Math_BigInteger
      * @access public
      */
@@ -3058,7 +3103,7 @@ class Math_BigInteger
      *
      * This function is deprecated.
      *
-     * @param String $generator
+     * @param string $generator
      * @access public
      */
     function setRandomGenerator($generator)
@@ -3070,7 +3115,7 @@ class Math_BigInteger
      *
      * Byte length is equal to $length. Uses crypt_random if it's loaded and mt_rand if it's not.
      *
-     * @param Integer $length
+     * @param int $length
      * @return Math_BigInteger
      * @access private
      */
@@ -3105,7 +3150,7 @@ class Math_BigInteger
      * $max->random($min)
      *
      * @param Math_BigInteger $arg1
-     * @param optional Math_BigInteger $arg2
+     * @param Math_BigInteger $arg2
      * @return Math_BigInteger
      * @access public
      * @internal The API for creating random numbers used to be $a->random($min, $max), where $a was a Math_BigInteger object.
@@ -3129,7 +3174,7 @@ class Math_BigInteger
 
         if (!$compare) {
             return $this->_normalize($min);
-        } else if ($compare < 0) {
+        } elseif ($compare < 0) {
             // if $min is bigger then $max, swap $min and $max
             $temp = $max;
             $max = $min;
@@ -3182,13 +3227,13 @@ class Math_BigInteger
     /**
      * Generate a random prime number.
      *
-     * If there's not a prime within the given range, false will be returned.  If more than $timeout seconds have elapsed,
-     * give up and return false.
+     * If there's not a prime within the given range, false will be returned.
+     * If more than $timeout seconds have elapsed, give up and return false.
      *
      * @param Math_BigInteger $arg1
-     * @param optional Math_BigInteger $arg2
-     * @param optional Integer $timeout
-     * @return Mixed
+     * @param Math_BigInteger $arg2
+     * @param int $timeout
+     * @return Math_BigInteger|false
      * @access public
      * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}.
      */
@@ -3210,7 +3255,7 @@ class Math_BigInteger
 
         if (!$compare) {
             return $min->isPrime() ? $min : false;
-        } else if ($compare < 0) {
+        } elseif ($compare < 0) {
             // if $min is bigger then $max, swap $min and $max
             $temp = $max;
             $max = $min;
@@ -3228,7 +3273,7 @@ class Math_BigInteger
         $x = $this->random($min, $max);
 
         // gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.
-        if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP && function_exists('gmp_nextprime') ) {
+        if (MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP && extension_loaded('gmp') && version_compare(PHP_VERSION, '5.2.0', '>=')) {
             $p = new Math_BigInteger();
             $p->value = gmp_nextprime($x->value);
 
@@ -3289,12 +3334,12 @@ class Math_BigInteger
      *
      * If the current number is odd it'll be unchanged.  If it's even, one will be added to it.
      *
-     * @see randomPrime()
+     * @see self::randomPrime()
      * @access private
      */
     function _make_odd()
     {
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 gmp_setbit($this->value, 0);
                 break;
@@ -3315,8 +3360,8 @@ class Math_BigInteger
      * $t parameter is distributability.  Math_BigInteger::randomPrime() can be distributed across multiple pageloads
      * on a website instead of just one.
      *
-     * @param optional Math_BigInteger $t
-     * @return Boolean
+     * @param Math_BigInteger $t
+     * @return bool
      * @access public
      * @internal Uses the
      *     {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}.  See
@@ -3346,7 +3391,7 @@ class Math_BigInteger
 
         // ie. gmp_testbit($this, 0)
         // ie. isEven() or !isOdd()
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
                 return gmp_prob_prime($this->value, $t) != 0;
             case MATH_BIGINTEGER_MODE_BCMATH:
@@ -3383,7 +3428,7 @@ class Math_BigInteger
                 953,  967,  971,  977,  983,  991,  997
             );
 
-            if ( MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL ) {
+            if (MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL) {
                 for ($i = 0; $i < count($primes); ++$i) {
                     $primes[$i] = new Math_BigInteger($primes[$i]);
                 }
@@ -3399,7 +3444,7 @@ class Math_BigInteger
         }
 
         // see HAC 4.4.1 "Random search for probable primes"
-        if ( MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL ) {
+        if (MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL) {
             foreach ($primes as $prime) {
                 list(, $r) = $this->divide($prime);
                 if ($r->equals($zero)) {
@@ -3423,7 +3468,7 @@ class Math_BigInteger
         $r = $n_1->copy();
         $r_value = $r->value;
         // ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s));
-        if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH ) {
+        if (MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH) {
             $s = 0;
             // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals($one) check earlier
             while ($r->value[strlen($r->value) - 1] % 2 == 0) {
@@ -3433,7 +3478,8 @@ class Math_BigInteger
         } else {
             for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) {
                 $temp = ~$r_value[$i] & 0xFFFFFF;
-                for ($j = 1; ($temp >> $j) & 1; ++$j);
+                for ($j = 1; ($temp >> $j) & 1; ++$j) {
+                }
                 if ($j != 25) {
                     break;
                 }
@@ -3467,12 +3513,12 @@ class Math_BigInteger
      *
      * Shifts BigInteger's by $shift bits.
      *
-     * @param Integer $shift
+     * @param int $shift
      * @access private
      */
     function _lshift($shift)
     {
-        if ( $shift == 0 ) {
+        if ($shift == 0) {
             return;
         }
 
@@ -3488,7 +3534,7 @@ class Math_BigInteger
             $this->value[$i] = (int) ($temp - $carry * MATH_BIGINTEGER_BASE_FULL);
         }
 
-        if ( $carry ) {
+        if ($carry) {
             $this->value[count($this->value)] = $carry;
         }
 
@@ -3502,7 +3548,7 @@ class Math_BigInteger
      *
      * Shifts BigInteger's by $shift bits.
      *
-     * @param Integer $shift
+     * @param int $shift
      * @access private
      */
     function _rshift($shift)
@@ -3516,7 +3562,7 @@ class Math_BigInteger
         $carry_shift = MATH_BIGINTEGER_BASE - $shift;
         $carry_mask = (1 << $shift) - 1;
 
-        if ( $num_digits ) {
+        if ($num_digits) {
             $this->value = array_slice($this->value, $num_digits);
         }
 
@@ -3538,7 +3584,7 @@ class Math_BigInteger
      *
      * @param Math_BigInteger
      * @return Math_BigInteger
-     * @see _trim()
+     * @see self::_trim()
      * @access private
      */
     function _normalize($result)
@@ -3546,9 +3592,9 @@ class Math_BigInteger
         $result->precision = $this->precision;
         $result->bitmask = $this->bitmask;
 
-        switch ( MATH_BIGINTEGER_MODE ) {
+        switch (MATH_BIGINTEGER_MODE) {
             case MATH_BIGINTEGER_MODE_GMP:
-                if (!empty($result->bitmask->value)) {
+                if ($this->bitmask !== false) {
                     $result->value = gmp_and($result->value, $result->bitmask->value);
                 }
 
@@ -3563,7 +3609,7 @@ class Math_BigInteger
 
         $value = &$result->value;
 
-        if ( !count($value) ) {
+        if (!count($value)) {
             return $result;
         }
 
@@ -3586,14 +3632,14 @@ class Math_BigInteger
      *
      * Removes leading zeros
      *
-     * @param Array $value
+     * @param array $value
      * @return Math_BigInteger
      * @access private
      */
     function _trim($value)
     {
         for ($i = count($value) - 1; $i >= 0; --$i) {
-            if ( $value[$i] ) {
+            if ($value[$i]) {
                 break;
             }
             unset($value[$i]);
@@ -3607,7 +3653,7 @@ class Math_BigInteger
      *
      * @param $input Array
      * @param $multiplier mixed
-     * @return Array
+     * @return array
      * @access private
      */
     function _array_repeat($input, $multiplier)
@@ -3622,7 +3668,7 @@ class Math_BigInteger
      *
      * @param $x String
      * @param $shift Integer
-     * @return String
+     * @return string
      * @access private
      */
     function _base256_lshift(&$x, $shift)
@@ -3651,7 +3697,7 @@ class Math_BigInteger
      *
      * @param $x String
      * @param $shift Integer
-     * @return String
+     * @return string
      * @access private
      */
     function _base256_rshift(&$x, $shift)
@@ -3691,8 +3737,8 @@ class Math_BigInteger
     /**
      * Converts 32-bit integers to bytes.
      *
-     * @param Integer $x
-     * @return String
+     * @param int $x
+     * @return string
      * @access private
      */
     function _int2bytes($x)
@@ -3703,8 +3749,8 @@ class Math_BigInteger
     /**
      * Converts bytes to 32-bit integers
      *
-     * @param String $x
-     * @return Integer
+     * @param string $x
+     * @return int
      * @access private
      */
     function _bytes2int($x)
@@ -3718,10 +3764,10 @@ class Math_BigInteger
      *
      * The ability to DER-encode integers is needed to create RSA public keys for use with OpenSSL
      *
-     * @see modPow()
+     * @see self::modPow()
      * @access private
-     * @param Integer $length
-     * @return String
+     * @param int $length
+     * @return string
      */
     function _encodeASN1Length($length)
     {
@@ -3742,9 +3788,9 @@ class Math_BigInteger
      * we'll guarantee that the dividend is divisible by first subtracting the remainder.
      *
      * @access private
-     * @param Integer $x
-     * @param Integer $y
-     * @return Integer
+     * @param int $x
+     * @param int $y
+     * @return int
      */
     function _safe_divide($x, $y)
     {
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
index b5cd2f55d4c61e3421a0ce1f26dc7ab150f491f5..83ae5cc8d159d44ed0b80e5f0dad4cb9cf752725 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
@@ -17,7 +17,7 @@
  *    if (!$ssh->login('username', 'password')) {
  *        exit('bad login');
  *    }
-
+ *
  *    $scp = new Net_SCP($ssh);
  *    $scp->put('abcd', str_repeat('x', 1024*1024));
  * ?>
@@ -51,7 +51,7 @@
 
 /**#@+
  * @access public
- * @see Net_SCP::put()
+ * @see self::put()
  */
 /**
  * Reads data from a local file.
@@ -65,8 +65,8 @@ define('NET_SCP_STRING',  2);
 
 /**#@+
  * @access private
- * @see Net_SCP::_send()
- * @see Net_SCP::_receive()
+ * @see self::_send()
+ * @see self::_receive()
  */
 /**
  * SSH1 is being used.
@@ -90,7 +90,7 @@ class Net_SCP
     /**
      * SSH Object
      *
-     * @var Object
+     * @var object
      * @access private
      */
     var $ssh;
@@ -98,7 +98,7 @@ class Net_SCP
     /**
      * Packet Size
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $packet_size;
@@ -106,7 +106,7 @@ class Net_SCP
     /**
      * Mode
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $mode;
@@ -116,13 +116,11 @@ class Net_SCP
      *
      * Connects to an SSH server
      *
-     * @param String $host
-     * @param optional Integer $port
-     * @param optional Integer $timeout
+     * @param Net_SSH1|Net_SSH2 $ssh
      * @return Net_SCP
      * @access public
      */
-    function Net_SCP($ssh)
+    function __construct($ssh)
     {
         if (!is_object($ssh)) {
             return;
@@ -143,6 +141,18 @@ class Net_SCP
         $this->ssh = $ssh;
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @param Net_SSH1|Net_SSH2 $ssh
+     * @access public
+     */
+    function Net_SCP($ssh)
+    {
+        $this->__construct($ssh);
+    }
+
     /**
      * Uploads a file to the SCP server.
      *
@@ -157,11 +167,11 @@ class Net_SCP
      * Currently, only binary mode is supported.  As such, if the line endings need to be adjusted, you will need to take
      * care of that, yourself.
      *
-     * @param String $remote_file
-     * @param String $data
-     * @param optional Integer $mode
-     * @param optional Callable $callback
-     * @return Boolean
+     * @param string $remote_file
+     * @param string $data
+     * @param int $mode
+     * @param callable $callback
+     * @return bool
      * @access public
      */
     function put($remote_file, $data, $mode = NET_SCP_STRING, $callback = null)
@@ -233,9 +243,9 @@ class Net_SCP
      * the operation was unsuccessful.  If $local_file is defined, returns true or false depending on the success of the
      * operation
      *
-     * @param String $remote_file
-     * @param optional String $local_file
-     * @return Mixed
+     * @param string $remote_file
+     * @param string $local_file
+     * @return mixed
      * @access public
      */
     function get($remote_file, $local_file = false)
@@ -291,7 +301,7 @@ class Net_SCP
     /**
      * Sends a packet to an SSH server
      *
-     * @param String $data
+     * @param string $data
      * @access private
      */
     function _send($data)
@@ -303,13 +313,13 @@ class Net_SCP
             case NET_SCP_SSH1:
                 $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data);
                 $this->ssh->_send_binary_packet($data);
-         }
+        }
     }
 
     /**
      * Receives a packet from an SSH server
      *
-     * @return String
+     * @return string
      * @access private
      */
     function _receive()
@@ -339,7 +349,7 @@ class Net_SCP
                             return false;
                     }
                 }
-         }
+        }
     }
 
     /**
@@ -355,6 +365,6 @@ class Net_SCP
                 break;
             case NET_SCP_SSH1:
                 $this->ssh->disconnect();
-         }
+        }
     }
 }
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
index 5f7d3666edf749226c71fbe21ff171d494293eca..a279bdfb12ce9603432183be71ee2711d5a37880 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
@@ -62,7 +62,7 @@ if (!class_exists('Net_SSH2')) {
 
 /**#@+
  * @access public
- * @see Net_SFTP::getLog()
+ * @see self::getLog()
  */
 /**
  * Returns the message numbers
@@ -91,7 +91,7 @@ define('NET_SFTP_CHANNEL', 0x100);
 
 /**#@+
  * @access public
- * @see Net_SFTP::put()
+ * @see self::put()
  */
 /**
  * Reads data from a local file.
@@ -102,6 +102,11 @@ define('NET_SFTP_LOCAL_FILE',    1);
  */
 // this value isn't really used anymore but i'm keeping it reserved for historical reasons
 define('NET_SFTP_STRING',        2);
+/**
+ * Reads data from callback:
+ * function callback($length) returns string to proceed, null for EOF
+ */
+define('NET_SFTP_CALLBACK',     16);
 /**
  * Resumes an upload
  */
@@ -124,8 +129,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Packet Types
      *
-     * @see Net_SFTP::Net_SFTP()
-     * @var Array
+     * @see self::Net_SFTP()
+     * @var array
      * @access private
      */
     var $packet_types = array();
@@ -133,8 +138,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Status Codes
      *
-     * @see Net_SFTP::Net_SFTP()
-     * @var Array
+     * @see self::Net_SFTP()
+     * @var array
      * @access private
      */
     var $status_codes = array();
@@ -145,8 +150,8 @@ class Net_SFTP extends Net_SSH2
      * The request ID exists in the off chance that a packet is sent out-of-order.  Of course, this library doesn't support
      * concurrent actions, so it's somewhat academic, here.
      *
-     * @var Integer
-     * @see Net_SFTP::_send_sftp_packet()
+     * @var int
+     * @see self::_send_sftp_packet()
      * @access private
      */
     var $request_id = false;
@@ -157,8 +162,8 @@ class Net_SFTP extends Net_SSH2
      * The request ID exists in the off chance that a packet is sent out-of-order.  Of course, this library doesn't support
      * concurrent actions, so it's somewhat academic, here.
      *
-     * @var Integer
-     * @see Net_SFTP::_get_sftp_packet()
+     * @var int
+     * @see self::_get_sftp_packet()
      * @access private
      */
     var $packet_type = -1;
@@ -166,8 +171,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Packet Buffer
      *
-     * @var String
-     * @see Net_SFTP::_get_sftp_packet()
+     * @var string
+     * @see self::_get_sftp_packet()
      * @access private
      */
     var $packet_buffer = '';
@@ -175,8 +180,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Extensions supported by the server
      *
-     * @var Array
-     * @see Net_SFTP::_initChannel()
+     * @var array
+     * @see self::_initChannel()
      * @access private
      */
     var $extensions = array();
@@ -184,8 +189,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Server SFTP version
      *
-     * @var Integer
-     * @see Net_SFTP::_initChannel()
+     * @var int
+     * @see self::_initChannel()
      * @access private
      */
     var $version;
@@ -193,9 +198,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Current working directory
      *
-     * @var String
-     * @see Net_SFTP::_realpath()
-     * @see Net_SFTP::chdir()
+     * @var string
+     * @see self::_realpath()
+     * @see self::chdir()
      * @access private
      */
     var $pwd = false;
@@ -203,8 +208,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Packet Type Log
      *
-     * @see Net_SFTP::getLog()
-     * @var Array
+     * @see self::getLog()
+     * @var array
      * @access private
      */
     var $packet_type_log = array();
@@ -212,8 +217,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Packet Log
      *
-     * @see Net_SFTP::getLog()
-     * @var Array
+     * @see self::getLog()
+     * @var array
      * @access private
      */
     var $packet_log = array();
@@ -221,9 +226,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Error information
      *
-     * @see Net_SFTP::getSFTPErrors()
-     * @see Net_SFTP::getLastSFTPError()
-     * @var String
+     * @see self::getSFTPErrors()
+     * @see self::getLastSFTPError()
+     * @var string
      * @access private
      */
     var $sftp_errors = array();
@@ -234,10 +239,10 @@ class Net_SFTP extends Net_SSH2
      * Rather than always having to open a directory and close it immediately there after to see if a file is a directory
      * we'll cache the results.
      *
-     * @see Net_SFTP::_update_stat_cache()
-     * @see Net_SFTP::_remove_from_stat_cache()
-     * @see Net_SFTP::_query_stat_cache()
-     * @var Array
+     * @see self::_update_stat_cache()
+     * @see self::_remove_from_stat_cache()
+     * @see self::_query_stat_cache()
+     * @var array
      * @access private
      */
     var $stat_cache = array();
@@ -245,9 +250,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Max SFTP Packet Size
      *
-     * @see Net_SFTP::Net_SFTP()
-     * @see Net_SFTP::get()
-     * @var Array
+     * @see self::Net_SFTP()
+     * @see self::get()
+     * @var array
      * @access private
      */
     var $max_sftp_packet;
@@ -255,9 +260,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Stat Cache Flag
      *
-     * @see Net_SFTP::disableStatCache()
-     * @see Net_SFTP::enableStatCache()
-     * @var Boolean
+     * @see self::disableStatCache()
+     * @see self::enableStatCache()
+     * @var bool
      * @access private
      */
     var $use_stat_cache = true;
@@ -265,9 +270,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Sort Options
      *
-     * @see Net_SFTP::_comparator()
-     * @see Net_SFTP::setListOrder()
-     * @var Array
+     * @see self::_comparator()
+     * @see self::setListOrder()
+     * @var array
      * @access private
      */
     var $sortOptions = array();
@@ -277,15 +282,15 @@ class Net_SFTP extends Net_SSH2
      *
      * Connects to an SFTP server
      *
-     * @param String $host
-     * @param optional Integer $port
-     * @param optional Integer $timeout
+     * @param string $host
+     * @param int $port
+     * @param int $timeout
      * @return Net_SFTP
      * @access public
      */
-    function Net_SFTP($host, $port = 22, $timeout = 10)
+    function __construct($host, $port = 22, $timeout = 10)
     {
-        parent::Net_SSH2($host, $port, $timeout);
+        parent::__construct($host, $port, $timeout);
 
         $this->max_sftp_packet = 1 << 15;
 
@@ -375,7 +380,7 @@ class Net_SFTP extends Net_SSH2
         );
         // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
         // the flag definitions change somewhat in SFTPv5+.  if SFTPv5+ support is added to this library, maybe name
-        // the array for that $this->open5_flags and similarily alter the constant names.
+        // the array for that $this->open5_flags and similarly alter the constant names.
         $this->open_flags = array(
             0x00000001 => 'NET_SFTP_OPEN_READ',
             0x00000002 => 'NET_SFTP_OPEN_WRITE',
@@ -412,12 +417,26 @@ class Net_SFTP extends Net_SSH2
         }
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @param string $host
+     * @param int $port
+     * @param int $timeout
+     * @access public
+     */
+    function Net_SFTP($host, $port = 22, $timeout = 10)
+    {
+        $this->__construct($host, $port, $timeout);
+    }
+
     /**
      * Login
      *
-     * @param String $username
-     * @param optional String $password
-     * @return Boolean
+     * @param string $username
+     * @param string $password
+     * @return bool
      * @access public
      */
     function login($username)
@@ -429,8 +448,15 @@ class Net_SFTP extends Net_SSH2
 
         $this->window_size_server_to_client[NET_SFTP_CHANNEL] = $this->window_size;
 
-        $packet = pack('CNa*N3',
-            NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', NET_SFTP_CHANNEL, $this->window_size, 0x4000);
+        $packet = pack(
+            'CNa*N3',
+            NET_SSH2_MSG_CHANNEL_OPEN,
+            strlen('session'),
+            'session',
+            NET_SFTP_CHANNEL,
+            $this->window_size,
+            0x4000
+        );
 
         if (!$this->_send_binary_packet($packet)) {
             return false;
@@ -443,8 +469,16 @@ class Net_SFTP extends Net_SSH2
             return false;
         }
 
-        $packet = pack('CNNa*CNa*',
-            NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SFTP_CHANNEL], strlen('subsystem'), 'subsystem', 1, strlen('sftp'), 'sftp');
+        $packet = pack(
+            'CNNa*CNa*',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $this->server_channels[NET_SFTP_CHANNEL],
+            strlen('subsystem'),
+            'subsystem',
+            1,
+            strlen('sftp'),
+            'sftp'
+        );
         if (!$this->_send_binary_packet($packet)) {
             return false;
         }
@@ -459,8 +493,16 @@ class Net_SFTP extends Net_SSH2
                        "exec sftp-server";
             // we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does
             // is redundant
-            $packet = pack('CNNa*CNa*',
-                NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SFTP_CHANNEL], strlen('exec'), 'exec', 1, strlen($command), $command);
+            $packet = pack(
+                'CNNa*CNa*',
+                NET_SSH2_MSG_CHANNEL_REQUEST,
+                $this->server_channels[NET_SFTP_CHANNEL],
+                strlen('exec'),
+                'exec',
+                1,
+                strlen($command),
+                $command
+            );
             if (!$this->_send_binary_packet($packet)) {
                 return false;
             }
@@ -582,7 +624,7 @@ class Net_SFTP extends Net_SSH2
     /**
      * Returns the current directory name
      *
-     * @return Mixed
+     * @return mixed
      * @access public
      */
     function pwd()
@@ -593,8 +635,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Logs errors
      *
-     * @param String $response
-     * @param optional Integer $status
+     * @param string $response
+     * @param int $status
      * @access public
      */
     function _logError($response, $status = -1)
@@ -613,15 +655,30 @@ class Net_SFTP extends Net_SSH2
         }
     }
 
+    /**
+     * Returns canonicalized absolute pathname
+     *
+     * realpath() expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the input
+     * path and returns the canonicalized absolute pathname.
+     *
+     * @param string $path
+     * @return mixed
+     * @access public
+     */
+    function realpath($path)
+    {
+        return $this->_realpath($path);
+    }
+
     /**
      * Canonicalize the Server-Side Path Name
      *
      * SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it.  Returns
      * the absolute (canonicalized) path.
      *
-     * @see Net_SFTP::chdir()
-     * @param String $path
-     * @return Mixed
+     * @see self::chdir()
+     * @param string $path
+     * @return mixed
      * @access private
      */
     function _realpath($path)
@@ -676,8 +733,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Changes the current directory
      *
-     * @param String $dir
-     * @return Boolean
+     * @param string $dir
+     * @return bool
      * @access public
      */
     function chdir($dir)
@@ -738,9 +795,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Returns a list of files in the given directory
      *
-     * @param optional String $dir
-     * @param optional Boolean $recursive
-     * @return Mixed
+     * @param string $dir
+     * @param bool $recursive
+     * @return mixed
      * @access public
      */
     function nlist($dir = '.', $recursive = false)
@@ -751,17 +808,17 @@ class Net_SFTP extends Net_SSH2
     /**
      * Helper method for nlist
      *
-     * @param String $dir
-     * @param Boolean $recursive
-     * @param String $relativeDir
-     * @return Mixed
+     * @param string $dir
+     * @param bool $recursive
+     * @param string $relativeDir
+     * @return mixed
      * @access private
      */
     function _nlist_helper($dir, $recursive, $relativeDir)
     {
         $files = $this->_list($dir, false);
 
-        if (!$recursive) {
+        if (!$recursive || $files === false) {
             return $files;
         }
 
@@ -787,9 +844,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Returns a detailed list of files in the given directory
      *
-     * @param optional String $dir
-     * @param optional Boolean $recursive
-     * @return Mixed
+     * @param string $dir
+     * @param bool $recursive
+     * @return mixed
      * @access public
      */
     function rawlist($dir = '.', $recursive = false)
@@ -801,7 +858,7 @@ class Net_SFTP extends Net_SSH2
 
         static $depth = 0;
 
-        foreach ($files as $key=>$value) {
+        foreach ($files as $key => $value) {
             if ($depth != 0 && $key == '..') {
                 unset($files[$key]);
                 continue;
@@ -821,9 +878,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Reads a list, be it detailed or not, of files in the given directory
      *
-     * @param String $dir
-     * @param optional Boolean $raw
-     * @return Mixed
+     * @param string $dir
+     * @param bool $raw
+     * @return mixed
      * @access private
      */
     function _list($dir, $raw = true)
@@ -896,7 +953,7 @@ class Net_SFTP extends Net_SSH2
                             } else {
                                 $temp = $dir . '/' . $shortname;
                             }
-                            $this->_update_stat_cache($temp, (object) $attributes);
+                            $this->_update_stat_cache($temp, (object) array('lstat' => $attributes));
                         }
                         // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the
                         // final SSH_FXP_STATUS packet should tell us that, already.
@@ -931,9 +988,9 @@ class Net_SFTP extends Net_SSH2
      *
      * Intended for use with uasort()
      *
-     * @param Array $a
-     * @param Array $b
-     * @return Integer
+     * @param array $a
+     * @param array $b
+     * @return int
      * @access private
      */
     function _comparator($a, $b)
@@ -1031,8 +1088,8 @@ class Net_SFTP extends Net_SSH2
      *
      * Files larger than 4GB will show up as being exactly 4GB.
      *
-     * @param String $filename
-     * @return Mixed
+     * @param string $filename
+     * @return mixed
      * @access public
      */
     function size($filename)
@@ -1051,22 +1108,40 @@ class Net_SFTP extends Net_SSH2
     /**
      * Save files / directories to cache
      *
-     * @param String $path
-     * @param Mixed $value
+     * @param string $path
+     * @param mixed $value
      * @access private
      */
     function _update_stat_cache($path, $value)
     {
+        if ($this->use_stat_cache === false) {
+            return;
+        }
+
         // preg_replace('#^/|/(?=/)|/$#', '', $dir) == str_replace('//', '/', trim($path, '/'))
         $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
 
         $temp = &$this->stat_cache;
         $max = count($dirs) - 1;
-        foreach ($dirs as $i=>$dir) {
+        foreach ($dirs as $i => $dir) {
+            // if $temp is an object that means one of two things.
+            //  1. a file was deleted and changed to a directory behind phpseclib's back
+            //  2. it's a symlink. when lstat is done it's unclear what it's a symlink to
+            if (is_object($temp)) {
+                $temp = array();
+            }
             if (!isset($temp[$dir])) {
                 $temp[$dir] = array();
             }
             if ($i === $max) {
+                if (is_object($temp[$dir])) {
+                    if (!isset($value->stat) && isset($temp[$dir]->stat)) {
+                        $value->stat = $temp[$dir]->stat;
+                    }
+                    if (!isset($value->lstat) && isset($temp[$dir]->lstat)) {
+                        $value->lstat = $temp[$dir]->lstat;
+                    }
+                }
                 $temp[$dir] = $value;
                 break;
             }
@@ -1077,8 +1152,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Remove files / directories from cache
      *
-     * @param String $path
-     * @return Boolean
+     * @param string $path
+     * @return bool
      * @access private
      */
     function _remove_from_stat_cache($path)
@@ -1087,7 +1162,7 @@ class Net_SFTP extends Net_SSH2
 
         $temp = &$this->stat_cache;
         $max = count($dirs) - 1;
-        foreach ($dirs as $i=>$dir) {
+        foreach ($dirs as $i => $dir) {
             if ($i === $max) {
                 unset($temp[$dir]);
                 return true;
@@ -1104,8 +1179,8 @@ class Net_SFTP extends Net_SSH2
      *
      * Mainly used by file_exists
      *
-     * @param String $dir
-     * @return Mixed
+     * @param string $dir
+     * @return mixed
      * @access private
      */
     function _query_stat_cache($path)
@@ -1127,8 +1202,8 @@ class Net_SFTP extends Net_SSH2
      *
      * Returns an array on success and false otherwise.
      *
-     * @param String $filename
-     * @return Mixed
+     * @param string $filename
+     * @return mixed
      * @access public
      */
     function stat($filename)
@@ -1144,11 +1219,11 @@ class Net_SFTP extends Net_SSH2
 
         if ($this->use_stat_cache) {
             $result = $this->_query_stat_cache($filename);
-            if (is_array($result) && isset($result['.'])) {
-                return (array) $result['.'];
+            if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) {
+                return $result['.']->stat;
             }
-            if (is_object($result)) {
-                return (array) $result;
+            if (is_object($result) && isset($result->stat)) {
+                return $result->stat;
             }
         }
 
@@ -1161,7 +1236,7 @@ class Net_SFTP extends Net_SSH2
             if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) {
                 $filename.= '/.';
             }
-            $this->_update_stat_cache($filename, (object) $stat);
+            $this->_update_stat_cache($filename, (object) array('stat' => $stat));
             return $stat;
         }
 
@@ -1174,7 +1249,7 @@ class Net_SFTP extends Net_SSH2
         if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) {
             $filename.= '/.';
         }
-        $this->_update_stat_cache($filename, (object) $stat);
+        $this->_update_stat_cache($filename, (object) array('stat' => $stat));
 
         return $stat;
     }
@@ -1184,8 +1259,8 @@ class Net_SFTP extends Net_SSH2
      *
      * Returns an array on success and false otherwise.
      *
-     * @param String $filename
-     * @return Mixed
+     * @param string $filename
+     * @return mixed
      * @access public
      */
     function lstat($filename)
@@ -1201,11 +1276,11 @@ class Net_SFTP extends Net_SSH2
 
         if ($this->use_stat_cache) {
             $result = $this->_query_stat_cache($filename);
-            if (is_array($result) && isset($result['.'])) {
-                return (array) $result['.'];
+            if (is_array($result) && isset($result['.']) && isset($result['.']->lstat)) {
+                return $result['.']->lstat;
             }
-            if (is_object($result)) {
-                return (array) $result;
+            if (is_object($result) && isset($result->lstat)) {
+                return $result->lstat;
             }
         }
 
@@ -1218,7 +1293,7 @@ class Net_SFTP extends Net_SSH2
             if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) {
                 $filename.= '/.';
             }
-            $this->_update_stat_cache($filename, (object) $lstat);
+            $this->_update_stat_cache($filename, (object) array('lstat' => $lstat));
             return $lstat;
         }
 
@@ -1226,7 +1301,7 @@ class Net_SFTP extends Net_SSH2
 
         if ($lstat != $stat) {
             $lstat = array_merge($lstat, array('type' => NET_SFTP_TYPE_SYMLINK));
-            $this->_update_stat_cache($filename, (object) $lstat);
+            $this->_update_stat_cache($filename, (object) array('lstat' => $lstat));
             return $stat;
         }
 
@@ -1239,7 +1314,7 @@ class Net_SFTP extends Net_SSH2
         if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) {
             $filename.= '/.';
         }
-        $this->_update_stat_cache($filename, (object) $lstat);
+        $this->_update_stat_cache($filename, (object) array('lstat' => $lstat));
 
         return $lstat;
     }
@@ -1250,9 +1325,9 @@ class Net_SFTP extends Net_SSH2
      * Determines information without calling Net_SFTP::_realpath().
      * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
      *
-     * @param String $filename
-     * @param Integer $type
-     * @return Mixed
+     * @param string $filename
+     * @param int $type
+     * @return mixed
      * @access private
      */
     function _stat($filename, $type)
@@ -1279,9 +1354,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Truncates a file to a given length
      *
-     * @param String $filename
-     * @param Integer $new_size
-     * @return Boolean
+     * @param string $filename
+     * @param int $new_size
+     * @return bool
      * @access public
      */
     function truncate($filename, $new_size)
@@ -1296,10 +1371,10 @@ class Net_SFTP extends Net_SSH2
      *
      * If the file does not exist, it will be created.
      *
-     * @param String $filename
-     * @param optional Integer $time
-     * @param optional Integer $atime
-     * @return Boolean
+     * @param string $filename
+     * @param int $time
+     * @param int $atime
+     * @return bool
      * @access public
      */
     function touch($filename, $time = null, $atime = null)
@@ -1347,10 +1422,10 @@ class Net_SFTP extends Net_SSH2
      *
      * Returns true on success or false on error.
      *
-     * @param String $filename
-     * @param Integer $uid
-     * @param optional Boolean $recursive
-     * @return Boolean
+     * @param string $filename
+     * @param int $uid
+     * @param bool $recursive
+     * @return bool
      * @access public
      */
     function chown($filename, $uid, $recursive = false)
@@ -1367,10 +1442,10 @@ class Net_SFTP extends Net_SSH2
      *
      * Returns true on success or false on error.
      *
-     * @param String $filename
-     * @param Integer $gid
-     * @param optional Boolean $recursive
-     * @return Boolean
+     * @param string $filename
+     * @param int $gid
+     * @param bool $recursive
+     * @return bool
      * @access public
      */
     function chgrp($filename, $gid, $recursive = false)
@@ -1386,10 +1461,10 @@ class Net_SFTP extends Net_SSH2
      * Returns the new file permissions on success or false on error.
      * If $recursive is true than this just returns true or false.
      *
-     * @param Integer $mode
-     * @param String $filename
-     * @param optional Boolean $recursive
-     * @return Mixed
+     * @param int $mode
+     * @param string $filename
+     * @param bool $recursive
+     * @return mixed
      * @access public
      */
     function chmod($mode, $filename, $recursive = false)
@@ -1408,6 +1483,7 @@ class Net_SFTP extends Net_SSH2
             return true;
         }
 
+        $filename = $this->_realPath($filename);
         // rather than return what the permissions *should* be, we'll return what they actually are.  this will also
         // tell us if the file actually exists.
         // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
@@ -1433,10 +1509,10 @@ class Net_SFTP extends Net_SSH2
     /**
      * Sets information about a file
      *
-     * @param String $filename
-     * @param String $attr
-     * @param Boolean $recursive
-     * @return Boolean
+     * @param string $filename
+     * @param string $attr
+     * @param bool $recursive
+     * @return bool
      * @access private
      */
     function _setstat($filename, $attr, $recursive)
@@ -1492,10 +1568,10 @@ class Net_SFTP extends Net_SSH2
      *
      * Minimizes directory lookups and SSH_FXP_STATUS requests for speed.
      *
-     * @param String $path
-     * @param String $attr
-     * @param Integer $i
-     * @return Boolean
+     * @param string $path
+     * @param string $attr
+     * @param int $i
+     * @return bool
      * @access private
      */
     function _setstat_recursive($path, $attr, &$i)
@@ -1517,7 +1593,7 @@ class Net_SFTP extends Net_SSH2
         }
 
         unset($entries['.'], $entries['..']);
-        foreach ($entries as $filename=>$props) {
+        foreach ($entries as $filename => $props) {
             if (!isset($props['type'])) {
                 return false;
             }
@@ -1562,8 +1638,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Return the target of a symbolic link
      *
-     * @param String $link
-     * @return Mixed
+     * @param string $link
+     * @return mixed
      * @access public
      */
     function readlink($link)
@@ -1605,9 +1681,9 @@ class Net_SFTP extends Net_SSH2
      *
      * symlink() creates a symbolic link to the existing target with the specified name link.
      *
-     * @param String $target
-     * @param String $link
-     * @return Boolean
+     * @param string $target
+     * @param string $link
+     * @return bool
      * @access public
      */
     function symlink($target, $link)
@@ -1616,7 +1692,7 @@ class Net_SFTP extends Net_SSH2
             return false;
         }
 
-        $target = $this->_realpath($target);
+        //$target = $this->_realpath($target);
         $link = $this->_realpath($link);
 
         $packet = pack('Na*Na*', strlen($target), $target, strlen($link), $link);
@@ -1642,8 +1718,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Creates a directory.
      *
-     * @param String $dir
-     * @return Boolean
+     * @param string $dir
+     * @return bool
      * @access public
      */
     function mkdir($dir, $mode = -1, $recursive = false)
@@ -1677,8 +1753,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Helper function for directory creation
      *
-     * @param String $dir
-     * @return Boolean
+     * @param string $dir
+     * @return bool
      * @access private
      */
     function _mkdir_helper($dir, $attr)
@@ -1705,8 +1781,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Removes a directory.
      *
-     * @param String $dir
-     * @return Boolean
+     * @param string $dir
+     * @return bool
      * @access public
      */
     function rmdir($dir)
@@ -1759,6 +1835,10 @@ class Net_SFTP extends Net_SSH2
      *
      * If $data is a resource then it'll be used as a resource instead.
      *
+     *
+     * Setting $mode to NET_SFTP_CALLBACK will use $data as callback function, which gets only one parameter -- number
+     * of bytes to return, and returns a string if there is some data or null if there is no more data
+     *
      * Currently, only binary mode is supported.  As such, if the line endings need to be adjusted, you will need to take
      * care of that, yourself.
      *
@@ -1779,16 +1859,17 @@ class Net_SFTP extends Net_SSH2
      *
      * Setting $local_start to > 0 or $mode | NET_SFTP_RESUME_START doesn't do anything unless $mode | NET_SFTP_LOCAL_FILE.
      *
-     * @param String $remote_file
-     * @param String|resource $data
-     * @param optional Integer $mode
-     * @param optional Integer $start
-     * @param optional Integer $local_start
-     * @return Boolean
+     * @param string $remote_file
+     * @param string|resource $data
+     * @param int $mode
+     * @param int $start
+     * @param int $local_start
+     * @param callable|null $progressCallback
+     * @return bool
      * @access public
      * @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - Net_SFTP::setMode().
      */
-    function put($remote_file, $data, $mode = NET_SFTP_STRING, $start = -1, $local_start = -1)
+    function put($remote_file, $data, $mode = NET_SFTP_STRING, $start = -1, $local_start = -1, $progressCallback = null)
     {
         if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
             return false;
@@ -1836,7 +1917,15 @@ class Net_SFTP extends Net_SSH2
         }
 
         // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
+        $dataCallback = false;
         switch (true) {
+            case $mode & NET_SFTP_CALLBACK:
+                if (!is_callable($data)) {
+                    user_error("\$data should be is_callable if you set NET_SFTP_CALLBACK flag");
+                }
+                $dataCallback = $data;
+                // do nothing
+                break;
             case is_resource($data):
                 $mode = $mode & ~NET_SFTP_LOCAL_FILE;
                 $fp = $data;
@@ -1858,11 +1947,10 @@ class Net_SFTP extends Net_SSH2
 
             if ($local_start >= 0) {
                 fseek($fp, $local_start);
-            } elseif ($mode & NET_SFTP_RESUME_START) {
-                // do nothing
-            } else {
-                fseek($fp, $offset);
+                $size-= $local_start;
             }
+        } elseif ($dataCallback) {
+            $size = 0;
         } else {
             $size = strlen($data);
         }
@@ -1874,8 +1962,19 @@ class Net_SFTP extends Net_SSH2
         // make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header"
         $sftp_packet_size-= strlen($handle) + 25;
         $i = 0;
-        while ($sent < $size) {
-            $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
+        while ($dataCallback || ($size === 0 || $sent < $size)) {
+            if ($dataCallback) {
+                $temp = call_user_func($dataCallback, $sftp_packet_size);
+                if (is_null($temp)) {
+                    break;
+                }
+            } else {
+                $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
+                if ($temp === false || $temp === '') {
+                    break;
+                }
+            }
+
             $subtemp = $offset + $sent;
             $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
             if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
@@ -1885,6 +1984,9 @@ class Net_SFTP extends Net_SSH2
                 return false;
             }
             $sent+= strlen($temp);
+            if (is_callable($progressCallback)) {
+                call_user_func($progressCallback, $sent);
+            }
 
             $i++;
 
@@ -1918,8 +2020,8 @@ class Net_SFTP extends Net_SSH2
      * Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i
      * SSH_FXP_WRITEs, in succession, and then reading $i responses.
      *
-     * @param Integer $i
-     * @return Boolean
+     * @param int $i
+     * @return bool
      * @access private
      */
     function _read_put_responses($i)
@@ -1944,8 +2046,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Close handle
      *
-     * @param String $handle
-     * @return Boolean
+     * @param string $handle
+     * @return bool
      * @access private
      */
     function _close_handle($handle)
@@ -1980,11 +2082,11 @@ class Net_SFTP extends Net_SSH2
      *
      * $offset and $length can be used to download files in chunks.
      *
-     * @param String $remote_file
-     * @param optional String $local_file
-     * @param optional Integer $offset
-     * @param optional Integer $length
-     * @return Mixed
+     * @param string $remote_file
+     * @param string $local_file
+     * @param int $offset
+     * @param int $length
+     * @return mixed
      * @access public
      */
     function get($remote_file, $local_file = false, $offset = 0, $length = -1)
@@ -2035,40 +2137,68 @@ class Net_SFTP extends Net_SSH2
         $fclose_check = $local_file !== false && !is_resource($local_file);
 
         $start = $offset;
-        $size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length;
+        $read = 0;
         while (true) {
-            $packet = pack('Na*N3', strlen($handle), $handle, $offset / 4294967296, $offset, $size);
-            if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
-                if ($fclose_check) {
-                    fclose($fp);
-                }
-                return false;
-            }
+            $i = 0;
 
-            $response = $this->_get_sftp_packet();
-            switch ($this->packet_type) {
-                case NET_SFTP_DATA:
-                    $temp = substr($response, 4);
-                    $offset+= strlen($temp);
-                    if ($local_file === false) {
-                        $content.= $temp;
-                    } else {
-                        fputs($fp, $temp);
-                    }
-                    break;
-                case NET_SFTP_STATUS:
-                    // could, in theory, return false if !strlen($content) but we'll hold off for the time being
-                    $this->_logError($response);
-                    break 2;
-                default:
-                    user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
+            while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) {
+                $tempoffset = $start + $read;
+
+                $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
+
+                $packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
+                if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
                     if ($fclose_check) {
                         fclose($fp);
                     }
                     return false;
+                }
+                $packet = null;
+                $read+= $packet_size;
+                $i++;
             }
 
-            if ($length > 0 && $length <= $offset - $start) {
+            if (!$i) {
+                break;
+            }
+
+            $clear_responses = false;
+            while ($i > 0) {
+                $i--;
+
+                if ($clear_responses) {
+                    $this->_get_sftp_packet();
+                    continue;
+                } else {
+                    $response = $this->_get_sftp_packet();
+                }
+
+                switch ($this->packet_type) {
+                    case NET_SFTP_DATA:
+                        $temp = substr($response, 4);
+                        $offset+= strlen($temp);
+                        if ($local_file === false) {
+                            $content.= $temp;
+                        } else {
+                            fputs($fp, $temp);
+                        }
+                        $temp = null;
+                        break;
+                    case NET_SFTP_STATUS:
+                        // could, in theory, return false if !strlen($content) but we'll hold off for the time being
+                        $this->_logError($response);
+                        $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses
+                        break;
+                    default:
+                        if ($fclose_check) {
+                            fclose($fp);
+                        }
+                        user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS');
+                }
+                $response = null;
+            }
+
+            if ($clear_responses) {
                 break;
             }
         }
@@ -2096,9 +2226,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Deletes a file on the SFTP server.
      *
-     * @param String $path
-     * @param Boolean $recursive
-     * @return Boolean
+     * @param string $path
+     * @param bool $recursive
+     * @return bool
      * @access public
      */
     function delete($path, $recursive = true)
@@ -2146,9 +2276,9 @@ class Net_SFTP extends Net_SSH2
      *
      * Minimizes directory lookups and SSH_FXP_STATUS requests for speed.
      *
-     * @param String $path
-     * @param Integer $i
-     * @return Boolean
+     * @param string $path
+     * @param int $i
+     * @return bool
      * @access private
      */
     function _delete_recursive($path, &$i)
@@ -2166,7 +2296,7 @@ class Net_SFTP extends Net_SSH2
         }
 
         unset($entries['.'], $entries['..']);
-        foreach ($entries as $filename=>$props) {
+        foreach ($entries as $filename => $props) {
             if (!isset($props['type'])) {
                 return false;
             }
@@ -2180,6 +2310,7 @@ class Net_SFTP extends Net_SSH2
                 if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($temp), $temp))) {
                     return false;
                 }
+                $this->_remove_from_stat_cache($temp);
 
                 $i++;
 
@@ -2190,12 +2321,12 @@ class Net_SFTP extends Net_SSH2
                     $i = 0;
                 }
             }
-            $this->_remove_from_stat_cache($path);
         }
 
         if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($path), $path))) {
             return false;
         }
+        $this->_remove_from_stat_cache($path);
 
         $i++;
 
@@ -2212,8 +2343,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Checks whether a file or directory exists
      *
-     * @param String $path
-     * @return Boolean
+     * @param string $path
+     * @return bool
      * @access public
      */
     function file_exists($path)
@@ -2235,8 +2366,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Tells whether the filename is a directory
      *
-     * @param String $path
-     * @return Boolean
+     * @param string $path
+     * @return bool
      * @access public
      */
     function is_dir($path)
@@ -2251,8 +2382,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Tells whether the filename is a regular file
      *
-     * @param String $path
-     * @return Boolean
+     * @param string $path
+     * @return bool
      * @access public
      */
     function is_file($path)
@@ -2267,24 +2398,94 @@ class Net_SFTP extends Net_SSH2
     /**
      * Tells whether the filename is a symbolic link
      *
-     * @param String $path
-     * @return Boolean
+     * @param string $path
+     * @return bool
      * @access public
      */
     function is_link($path)
     {
-        $result = $this->_get_stat_cache_prop($path, 'type');
+        $result = $this->_get_lstat_cache_prop($path, 'type');
         if ($result === false) {
             return false;
         }
         return $result === NET_SFTP_TYPE_SYMLINK;
     }
 
+    /**
+     * Tells whether a file exists and is readable
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function is_readable($path)
+    {
+        $path = $this->_realpath($path);
+
+        $packet = pack('Na*N2', strlen($path), $path, NET_SFTP_OPEN_READ, 0);
+        if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_HANDLE:
+                return true;
+            case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+                return false;
+            default:
+                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+                return false;
+        }
+    }
+
+    /**
+     * Tells whether the filename is writable
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function is_writable($path)
+    {
+        $path = $this->_realpath($path);
+
+        $packet = pack('Na*N2', strlen($path), $path, NET_SFTP_OPEN_WRITE, 0);
+        if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_HANDLE:
+                return true;
+            case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+                return false;
+            default:
+                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+                return false;
+        }
+    }
+
+    /**
+     * Tells whether the filename is writeable
+     *
+     * Alias of is_writable
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function is_writeable($path)
+    {
+        return $this->is_writable($path);
+    }
+
     /**
      * Gets last access time of file
      *
-     * @param String $path
-     * @return Mixed
+     * @param string $path
+     * @return mixed
      * @access public
      */
     function fileatime($path)
@@ -2295,8 +2496,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Gets file modification time
      *
-     * @param String $path
-     * @return Mixed
+     * @param string $path
+     * @return mixed
      * @access public
      */
     function filemtime($path)
@@ -2307,8 +2508,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Gets file permissions
      *
-     * @param String $path
-     * @return Mixed
+     * @param string $path
+     * @return mixed
      * @access public
      */
     function fileperms($path)
@@ -2319,8 +2520,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Gets file owner
      *
-     * @param String $path
-     * @return Mixed
+     * @param string $path
+     * @return mixed
      * @access public
      */
     function fileowner($path)
@@ -2331,8 +2532,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Gets file group
      *
-     * @param String $path
-     * @return Mixed
+     * @param string $path
+     * @return mixed
      * @access public
      */
     function filegroup($path)
@@ -2343,8 +2544,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Gets file size
      *
-     * @param String $path
-     * @return Mixed
+     * @param string $path
+     * @return mixed
      * @access public
      */
     function filesize($path)
@@ -2355,8 +2556,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Gets file type
      *
-     * @param String $path
-     * @return Mixed
+     * @param string $path
+     * @return mixed
      * @access public
      */
     function filetype($path)
@@ -2367,13 +2568,20 @@ class Net_SFTP extends Net_SSH2
         }
 
         switch ($type) {
-            case NET_SFTP_TYPE_BLOCK_DEVICE: return 'block';
-            case NET_SFTP_TYPE_CHAR_DEVICE: return 'char';
-            case NET_SFTP_TYPE_DIRECTORY: return 'dir';
-            case NET_SFTP_TYPE_FIFO: return 'fifo';
-            case NET_SFTP_TYPE_REGULAR: return 'file';
-            case NET_SFTP_TYPE_SYMLINK: return 'link';
-            default: return false;
+            case NET_SFTP_TYPE_BLOCK_DEVICE:
+                return 'block';
+            case NET_SFTP_TYPE_CHAR_DEVICE:
+                return 'char';
+            case NET_SFTP_TYPE_DIRECTORY:
+                return 'dir';
+            case NET_SFTP_TYPE_FIFO:
+                return 'fifo';
+            case NET_SFTP_TYPE_REGULAR:
+                return 'file';
+            case NET_SFTP_TYPE_SYMLINK:
+                return 'link';
+            default:
+                return false;
         }
     }
 
@@ -2382,24 +2590,54 @@ class Net_SFTP extends Net_SSH2
      *
      * Uses cache if appropriate.
      *
-     * @param String $path
-     * @param String $prop
-     * @return Mixed
+     * @param string $path
+     * @param string $prop
+     * @return mixed
      * @access private
      */
     function _get_stat_cache_prop($path, $prop)
+    {
+        return $this->_get_xstat_cache_prop($path, $prop, 'stat');
+    }
+
+    /**
+     * Return an lstat properity
+     *
+     * Uses cache if appropriate.
+     *
+     * @param string $path
+     * @param string $prop
+     * @return mixed
+     * @access private
+     */
+    function _get_lstat_cache_prop($path, $prop)
+    {
+        return $this->_get_xstat_cache_prop($path, $prop, 'lstat');
+    }
+
+    /**
+     * Return a stat or lstat properity
+     *
+     * Uses cache if appropriate.
+     *
+     * @param string $path
+     * @param string $prop
+     * @return mixed
+     * @access private
+     */
+    function _get_xstat_cache_prop($path, $prop, $type)
     {
         if ($this->use_stat_cache) {
             $path = $this->_realpath($path);
 
             $result = $this->_query_stat_cache($path);
 
-            if (is_object($result) && isset($result->$prop)) {
-                return $result->$prop;
+            if (is_object($result) && isset($result->$type)) {
+                return $result->{$type}[$prop];
             }
         }
 
-        $result = $this->stat($path);
+        $result = $this->$type($path);
 
         if ($result === false || !isset($result[$prop])) {
             return false;
@@ -2411,9 +2649,9 @@ class Net_SFTP extends Net_SSH2
     /**
      * Renames a file or a directory on the SFTP server
      *
-     * @param String $oldname
-     * @param String $newname
-     * @return Boolean
+     * @param string $oldname
+     * @param string $newname
+     * @return bool
      * @access public
      */
     function rename($oldname, $newname)
@@ -2461,8 +2699,8 @@ class Net_SFTP extends Net_SSH2
      *
      * See '7.  File Attributes' of draft-ietf-secsh-filexfer-13 for more info.
      *
-     * @param String $response
-     * @return Array
+     * @param string $response
+     * @return array
      * @access private
      */
     function _parseAttributes(&$response)
@@ -2515,8 +2753,8 @@ class Net_SFTP extends Net_SSH2
      *
      * Quoting the SFTP RFC, "Implementations MUST NOT send bits that are not defined" but they seem to anyway
      *
-     * @param Integer $mode
-     * @return Integer
+     * @param int $mode
+     * @return int
      * @access private
      */
     function _parseMode($mode)
@@ -2562,8 +2800,8 @@ class Net_SFTP extends Net_SSH2
      *
      * If the longname is in an unrecognized format bool(false) is returned.
      *
-     * @param String $longname
-     * @return Mixed
+     * @param string $longname
+     * @return mixed
      * @access private
      */
     function _parseLongname($longname)
@@ -2591,18 +2829,18 @@ class Net_SFTP extends Net_SSH2
      *
      * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.
      *
-     * @param Integer $type
-     * @param String $data
-     * @see Net_SFTP::_get_sftp_packet()
+     * @param int $type
+     * @param string $data
+     * @see self::_get_sftp_packet()
      * @see Net_SSH2::_send_channel_packet()
-     * @return Boolean
+     * @return bool
      * @access private
      */
     function _send_sftp_packet($type, $data)
     {
         $packet = $this->request_id !== false ?
             pack('NCNa*', strlen($data) + 5, $type, $this->request_id, $data) :
-            pack('NCa*',  strlen($data) + 1, $type, $data);
+            pack('NCa*', strlen($data) + 1, $type, $data);
 
         $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
         $result = $this->_send_channel_packet(NET_SFTP_CHANNEL, $packet);
@@ -2635,8 +2873,8 @@ class Net_SFTP extends Net_SSH2
      * There can be one SSH_MSG_CHANNEL_DATA messages containing two SFTP packets or there can be two SSH_MSG_CHANNEL_DATA
      * messages containing one SFTP packet.
      *
-     * @see Net_SFTP::_send_sftp_packet()
-     * @return String
+     * @see self::_send_sftp_packet()
+     * @return string
      * @access private
      */
     function _get_sftp_packet()
@@ -2708,7 +2946,7 @@ class Net_SFTP extends Net_SSH2
      * Returns a string if NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX, an array if NET_SFTP_LOGGING == NET_SFTP_LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING')
      *
      * @access public
-     * @return String or Array
+     * @return string or Array
      */
     function getSFTPLog()
     {
@@ -2729,7 +2967,7 @@ class Net_SFTP extends Net_SSH2
     /**
      * Returns all errors
      *
-     * @return String
+     * @return string
      * @access public
      */
     function getSFTPErrors()
@@ -2740,7 +2978,7 @@ class Net_SFTP extends Net_SSH2
     /**
      * Returns the last error
      *
-     * @return String
+     * @return string
      * @access public
      */
     function getLastSFTPError()
@@ -2751,7 +2989,7 @@ class Net_SFTP extends Net_SSH2
     /**
      * Get supported SFTP versions
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getSupportedVersions()
@@ -2766,8 +3004,8 @@ class Net_SFTP extends Net_SSH2
     /**
      * Disconnect
      *
-     * @param Integer $reason
-     * @return Boolean
+     * @param int $reason
+     * @return bool
      * @access private
      */
     function _disconnect($reason)
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
index eda1cdbab50ba5517be6249bf03e5ea1a9fbde01..a944d7f0a80a9bef4f7c9960644c0b05d9276e99 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
@@ -47,14 +47,14 @@ class Net_SFTP_Stream
      *
      * Rather than re-create the connection we re-use instances if possible
      *
-     * @var Array
+     * @var array
      */
     static $instances;
 
     /**
      * SFTP instance
      *
-     * @var Object
+     * @var object
      * @access private
      */
     var $sftp;
@@ -62,7 +62,7 @@ class Net_SFTP_Stream
     /**
      * Path
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $path;
@@ -70,7 +70,7 @@ class Net_SFTP_Stream
     /**
      * Mode
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $mode;
@@ -78,7 +78,7 @@ class Net_SFTP_Stream
     /**
      * Position
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $pos;
@@ -86,7 +86,7 @@ class Net_SFTP_Stream
     /**
      * Size
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $size;
@@ -94,7 +94,7 @@ class Net_SFTP_Stream
     /**
      * Directory entries
      *
-     * @var Array
+     * @var array
      * @access private
      */
     var $entries;
@@ -102,7 +102,7 @@ class Net_SFTP_Stream
     /**
      * EOF flag
      *
-     * @var Boolean
+     * @var bool
      * @access private
      */
     var $eof;
@@ -112,7 +112,7 @@ class Net_SFTP_Stream
      *
      * Technically this needs to be publically accessible so PHP can set it directly
      *
-     * @var Resource
+     * @var resource
      * @access public
      */
     var $context;
@@ -120,7 +120,7 @@ class Net_SFTP_Stream
     /**
      * Notification callback function
      *
-     * @var Callable
+     * @var callable
      * @access public
      */
     var $notification;
@@ -128,8 +128,8 @@ class Net_SFTP_Stream
     /**
      * Registers this class as a URL wrapper.
      *
-     * @param optional String $protocol The wrapper name to be registered.
-     * @return Boolean True on success, false otherwise.
+     * @param string $protocol The wrapper name to be registered.
+     * @return bool True on success, false otherwise.
      * @access public
      */
     static function register($protocol = 'sftp')
@@ -146,7 +146,7 @@ class Net_SFTP_Stream
      *
      * @access public
      */
-    function Net_SFTP_Stream()
+    function __construct()
     {
         if (defined('NET_SFTP_STREAM_LOGGING')) {
             echo "__construct()\r\n";
@@ -165,13 +165,24 @@ class Net_SFTP_Stream
      * If "notification" is set as a context parameter the message code for successful login is
      * NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE.
      *
-     * @param String $path
-     * @return String
+     * @param string $path
+     * @return string
      * @access private
      */
     function _parse_path($path)
     {
+        $orig = $path;
         extract(parse_url($path) + array('port' => 22));
+        if (isset($query)) {
+            $path.= '?' . $query;
+        } elseif (preg_match('/(\?|\?#)$/', $orig)) {
+            $path.= '?';
+        }
+        if (isset($fragment)) {
+            $path.= '#' . $fragment;
+        } elseif ($orig[strlen($orig) - 1] == '#') {
+            $path.= '#';
+        }
 
         if (!isset($host)) {
             return false;
@@ -257,11 +268,11 @@ class Net_SFTP_Stream
     /**
      * Opens file or URL
      *
-     * @param String $path
-     * @param String $mode
-     * @param Integer $options
-     * @param String $opened_path
-     * @return Boolean
+     * @param string $path
+     * @param string $mode
+     * @param int $options
+     * @param string $opened_path
+     * @return bool
      * @access public
      */
     function _stream_open($path, $mode, $options, &$opened_path)
@@ -280,14 +291,17 @@ class Net_SFTP_Stream
         if ($this->size === false) {
             if ($this->mode[0] == 'r') {
                 return false;
+            } else {
+                $this->sftp->touch($path);
+                $this->size = 0;
             }
         } else {
             switch ($this->mode[0]) {
                 case 'x':
                     return false;
                 case 'w':
-                case 'c':
                     $this->sftp->truncate($path, 0);
+                    $this->size = 0;
             }
         }
 
@@ -299,8 +313,8 @@ class Net_SFTP_Stream
     /**
      * Read from stream
      *
-     * @param Integer $count
-     * @return Mixed
+     * @param int $count
+     * @return mixed
      * @access public
      */
     function _stream_read($count)
@@ -341,8 +355,8 @@ class Net_SFTP_Stream
     /**
      * Write to stream
      *
-     * @param String $data
-     * @return Mixed
+     * @param string $data
+     * @return mixed
      * @access public
      */
     function _stream_write($data)
@@ -376,7 +390,7 @@ class Net_SFTP_Stream
     /**
      * Retrieve the current position of a stream
      *
-     * @return Integer
+     * @return int
      * @access public
      */
     function _stream_tell()
@@ -394,7 +408,7 @@ class Net_SFTP_Stream
      * will return false. do fread($fp, 1) and feof() will then return true. do fseek($fp, 10) on ablank file and feof()
      * will return false. do fread($fp, 1) and feof() will then return true.
      *
-     * @return Boolean
+     * @return bool
      * @access public
      */
     function _stream_eof()
@@ -405,9 +419,9 @@ class Net_SFTP_Stream
     /**
      * Seeks to specific location in a stream
      *
-     * @param Integer $offset
-     * @param Integer $whence
-     * @return Boolean
+     * @param int $offset
+     * @param int $whence
+     * @return bool
      * @access public
      */
     function _stream_seek($offset, $whence)
@@ -433,10 +447,10 @@ class Net_SFTP_Stream
     /**
      * Change stream options
      *
-     * @param String $path
-     * @param Integer $option
-     * @param Mixed $var
-     * @return Boolean
+     * @param string $path
+     * @param int $option
+     * @param mixed $var
+     * @return bool
      * @access public
      */
     function _stream_metadata($path, $option, $var)
@@ -467,8 +481,8 @@ class Net_SFTP_Stream
     /**
      * Retrieve the underlaying resource
      *
-     * @param Integer $cast_as
-     * @return Resource
+     * @param int $cast_as
+     * @return resource
      * @access public
      */
     function _stream_cast($cast_as)
@@ -479,8 +493,8 @@ class Net_SFTP_Stream
     /**
      * Advisory file locking
      *
-     * @param Integer $operation
-     * @return Boolean
+     * @param int $operation
+     * @return bool
      * @access public
      */
     function _stream_lock($operation)
@@ -495,9 +509,9 @@ class Net_SFTP_Stream
      * If newname exists, it will be overwritten.  This is a departure from what Net_SFTP
      * does.
      *
-     * @param String $path_from
-     * @param String $path_to
-     * @return Boolean
+     * @param string $path_from
+     * @param string $path_to
+     * @return bool
      * @access public
      */
     function _rename($path_from, $path_to)
@@ -511,7 +525,7 @@ class Net_SFTP_Stream
 
         $path_from = $this->_parse_path($path_from);
         $path_to = parse_url($path_to);
-        if ($path_from == false) {
+        if ($path_from === false) {
             return false;
         }
 
@@ -547,9 +561,9 @@ class Net_SFTP_Stream
      *                string     longname
      *                ATTRS      attrs
      *
-     * @param String $path
-     * @param Integer $options
-     * @return Boolean
+     * @param string $path
+     * @param int $options
+     * @return bool
      * @access public
      */
     function _dir_opendir($path, $options)
@@ -566,7 +580,7 @@ class Net_SFTP_Stream
     /**
      * Read entry from directory handle
      *
-     * @return Mixed
+     * @return mixed
      * @access public
      */
     function _dir_readdir()
@@ -580,7 +594,7 @@ class Net_SFTP_Stream
     /**
      * Rewind directory handle
      *
-     * @return Boolean
+     * @return bool
      * @access public
      */
     function _dir_rewinddir()
@@ -592,7 +606,7 @@ class Net_SFTP_Stream
     /**
      * Close directory handle
      *
-     * @return Boolean
+     * @return bool
      * @access public
      */
     function _dir_closedir()
@@ -605,10 +619,10 @@ class Net_SFTP_Stream
      *
      * Only valid $options is STREAM_MKDIR_RECURSIVE
      *
-     * @param String $path
-     * @param Integer $mode
-     * @param Integer $options
-     * @return Boolean
+     * @param string $path
+     * @param int $mode
+     * @param int $options
+     * @return bool
      * @access public
      */
     function _mkdir($path, $mode, $options)
@@ -629,10 +643,10 @@ class Net_SFTP_Stream
      * STREAM_MKDIR_RECURSIVE is supposed to be set. Also, when I try it out with rmdir() I get 8 as
      * $options. What does 8 correspond to?
      *
-     * @param String $path
-     * @param Integer $mode
-     * @param Integer $options
-     * @return Boolean
+     * @param string $path
+     * @param int $mode
+     * @param int $options
+     * @return bool
      * @access public
      */
     function _rmdir($path, $options)
@@ -650,7 +664,7 @@ class Net_SFTP_Stream
      *
      * See <http://php.net/fflush>. Always returns true because Net_SFTP doesn't cache stuff before writing
      *
-     * @return Boolean
+     * @return bool
      * @access public
      */
     function _stream_flush()
@@ -661,7 +675,7 @@ class Net_SFTP_Stream
     /**
      * Retrieve information about a file resource
      *
-     * @return Mixed
+     * @return mixed
      * @access public
      */
     function _stream_stat()
@@ -676,8 +690,8 @@ class Net_SFTP_Stream
     /**
      * Delete a file
      *
-     * @param String $path
-     * @return Boolean
+     * @param string $path
+     * @return bool
      * @access public
      */
     function _unlink($path)
@@ -697,9 +711,9 @@ class Net_SFTP_Stream
      * might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll
      * cross that bridge when and if it's reached
      *
-     * @param String $path
-     * @param Integer $flags
-     * @return Mixed
+     * @param string $path
+     * @param int $flags
+     * @return mixed
      * @access public
      */
     function _url_stat($path, $flags)
@@ -720,8 +734,8 @@ class Net_SFTP_Stream
     /**
      * Truncate stream
      *
-     * @param Integer $new_size
-     * @return Boolean
+     * @param int $new_size
+     * @return bool
      * @access public
      */
     function _stream_truncate($new_size)
@@ -742,10 +756,10 @@ class Net_SFTP_Stream
      * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't.
      * The other two aren't supported because of limitations in Net_SFTP.
      *
-     * @param Integer $option
-     * @param Integer $arg1
-     * @param Integer $arg2
-     * @return Boolean
+     * @param int $option
+     * @param int $arg1
+     * @param int $arg2
+     * @return bool
      * @access public
      */
     function _stream_set_option($option, $arg1, $arg2)
@@ -772,9 +786,9 @@ class Net_SFTP_Stream
      * If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not
      * NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method.
      *
-     * @param String
-     * @param Array
-     * @return Mixed
+     * @param string
+     * @param array
+     * @return mixed
      * @access public
      */
     function __call($name, $arguments)
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php
index f1fae02ba7349ab6cbef9ec37ced22009b40bd5b..fb23daa65f5a84e8ab1de901e0229df10e31c6ef 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php
@@ -67,7 +67,7 @@
 /**#@+
  * Encryption Methods
  *
- * @see Net_SSH1::getSupportedCiphers()
+ * @see self::getSupportedCiphers()
  * @access public
  */
 /**
@@ -127,7 +127,7 @@ define('NET_SSH1_CIPHER_BLOWFISH',   6);
 /**#@+
  * Authentication Methods
  *
- * @see Net_SSH1::getSupportedAuthentications()
+ * @see self::getSupportedAuthentications()
  * @access public
  */
 /**
@@ -162,7 +162,7 @@ define('NET_SSH1_TTY_OP_END',  0);
 /**
  * The Response Type
  *
- * @see Net_SSH1::_get_binary_packet()
+ * @see self::_get_binary_packet()
  * @access private
  */
 define('NET_SSH1_RESPONSE_TYPE', 1);
@@ -170,7 +170,7 @@ define('NET_SSH1_RESPONSE_TYPE', 1);
 /**
  * The Response Data
  *
- * @see Net_SSH1::_get_binary_packet()
+ * @see self::_get_binary_packet()
  * @access private
  */
 define('NET_SSH1_RESPONSE_DATA', 2);
@@ -178,7 +178,7 @@ define('NET_SSH1_RESPONSE_DATA', 2);
 /**#@+
  * Execution Bitmap Masks
  *
- * @see Net_SSH1::bitmap
+ * @see self::bitmap
  * @access private
  */
 define('NET_SSH1_MASK_CONSTRUCTOR', 0x00000001);
@@ -189,7 +189,7 @@ define('NET_SSH1_MASK_SHELL',       0x00000008);
 
 /**#@+
  * @access public
- * @see Net_SSH1::getLog()
+ * @see self::getLog()
  */
 /**
  * Returns the message numbers
@@ -211,7 +211,7 @@ define('NET_SSH1_LOG_REALTIME_FILE', 4);
 
 /**#@+
  * @access public
- * @see Net_SSH1::read()
+ * @see self::read()
  */
 /**
  * Returns when a string matching $expect exactly is found
@@ -235,7 +235,7 @@ class Net_SSH1
     /**
      * The SSH identifier
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $identifier = 'SSH-1.5-phpseclib';
@@ -243,7 +243,7 @@ class Net_SSH1
     /**
      * The Socket Object
      *
-     * @var Object
+     * @var object
      * @access private
      */
     var $fsock;
@@ -251,7 +251,7 @@ class Net_SSH1
     /**
      * The cryptography object
      *
-     * @var Object
+     * @var object
      * @access private
      */
     var $crypto = false;
@@ -262,7 +262,7 @@ class Net_SSH1
      * The bits that are set represent functions that have been called already.  This is used to determine
      * if a requisite function has been successfully executed.  If not, an error should be thrown.
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $bitmap = 0;
@@ -272,8 +272,8 @@ class Net_SSH1
      *
      * Logged for debug purposes
      *
-     * @see Net_SSH1::getServerKeyPublicExponent()
-     * @var String
+     * @see self::getServerKeyPublicExponent()
+     * @var string
      * @access private
      */
     var $server_key_public_exponent;
@@ -283,8 +283,8 @@ class Net_SSH1
      *
      * Logged for debug purposes
      *
-     * @see Net_SSH1::getServerKeyPublicModulus()
-     * @var String
+     * @see self::getServerKeyPublicModulus()
+     * @var string
      * @access private
      */
     var $server_key_public_modulus;
@@ -294,8 +294,8 @@ class Net_SSH1
      *
      * Logged for debug purposes
      *
-     * @see Net_SSH1::getHostKeyPublicExponent()
-     * @var String
+     * @see self::getHostKeyPublicExponent()
+     * @var string
      * @access private
      */
     var $host_key_public_exponent;
@@ -305,8 +305,8 @@ class Net_SSH1
      *
      * Logged for debug purposes
      *
-     * @see Net_SSH1::getHostKeyPublicModulus()
-     * @var String
+     * @see self::getHostKeyPublicModulus()
+     * @var string
      * @access private
      */
     var $host_key_public_modulus;
@@ -316,8 +316,8 @@ class Net_SSH1
      *
      * Logged for debug purposes
      *
-     * @see Net_SSH1::getSupportedCiphers()
-     * @var Array
+     * @see self::getSupportedCiphers()
+     * @var array
      * @access private
      */
     var $supported_ciphers = array(
@@ -335,8 +335,8 @@ class Net_SSH1
      *
      * Logged for debug purposes
      *
-     * @see Net_SSH1::getSupportedAuthentications()
-     * @var Array
+     * @see self::getSupportedAuthentications()
+     * @var array
      * @access private
      */
     var $supported_authentications = array(
@@ -349,8 +349,8 @@ class Net_SSH1
     /**
      * Server Identification
      *
-     * @see Net_SSH1::getServerIdentification()
-     * @var String
+     * @see self::getServerIdentification()
+     * @var string
      * @access private
      */
     var $server_identification = '';
@@ -358,8 +358,8 @@ class Net_SSH1
     /**
      * Protocol Flags
      *
-     * @see Net_SSH1::Net_SSH1()
-     * @var Array
+     * @see self::Net_SSH1()
+     * @var array
      * @access private
      */
     var $protocol_flags = array();
@@ -367,8 +367,8 @@ class Net_SSH1
     /**
      * Protocol Flag Log
      *
-     * @see Net_SSH1::getLog()
-     * @var Array
+     * @see self::getLog()
+     * @var array
      * @access private
      */
     var $protocol_flag_log = array();
@@ -376,8 +376,8 @@ class Net_SSH1
     /**
      * Message Log
      *
-     * @see Net_SSH1::getLog()
-     * @var Array
+     * @see self::getLog()
+     * @var array
      * @access private
      */
     var $message_log = array();
@@ -385,8 +385,8 @@ class Net_SSH1
     /**
      * Real-time log file pointer
      *
-     * @see Net_SSH1::_append_log()
-     * @var Resource
+     * @see self::_append_log()
+     * @var resource
      * @access private
      */
     var $realtime_log_file;
@@ -394,8 +394,8 @@ class Net_SSH1
     /**
      * Real-time log file size
      *
-     * @see Net_SSH1::_append_log()
-     * @var Integer
+     * @see self::_append_log()
+     * @var int
      * @access private
      */
     var $realtime_log_size;
@@ -403,8 +403,8 @@ class Net_SSH1
     /**
      * Real-time log file wrap boolean
      *
-     * @see Net_SSH1::_append_log()
-     * @var Boolean
+     * @see self::_append_log()
+     * @var bool
      * @access private
      */
     var $realtime_log_wrap;
@@ -412,8 +412,8 @@ class Net_SSH1
     /**
      * Interactive Buffer
      *
-     * @see Net_SSH1::read()
-     * @var Array
+     * @see self::read()
+     * @var array
      * @access private
      */
     var $interactiveBuffer = '';
@@ -421,7 +421,7 @@ class Net_SSH1
     /**
      * Timeout
      *
-     * @see Net_SSH1::setTimeout()
+     * @see self::setTimeout()
      * @access private
      */
     var $timeout;
@@ -429,7 +429,7 @@ class Net_SSH1
     /**
      * Current Timeout
      *
-     * @see Net_SSH1::_get_channel_packet()
+     * @see self::_get_channel_packet()
      * @access private
      */
     var $curTimeout;
@@ -437,7 +437,7 @@ class Net_SSH1
     /**
      * Log Boundary
      *
-     * @see Net_SSH1::_format_log
+     * @see self::_format_log()
      * @access private
      */
     var $log_boundary = ':';
@@ -445,7 +445,7 @@ class Net_SSH1
     /**
      * Log Long Width
      *
-     * @see Net_SSH1::_format_log
+     * @see self::_format_log()
      * @access private
      */
     var $log_long_width = 65;
@@ -453,7 +453,7 @@ class Net_SSH1
     /**
      * Log Short Width
      *
-     * @see Net_SSH1::_format_log
+     * @see self::_format_log()
      * @access private
      */
     var $log_short_width = 16;
@@ -461,9 +461,9 @@ class Net_SSH1
     /**
      * Hostname
      *
-     * @see Net_SSH1::Net_SSH1()
-     * @see Net_SSH1::_connect()
-     * @var String
+     * @see self::Net_SSH1()
+     * @see self::_connect()
+     * @var string
      * @access private
      */
     var $host;
@@ -471,9 +471,9 @@ class Net_SSH1
     /**
      * Port Number
      *
-     * @see Net_SSH1::Net_SSH1()
-     * @see Net_SSH1::_connect()
-     * @var Integer
+     * @see self::Net_SSH1()
+     * @see self::_connect()
+     * @var int
      * @access private
      */
     var $port;
@@ -486,9 +486,9 @@ class Net_SSH1
      * however, is non-optional. There will be a timeout, whether or not you set it. If you don't it'll be
      * 10 seconds. It is used by fsockopen() in that function.
      *
-     * @see Net_SSH1::Net_SSH1()
-     * @see Net_SSH1::_connect()
-     * @var Integer
+     * @see self::Net_SSH1()
+     * @see self::_connect()
+     * @var int
      * @access private
      */
     var $connectionTimeout;
@@ -496,9 +496,9 @@ class Net_SSH1
     /**
      * Default cipher
      *
-     * @see Net_SSH1::Net_SSH1()
-     * @see Net_SSH1::_connect()
-     * @var Integer
+     * @see self::Net_SSH1()
+     * @see self::_connect()
+     * @var int
      * @access private
      */
     var $cipher;
@@ -508,14 +508,14 @@ class Net_SSH1
      *
      * Connects to an SSHv1 server
      *
-     * @param String $host
-     * @param optional Integer $port
-     * @param optional Integer $timeout
-     * @param optional Integer $cipher
+     * @param string $host
+     * @param int $port
+     * @param int $timeout
+     * @param int $cipher
      * @return Net_SSH1
      * @access public
      */
-    function Net_SSH1($host, $port = 22, $timeout = 10, $cipher = NET_SSH1_CIPHER_3DES)
+    function __construct($host, $port = 22, $timeout = 10, $cipher = NET_SSH1_CIPHER_3DES)
     {
         if (!class_exists('Math_BigInteger')) {
             include_once 'Math/BigInteger.php';
@@ -557,10 +557,25 @@ class Net_SSH1
         $this->cipher = $cipher;
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @param string $host
+     * @param int $port
+     * @param int $timeout
+     * @param int $cipher
+     * @access public
+     */
+    function Net_SSH1($host, $port = 22, $timeout = 10, $cipher = NET_SSH1_CIPHER_3DES)
+    {
+        $this->__construct($host, $port, $timeout, $cipher);
+    }
+
     /**
      * Connect to an SSHv1 server
      *
-     * @return Boolean
+     * @return bool
      * @access private
      */
     function _connect()
@@ -621,7 +636,7 @@ class Net_SSH1
 
         // get a list of the supported ciphers
         extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4)));
-        foreach ($this->supported_ciphers as $mask=>$name) {
+        foreach ($this->supported_ciphers as $mask => $name) {
             if (($supported_ciphers_mask & (1 << $mask)) == 0) {
                 unset($this->supported_ciphers[$mask]);
             }
@@ -629,7 +644,7 @@ class Net_SSH1
 
         // get a list of the supported authentications
         extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4)));
-        foreach ($this->supported_authentications as $mask=>$name) {
+        foreach ($this->supported_authentications as $mask => $name) {
             if (($supported_authentications_mask & (1 << $mask)) == 0) {
                 unset($this->supported_authentications[$mask]);
             }
@@ -691,7 +706,7 @@ class Net_SSH1
                 $this->crypto = new Crypt_DES();
                 $this->crypto->disablePadding();
                 $this->crypto->enableContinuousBuffer();
-                $this->crypto->setKey(substr($session_key, 0,  8));
+                $this->crypto->setKey(substr($session_key, 0, 8));
                 break;
             case NET_SSH1_CIPHER_3DES:
                 if (!class_exists('Crypt_TripleDES')) {
@@ -727,9 +742,9 @@ class Net_SSH1
     /**
      * Login
      *
-     * @param String $username
-     * @param optional String $password
-     * @return Boolean
+     * @param string $username
+     * @param string $password
+     * @return bool
      * @access public
      */
     function login($username, $password = '')
@@ -760,7 +775,7 @@ class Net_SSH1
         if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
             $this->bitmap |= NET_SSH1_MASK_LOGIN;
             return true;
-        } else if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
+        } elseif ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
             user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
             return false;
         }
@@ -786,7 +801,7 @@ class Net_SSH1
         if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
             $this->bitmap |= NET_SSH1_MASK_LOGIN;
             return true;
-        } else if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
+        } elseif ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
             return false;
         } else {
             user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
@@ -800,7 +815,7 @@ class Net_SSH1
      * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely.  setTimeout() makes it so it'll timeout.
      * Setting $timeout to false or 0 will mean there is no timeout.
      *
-     * @param Mixed $timeout
+     * @param mixed $timeout
      */
     function setTimeout($timeout)
     {
@@ -821,9 +836,9 @@ class Net_SSH1
      *
      * Returns false on failure and the output, otherwise.
      *
-     * @see Net_SSH1::interactiveRead()
-     * @see Net_SSH1::interactiveWrite()
-     * @param String $cmd
+     * @see self::interactiveRead()
+     * @see self::interactiveWrite()
+     * @param string $cmd
      * @return mixed
      * @access public
      */
@@ -871,9 +886,9 @@ class Net_SSH1
     /**
      * Creates an interactive shell
      *
-     * @see Net_SSH1::interactiveRead()
-     * @see Net_SSH1::interactiveWrite()
-     * @return Boolean
+     * @see self::interactiveRead()
+     * @see self::interactiveWrite()
+     * @return bool
      * @access private
      */
     function _initShell()
@@ -915,9 +930,9 @@ class Net_SSH1
     /**
      * Inputs a command into an interactive shell.
      *
-     * @see Net_SSH1::interactiveWrite()
-     * @param String $cmd
-     * @return Boolean
+     * @see self::interactiveWrite()
+     * @param string $cmd
+     * @return bool
      * @access public
      */
     function write($cmd)
@@ -931,10 +946,10 @@ class Net_SSH1
      * $expect can take the form of a string literal or, if $mode == NET_SSH1_READ_REGEX,
      * a regular expression.
      *
-     * @see Net_SSH1::write()
-     * @param String $expect
-     * @param Integer $mode
-     * @return Boolean
+     * @see self::write()
+     * @param string $expect
+     * @param int $mode
+     * @return bool
      * @access public
      */
     function read($expect, $mode = NET_SSH1_READ_SIMPLE)
@@ -971,9 +986,9 @@ class Net_SSH1
     /**
      * Inputs a command into an interactive shell.
      *
-     * @see Net_SSH1::interactiveRead()
-     * @param String $cmd
-     * @return Boolean
+     * @see self::interactiveRead()
+     * @param string $cmd
+     * @return bool
      * @access public
      */
     function interactiveWrite($cmd)
@@ -1007,8 +1022,8 @@ class Net_SSH1
      * does not support ANSI escape sequences in Win32 Console applications", so if you're a Windows user,
      * there's not going to be much recourse.
      *
-     * @see Net_SSH1::interactiveRead()
-     * @return String
+     * @see self::interactiveRead()
+     * @return string
      * @access public
      */
     function interactiveRead()
@@ -1059,7 +1074,7 @@ class Net_SSH1
     /**
      * Disconnect
      *
-     * @param String $msg
+     * @param string $msg
      * @access private
      */
     function _disconnect($msg = 'Client Quit')
@@ -1096,8 +1111,8 @@ class Net_SSH1
      * Also, this function could be improved upon by adding detection for the following exploit:
      * http://www.securiteam.com/securitynews/5LP042K3FY.html
      *
-     * @see Net_SSH1::_send_binary_packet()
-     * @return Array
+     * @see self::_send_binary_packet()
+     * @return array
      * @access private
      */
     function _get_binary_packet()
@@ -1172,9 +1187,9 @@ class Net_SSH1
      *
      * Returns true on success, false on failure.
      *
-     * @see Net_SSH1::_get_binary_packet()
-     * @param String $data
-     * @return Boolean
+     * @see self::_get_binary_packet()
+     * @param string $data
+     * @return bool
      * @access private
      */
     function _send_binary_packet($data)
@@ -1219,10 +1234,10 @@ class Net_SSH1
      * we've reimplemented it. A more detailed discussion of the differences can be found after
      * $crc_lookup_table's initialization.
      *
-     * @see Net_SSH1::_get_binary_packet()
-     * @see Net_SSH1::_send_binary_packet()
-     * @param String $data
-     * @return Integer
+     * @see self::_get_binary_packet()
+     * @see self::_send_binary_packet()
+     * @param string $data
+     * @return int
      * @access private
      */
     function _crc($data)
@@ -1299,7 +1314,7 @@ class Net_SSH1
         $crc = 0x00000000;
         $length = strlen($data);
 
-        for ($i=0;$i<$length;$i++) {
+        for ($i=0; $i<$length; $i++) {
             // We AND $crc >> 8 with 0x00FFFFFF because we want the eight newly added bits to all
             // be zero.  PHP, unfortunately, doesn't always do this.  0x80000000 >> 8, as an example,
             // yields 0xFF800000 - not 0x00800000.  The following link elaborates:
@@ -1317,9 +1332,9 @@ class Net_SSH1
      *
      * Inspired by array_shift
      *
-     * @param String $string
-     * @param optional Integer $index
-     * @return String
+     * @param string $string
+     * @param int $index
+     * @return string
      * @access private
      */
     function _string_shift(&$string, $index = 1)
@@ -1336,9 +1351,9 @@ class Net_SSH1
      * should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1.  Could just make anything that
      * calls this call modexp, instead, but I think this makes things clearer, maybe...
      *
-     * @see Net_SSH1::Net_SSH1()
+     * @see self::Net_SSH1()
      * @param Math_BigInteger $m
-     * @param Array $key
+     * @param array $key
      * @return Math_BigInteger
      * @access private
      */
@@ -1391,14 +1406,14 @@ class Net_SSH1
      * named constants from it, using the value as the name of the constant and the index as the value of the constant.
      * If any of the constants that would be defined already exists, none of the constants will be defined.
      *
-     * @param Array $array
+     * @param array $array
      * @access private
      */
     function _define_array()
     {
         $args = func_get_args();
         foreach ($args as $arg) {
-            foreach ($arg as $key=>$value) {
+            foreach ($arg as $key => $value) {
                 if (!defined($value)) {
                     define($value, $key);
                 } else {
@@ -1414,7 +1429,7 @@ class Net_SSH1
      * Returns a string if NET_SSH1_LOGGING == NET_SSH1_LOG_COMPLEX, an array if NET_SSH1_LOGGING == NET_SSH1_LOG_SIMPLE and false if !defined('NET_SSH1_LOGGING')
      *
      * @access public
-     * @return String or Array
+     * @return array|false|string
      */
     function getLog()
     {
@@ -1437,10 +1452,10 @@ class Net_SSH1
     /**
      * Formats a log for printing
      *
-     * @param Array $message_log
-     * @param Array $message_number_log
+     * @param array $message_log
+     * @param array $message_number_log
      * @access private
-     * @return String
+     * @return string
      */
     function _format_log($message_log, $message_number_log)
     {
@@ -1473,9 +1488,9 @@ class Net_SSH1
      *
      * For use with preg_replace_callback()
      *
-     * @param Array $matches
+     * @param array $matches
      * @access private
-     * @return String
+     * @return string
      */
     function _format_log_helper($matches)
     {
@@ -1488,8 +1503,8 @@ class Net_SSH1
      * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,
      * the raw bytes.  This behavior is similar to PHP's md5() function.
      *
-     * @param optional Boolean $raw_output
-     * @return String
+     * @param bool $raw_output
+     * @return string
      * @access public
      */
     function getServerKeyPublicExponent($raw_output = false)
@@ -1503,8 +1518,8 @@ class Net_SSH1
      * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,
      * the raw bytes.  This behavior is similar to PHP's md5() function.
      *
-     * @param optional Boolean $raw_output
-     * @return String
+     * @param bool $raw_output
+     * @return string
      * @access public
      */
     function getServerKeyPublicModulus($raw_output = false)
@@ -1518,8 +1533,8 @@ class Net_SSH1
      * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,
      * the raw bytes.  This behavior is similar to PHP's md5() function.
      *
-     * @param optional Boolean $raw_output
-     * @return String
+     * @param bool $raw_output
+     * @return string
      * @access public
      */
     function getHostKeyPublicExponent($raw_output = false)
@@ -1533,8 +1548,8 @@ class Net_SSH1
      * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,
      * the raw bytes.  This behavior is similar to PHP's md5() function.
      *
-     * @param optional Boolean $raw_output
-     * @return String
+     * @param bool $raw_output
+     * @return string
      * @access public
      */
     function getHostKeyPublicModulus($raw_output = false)
@@ -1549,8 +1564,8 @@ class Net_SSH1
      * is set to true, returns, instead, an array of constants.  ie. instead of array('Triple-DES in CBC mode'), you'll
      * get array(NET_SSH1_CIPHER_3DES).
      *
-     * @param optional Boolean $raw_output
-     * @return Array
+     * @param bool $raw_output
+     * @return array
      * @access public
      */
     function getSupportedCiphers($raw_output = false)
@@ -1565,8 +1580,8 @@ class Net_SSH1
      * is set to true, returns, instead, an array of constants.  ie. instead of array('password authentication'), you'll
      * get array(NET_SSH1_AUTH_PASSWORD).
      *
-     * @param optional Boolean $raw_output
-     * @return Array
+     * @param bool $raw_output
+     * @return array
      * @access public
      */
     function getSupportedAuthentications($raw_output = false)
@@ -1577,7 +1592,7 @@ class Net_SSH1
     /**
      * Return the server identification.
      *
-     * @return String
+     * @return string
      * @access public
      */
     function getServerIdentification()
@@ -1590,7 +1605,7 @@ class Net_SSH1
      *
      * Makes sure that only the last 1MB worth of packets will be logged
      *
-     * @param String $data
+     * @param string $data
      * @access private
      */
     function _append_log($protocol_flags, $message)
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
index d613456228bdcd3d92c7c7af6fabe45d21d937d2..8281e73a021174be608a208e83a3e808dd0899cd 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
@@ -69,7 +69,7 @@
 /**#@+
  * Execution Bitmap Masks
  *
- * @see Net_SSH2::bitmap
+ * @see self::bitmap
  * @access private
  */
 define('NET_SSH2_MASK_CONSTRUCTOR',   0x00000001);
@@ -92,18 +92,19 @@ define('NET_SSH2_MASK_WINDOW_ADJUST', 0x00000020);
  *     open request, and 'sender channel' is the channel number allocated by
  *     the other side.
  *
- * @see Net_SSH2::_send_channel_packet()
- * @see Net_SSH2::_get_channel_packet()
+ * @see self::_send_channel_packet()
+ * @see self::_get_channel_packet()
  * @access private
  */
 define('NET_SSH2_CHANNEL_EXEC',      0); // PuTTy uses 0x100
 define('NET_SSH2_CHANNEL_SHELL',     1);
 define('NET_SSH2_CHANNEL_SUBSYSTEM', 2);
+define('NET_SSH2_CHANNEL_AGENT_FORWARD', 3);
 /**#@-*/
 
 /**#@+
  * @access public
- * @see Net_SSH2::getLog()
+ * @see self::getLog()
  */
 /**
  * Returns the message numbers
@@ -125,7 +126,7 @@ define('NET_SSH2_LOG_REALTIME_FILE', 4);
 
 /**#@+
  * @access public
- * @see Net_SSH2::read()
+ * @see self::read()
  */
 /**
  * Returns when a string matching $expect exactly is found
@@ -153,7 +154,7 @@ class Net_SSH2
     /**
      * The SSH identifier
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $identifier;
@@ -161,7 +162,7 @@ class Net_SSH2
     /**
      * The Socket Object
      *
-     * @var Object
+     * @var object
      * @access private
      */
     var $fsock;
@@ -172,7 +173,7 @@ class Net_SSH2
      * The bits that are set represent functions that have been called already.  This is used to determine
      * if a requisite function has been successfully executed.  If not, an error should be thrown.
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $bitmap = 0;
@@ -180,9 +181,9 @@ class Net_SSH2
     /**
      * Error information
      *
-     * @see Net_SSH2::getErrors()
-     * @see Net_SSH2::getLastError()
-     * @var String
+     * @see self::getErrors()
+     * @see self::getLastError()
+     * @var string
      * @access private
      */
     var $errors = array();
@@ -190,8 +191,8 @@ class Net_SSH2
     /**
      * Server Identifier
      *
-     * @see Net_SSH2::getServerIdentification()
-     * @var mixed false or Array
+     * @see self::getServerIdentification()
+     * @var array|false
      * @access private
      */
     var $server_identifier = false;
@@ -199,17 +200,44 @@ class Net_SSH2
     /**
      * Key Exchange Algorithms
      *
-     * @see Net_SSH2::getKexAlgorithims()
-     * @var mixed false or Array
+     * @see self::getKexAlgorithims()
+     * @var array|false
      * @access private
      */
     var $kex_algorithms = false;
 
+    /**
+     * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
+     *
+     * @see self::_key_exchange()
+     * @var int
+     * @access private
+     */
+    var $kex_dh_group_size_min = 1536;
+
+    /**
+     * Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
+     *
+     * @see self::_key_exchange()
+     * @var int
+     * @access private
+     */
+    var $kex_dh_group_size_preferred = 2048;
+
+    /**
+     * Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
+     *
+     * @see self::_key_exchange()
+     * @var int
+     * @access private
+     */
+    var $kex_dh_group_size_max = 4096;
+
     /**
      * Server Host Key Algorithms
      *
-     * @see Net_SSH2::getServerHostKeyAlgorithms()
-     * @var mixed false or Array
+     * @see self::getServerHostKeyAlgorithms()
+     * @var array|false
      * @access private
      */
     var $server_host_key_algorithms = false;
@@ -217,8 +245,8 @@ class Net_SSH2
     /**
      * Encryption Algorithms: Client to Server
      *
-     * @see Net_SSH2::getEncryptionAlgorithmsClient2Server()
-     * @var mixed false or Array
+     * @see self::getEncryptionAlgorithmsClient2Server()
+     * @var array|false
      * @access private
      */
     var $encryption_algorithms_client_to_server = false;
@@ -226,8 +254,8 @@ class Net_SSH2
     /**
      * Encryption Algorithms: Server to Client
      *
-     * @see Net_SSH2::getEncryptionAlgorithmsServer2Client()
-     * @var mixed false or Array
+     * @see self::getEncryptionAlgorithmsServer2Client()
+     * @var array|false
      * @access private
      */
     var $encryption_algorithms_server_to_client = false;
@@ -235,8 +263,8 @@ class Net_SSH2
     /**
      * MAC Algorithms: Client to Server
      *
-     * @see Net_SSH2::getMACAlgorithmsClient2Server()
-     * @var mixed false or Array
+     * @see self::getMACAlgorithmsClient2Server()
+     * @var array|false
      * @access private
      */
     var $mac_algorithms_client_to_server = false;
@@ -244,8 +272,8 @@ class Net_SSH2
     /**
      * MAC Algorithms: Server to Client
      *
-     * @see Net_SSH2::getMACAlgorithmsServer2Client()
-     * @var mixed false or Array
+     * @see self::getMACAlgorithmsServer2Client()
+     * @var array|false
      * @access private
      */
     var $mac_algorithms_server_to_client = false;
@@ -253,8 +281,8 @@ class Net_SSH2
     /**
      * Compression Algorithms: Client to Server
      *
-     * @see Net_SSH2::getCompressionAlgorithmsClient2Server()
-     * @var mixed false or Array
+     * @see self::getCompressionAlgorithmsClient2Server()
+     * @var array|false
      * @access private
      */
     var $compression_algorithms_client_to_server = false;
@@ -262,8 +290,8 @@ class Net_SSH2
     /**
      * Compression Algorithms: Server to Client
      *
-     * @see Net_SSH2::getCompressionAlgorithmsServer2Client()
-     * @var mixed false or Array
+     * @see self::getCompressionAlgorithmsServer2Client()
+     * @var array|false
      * @access private
      */
     var $compression_algorithms_server_to_client = false;
@@ -271,8 +299,8 @@ class Net_SSH2
     /**
      * Languages: Server to Client
      *
-     * @see Net_SSH2::getLanguagesServer2Client()
-     * @var mixed false or Array
+     * @see self::getLanguagesServer2Client()
+     * @var array|false
      * @access private
      */
     var $languages_server_to_client = false;
@@ -280,8 +308,8 @@ class Net_SSH2
     /**
      * Languages: Client to Server
      *
-     * @see Net_SSH2::getLanguagesClient2Server()
-     * @var mixed false or Array
+     * @see self::getLanguagesClient2Server()
+     * @var array|false
      * @access private
      */
     var $languages_client_to_server = false;
@@ -296,9 +324,9 @@ class Net_SSH2
      *
      *  -- http://tools.ietf.org/html/rfc4253#section-6
      *
-     * @see Net_SSH2::Net_SSH2()
-     * @see Net_SSH2::_send_binary_packet()
-     * @var Integer
+     * @see self::Net_SSH2()
+     * @see self::_send_binary_packet()
+     * @var int
      * @access private
      */
     var $encrypt_block_size = 8;
@@ -306,9 +334,9 @@ class Net_SSH2
     /**
      * Block Size for Client to Server Encryption
      *
-     * @see Net_SSH2::Net_SSH2()
-     * @see Net_SSH2::_get_binary_packet()
-     * @var Integer
+     * @see self::Net_SSH2()
+     * @see self::_get_binary_packet()
+     * @var int
      * @access private
      */
     var $decrypt_block_size = 8;
@@ -316,8 +344,8 @@ class Net_SSH2
     /**
      * Server to Client Encryption Object
      *
-     * @see Net_SSH2::_get_binary_packet()
-     * @var Object
+     * @see self::_get_binary_packet()
+     * @var object
      * @access private
      */
     var $decrypt = false;
@@ -325,8 +353,8 @@ class Net_SSH2
     /**
      * Client to Server Encryption Object
      *
-     * @see Net_SSH2::_send_binary_packet()
-     * @var Object
+     * @see self::_send_binary_packet()
+     * @var object
      * @access private
      */
     var $encrypt = false;
@@ -334,8 +362,8 @@ class Net_SSH2
     /**
      * Client to Server HMAC Object
      *
-     * @see Net_SSH2::_send_binary_packet()
-     * @var Object
+     * @see self::_send_binary_packet()
+     * @var object
      * @access private
      */
     var $hmac_create = false;
@@ -343,8 +371,8 @@ class Net_SSH2
     /**
      * Server to Client HMAC Object
      *
-     * @see Net_SSH2::_get_binary_packet()
-     * @var Object
+     * @see self::_get_binary_packet()
+     * @var object
      * @access private
      */
     var $hmac_check = false;
@@ -356,8 +384,8 @@ class Net_SSH2
      * For the client to server side, the HMAC object will make the HMAC as long as it needs to be.  All we need to do is
      * append it.
      *
-     * @see Net_SSH2::_get_binary_packet()
-     * @var Integer
+     * @see self::_get_binary_packet()
+     * @var int
      * @access private
      */
     var $hmac_size = false;
@@ -365,14 +393,14 @@ class Net_SSH2
     /**
      * Server Public Host Key
      *
-     * @see Net_SSH2::getServerPublicHostKey()
-     * @var String
+     * @see self::getServerPublicHostKey()
+     * @var string
      * @access private
      */
     var $server_public_host_key;
 
     /**
-     * Session identifer
+     * Session identifier
      *
      * "The exchange hash H from the first key exchange is additionally
      *  used as the session identifier, which is a unique identifier for
@@ -380,8 +408,8 @@ class Net_SSH2
      *
      *  -- http://tools.ietf.org/html/rfc4253#section-7.2
      *
-     * @see Net_SSH2::_key_exchange()
-     * @var String
+     * @see self::_key_exchange()
+     * @var string
      * @access private
      */
     var $session_id = false;
@@ -391,8 +419,8 @@ class Net_SSH2
      *
      * The current exchange hash
      *
-     * @see Net_SSH2::_key_exchange()
-     * @var String
+     * @see self::_key_exchange()
+     * @var string
      * @access private
      */
     var $exchange_hash = false;
@@ -400,8 +428,8 @@ class Net_SSH2
     /**
      * Message Numbers
      *
-     * @see Net_SSH2::Net_SSH2()
-     * @var Array
+     * @see self::Net_SSH2()
+     * @var array
      * @access private
      */
     var $message_numbers = array();
@@ -409,8 +437,8 @@ class Net_SSH2
     /**
      * Disconnection Message 'reason codes' defined in RFC4253
      *
-     * @see Net_SSH2::Net_SSH2()
-     * @var Array
+     * @see self::Net_SSH2()
+     * @var array
      * @access private
      */
     var $disconnect_reasons = array();
@@ -418,8 +446,8 @@ class Net_SSH2
     /**
      * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254
      *
-     * @see Net_SSH2::Net_SSH2()
-     * @var Array
+     * @see self::Net_SSH2()
+     * @var array
      * @access private
      */
     var $channel_open_failure_reasons = array();
@@ -428,8 +456,8 @@ class Net_SSH2
      * Terminal Modes
      *
      * @link http://tools.ietf.org/html/rfc4254#section-8
-     * @see Net_SSH2::Net_SSH2()
-     * @var Array
+     * @see self::Net_SSH2()
+     * @var array
      * @access private
      */
     var $terminal_modes = array();
@@ -438,8 +466,8 @@ class Net_SSH2
      * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes
      *
      * @link http://tools.ietf.org/html/rfc4254#section-5.2
-     * @see Net_SSH2::Net_SSH2()
-     * @var Array
+     * @see self::Net_SSH2()
+     * @var array
      * @access private
      */
     var $channel_extended_data_type_codes = array();
@@ -449,8 +477,8 @@ class Net_SSH2
      *
      * See 'Section 6.4.  Data Integrity' of rfc4253 for more info.
      *
-     * @see Net_SSH2::_send_binary_packet()
-     * @var Integer
+     * @see self::_send_binary_packet()
+     * @var int
      * @access private
      */
     var $send_seq_no = 0;
@@ -460,8 +488,8 @@ class Net_SSH2
      *
      * See 'Section 6.4.  Data Integrity' of rfc4253 for more info.
      *
-     * @see Net_SSH2::_get_binary_packet()
-     * @var Integer
+     * @see self::_get_binary_packet()
+     * @var int
      * @access private
      */
     var $get_seq_no = 0;
@@ -471,9 +499,9 @@ class Net_SSH2
      *
      * Maps client channels to server channels
      *
-     * @see Net_SSH2::_get_channel_packet()
-     * @see Net_SSH2::exec()
-     * @var Array
+     * @see self::_get_channel_packet()
+     * @see self::exec()
+     * @var array
      * @access private
      */
     var $server_channels = array();
@@ -484,9 +512,9 @@ class Net_SSH2
      * If a client requests a packet from one channel but receives two packets from another those packets should
      * be placed in a buffer
      *
-     * @see Net_SSH2::_get_channel_packet()
-     * @see Net_SSH2::exec()
-     * @var Array
+     * @see self::_get_channel_packet()
+     * @see self::exec()
+     * @var array
      * @access private
      */
     var $channel_buffers = array();
@@ -496,8 +524,8 @@ class Net_SSH2
      *
      * Contains the type of the last sent message
      *
-     * @see Net_SSH2::_get_channel_packet()
-     * @var Array
+     * @see self::_get_channel_packet()
+     * @var array
      * @access private
      */
     var $channel_status = array();
@@ -507,8 +535,8 @@ class Net_SSH2
      *
      * Maximum packet size indexed by channel
      *
-     * @see Net_SSH2::_send_channel_packet()
-     * @var Array
+     * @see self::_send_channel_packet()
+     * @var array
      * @access private
      */
     var $packet_size_client_to_server = array();
@@ -516,8 +544,8 @@ class Net_SSH2
     /**
      * Message Number Log
      *
-     * @see Net_SSH2::getLog()
-     * @var Array
+     * @see self::getLog()
+     * @var array
      * @access private
      */
     var $message_number_log = array();
@@ -525,8 +553,8 @@ class Net_SSH2
     /**
      * Message Log
      *
-     * @see Net_SSH2::getLog()
-     * @var Array
+     * @see self::getLog()
+     * @var array
      * @access private
      */
     var $message_log = array();
@@ -536,9 +564,9 @@ class Net_SSH2
      *
      * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 2GB)
      *
-     * @var Integer
-     * @see Net_SSH2::_send_channel_packet()
-     * @see Net_SSH2::exec()
+     * @var int
+     * @see self::_send_channel_packet()
+     * @see self::exec()
      * @access private
      */
     var $window_size = 0x7FFFFFFF;
@@ -548,8 +576,8 @@ class Net_SSH2
      *
      * Window size indexed by channel
      *
-     * @see Net_SSH2::_send_channel_packet()
-     * @var Array
+     * @see self::_send_channel_packet()
+     * @var array
      * @access private
      */
     var $window_size_server_to_client = array();
@@ -559,8 +587,8 @@ class Net_SSH2
      *
      * Window size indexed by channel
      *
-     * @see Net_SSH2::_get_channel_packet()
-     * @var Array
+     * @see self::_get_channel_packet()
+     * @var array
      * @access private
      */
     var $window_size_client_to_server = array();
@@ -570,8 +598,8 @@ class Net_SSH2
      *
      * Verified against $this->session_id
      *
-     * @see Net_SSH2::getServerPublicHostKey()
-     * @var String
+     * @see self::getServerPublicHostKey()
+     * @var string
      * @access private
      */
     var $signature = '';
@@ -581,8 +609,8 @@ class Net_SSH2
      *
      * ssh-rsa or ssh-dss.
      *
-     * @see Net_SSH2::getServerPublicHostKey()
-     * @var String
+     * @see self::getServerPublicHostKey()
+     * @var string
      * @access private
      */
     var $signature_format = '';
@@ -590,8 +618,8 @@ class Net_SSH2
     /**
      * Interactive Buffer
      *
-     * @see Net_SSH2::read()
-     * @var Array
+     * @see self::read()
+     * @var array
      * @access private
      */
     var $interactiveBuffer = '';
@@ -601,9 +629,9 @@ class Net_SSH2
      *
      * Should never exceed NET_SSH2_LOG_MAX_SIZE
      *
-     * @see Net_SSH2::_send_binary_packet()
-     * @see Net_SSH2::_get_binary_packet()
-     * @var Integer
+     * @see self::_send_binary_packet()
+     * @see self::_get_binary_packet()
+     * @var int
      * @access private
      */
     var $log_size;
@@ -611,7 +639,7 @@ class Net_SSH2
     /**
      * Timeout
      *
-     * @see Net_SSH2::setTimeout()
+     * @see self::setTimeout()
      * @access private
      */
     var $timeout;
@@ -619,7 +647,7 @@ class Net_SSH2
     /**
      * Current Timeout
      *
-     * @see Net_SSH2::_get_channel_packet()
+     * @see self::_get_channel_packet()
      * @access private
      */
     var $curTimeout;
@@ -627,8 +655,8 @@ class Net_SSH2
     /**
      * Real-time log file pointer
      *
-     * @see Net_SSH2::_append_log()
-     * @var Resource
+     * @see self::_append_log()
+     * @var resource
      * @access private
      */
     var $realtime_log_file;
@@ -636,8 +664,8 @@ class Net_SSH2
     /**
      * Real-time log file size
      *
-     * @see Net_SSH2::_append_log()
-     * @var Integer
+     * @see self::_append_log()
+     * @var int
      * @access private
      */
     var $realtime_log_size;
@@ -645,8 +673,8 @@ class Net_SSH2
     /**
      * Has the signature been validated?
      *
-     * @see Net_SSH2::getServerPublicHostKey()
-     * @var Boolean
+     * @see self::getServerPublicHostKey()
+     * @var bool
      * @access private
      */
     var $signature_validated = false;
@@ -654,7 +682,7 @@ class Net_SSH2
     /**
      * Real-time log file wrap boolean
      *
-     * @see Net_SSH2::_append_log()
+     * @see self::_append_log()
      * @access private
      */
     var $realtime_log_wrap;
@@ -662,7 +690,7 @@ class Net_SSH2
     /**
      * Flag to suppress stderr from output
      *
-     * @see Net_SSH2::enableQuietMode()
+     * @see self::enableQuietMode()
      * @access private
      */
     var $quiet_mode = false;
@@ -670,7 +698,7 @@ class Net_SSH2
     /**
      * Time of first network activity
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $last_packet;
@@ -678,7 +706,7 @@ class Net_SSH2
     /**
      * Exit status returned from ssh if any
      *
-     * @var Integer
+     * @var int
      * @access private
      */
     var $exit_status;
@@ -686,8 +714,8 @@ class Net_SSH2
     /**
      * Flag to request a PTY when using exec()
      *
-     * @var Boolean
-     * @see Net_SSH2::enablePTY()
+     * @var bool
+     * @see self::enablePTY()
      * @access private
      */
     var $request_pty = false;
@@ -695,7 +723,7 @@ class Net_SSH2
     /**
      * Flag set while exec() is running when using enablePTY()
      *
-     * @var Boolean
+     * @var bool
      * @access private
      */
     var $in_request_pty_exec = false;
@@ -703,7 +731,7 @@ class Net_SSH2
     /**
      * Flag set after startSubsystem() is called
      *
-     * @var Boolean
+     * @var bool
      * @access private
      */
     var $in_subsystem;
@@ -711,7 +739,7 @@ class Net_SSH2
     /**
      * Contents of stdError
      *
-     * @var String
+     * @var string
      * @access private
      */
     var $stdErrorLog;
@@ -719,8 +747,8 @@ class Net_SSH2
     /**
      * The Last Interactive Response
      *
-     * @see Net_SSH2::_keyboard_interactive_process()
-     * @var String
+     * @see self::_keyboard_interactive_process()
+     * @var string
      * @access private
      */
     var $last_interactive_response = '';
@@ -728,8 +756,8 @@ class Net_SSH2
     /**
      * Keyboard Interactive Request / Responses
      *
-     * @see Net_SSH2::_keyboard_interactive_process()
-     * @var Array
+     * @see self::_keyboard_interactive_process()
+     * @var array
      * @access private
      */
     var $keyboard_requests_responses = array();
@@ -740,9 +768,9 @@ class Net_SSH2
      * Quoting from the RFC, "in some jurisdictions, sending a warning message before
      * authentication may be relevant for getting legal protection."
      *
-     * @see Net_SSH2::_filter()
-     * @see Net_SSH2::getBannerMessage()
-     * @var String
+     * @see self::_filter()
+     * @see self::getBannerMessage()
+     * @var string
      * @access private
      */
     var $banner_message = '';
@@ -750,8 +778,8 @@ class Net_SSH2
     /**
      * Did read() timeout or return normally?
      *
-     * @see Net_SSH2::isTimeout()
-     * @var Boolean
+     * @see self::isTimeout()
+     * @var bool
      * @access private
      */
     var $is_timeout = false;
@@ -759,8 +787,8 @@ class Net_SSH2
     /**
      * Log Boundary
      *
-     * @see Net_SSH2::_format_log()
-     * @var String
+     * @see self::_format_log()
+     * @var string
      * @access private
      */
     var $log_boundary = ':';
@@ -768,8 +796,8 @@ class Net_SSH2
     /**
      * Log Long Width
      *
-     * @see Net_SSH2::_format_log()
-     * @var Integer
+     * @see self::_format_log()
+     * @var int
      * @access private
      */
     var $log_long_width = 65;
@@ -777,8 +805,8 @@ class Net_SSH2
     /**
      * Log Short Width
      *
-     * @see Net_SSH2::_format_log()
-     * @var Integer
+     * @see self::_format_log()
+     * @var int
      * @access private
      */
     var $log_short_width = 16;
@@ -786,9 +814,9 @@ class Net_SSH2
     /**
      * Hostname
      *
-     * @see Net_SSH2::Net_SSH2()
-     * @see Net_SSH2::_connect()
-     * @var String
+     * @see self::Net_SSH2()
+     * @see self::_connect()
+     * @var string
      * @access private
      */
     var $host;
@@ -796,61 +824,66 @@ class Net_SSH2
     /**
      * Port Number
      *
-     * @see Net_SSH2::Net_SSH2()
-     * @see Net_SSH2::_connect()
-     * @var Integer
+     * @see self::Net_SSH2()
+     * @see self::_connect()
+     * @var int
      * @access private
      */
     var $port;
 
     /**
-     * Timeout for initial connection
-     *
-     * Set by the constructor call. Calling setTimeout() is optional. If it's not called functions like
-     * exec() won't timeout unless some PHP setting forces it too. The timeout specified in the constructor,
-     * however, is non-optional. There will be a timeout, whether or not you set it. If you don't it'll be
-     * 10 seconds. It is used by fsockopen() and the initial stream_select in that function.
+     * Number of columns for terminal window size
      *
-     * @see Net_SSH2::Net_SSH2()
-     * @see Net_SSH2::_connect()
-     * @var Integer
+     * @see self::getWindowColumns()
+     * @see self::setWindowColumns()
+     * @see self::setWindowSize()
+     * @var int
      * @access private
      */
-    var $connectionTimeout;
+    var $windowColumns = 80;
 
     /**
      * Number of columns for terminal window size
      *
-     * @see Net_SSH2::getWindowColumns()
-     * @see Net_SSH2::setWindowColumns()
-     * @see Net_SSH2::setWindowSize()
-     * @var Integer
+     * @see self::getWindowRows()
+     * @see self::setWindowRows()
+     * @see self::setWindowSize()
+     * @var int
      * @access private
      */
-    var $windowColumns = 80;
+    var $windowRows = 24;
 
     /**
-     * Number of columns for terminal window size
+     * Crypto Engine
      *
-     * @see Net_SSH2::getWindowRows()
-     * @see Net_SSH2::setWindowRows()
-     * @see Net_SSH2::setWindowSize()
-     * @var Integer
+     * @see self::setCryptoEngine()
+     * @see self::_key_exchange()
+     * @var int
      * @access private
      */
-    var $windowRows = 24;
+    var $crypto_engine = false;
+
+    /**
+     * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario
+     *
+     * @var System_SSH_Agent
+     * @access private
+     */
+    var $agent;
 
     /**
      * Default Constructor.
      *
-     * @param String $host
-     * @param optional Integer $port
-     * @param optional Integer $timeout
-     * @see Net_SSH2::login()
+     * $host can either be a string, representing the host, or a stream resource.
+     *
+     * @param mixed $host
+     * @param int $port
+     * @param int $timeout
+     * @see self::login()
      * @return Net_SSH2
      * @access public
      */
-    function Net_SSH2($host, $port = 22, $timeout = 10)
+    function __construct($host, $port = 22, $timeout = 10)
     {
         // Include Math_BigInteger
         // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification.
@@ -866,6 +899,11 @@ class Net_SSH2
             include_once 'Crypt/Hash.php';
         }
 
+        // include Crypt_Base so constants can be defined for setCryptoEngine()
+        if (!class_exists('Crypt_Base')) {
+            include_once 'Crypt/Base.php';
+        }
+
         $this->message_numbers = array(
             1 => 'NET_SSH2_MSG_DISCONNECT',
             2 => 'NET_SSH2_MSG_IGNORE',
@@ -933,18 +971,59 @@ class Net_SSH2
             array(60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'),
             array(60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'),
             array(60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
-                  61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE')
+                  61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'),
+            // RFC 4419 - diffie-hellman-group-exchange-sha{1,256}
+            array(30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD',
+                  31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP',
+                  32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT',
+                  33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY',
+                  34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST')
         );
 
-        $this->host = $host;
-        $this->port = $port;
-        $this->connectionTimeout = $timeout;
+        if (is_resource($host)) {
+            $this->fsock = $host;
+            return;
+        }
+
+        if (is_string($host)) {
+            $this->host = $host;
+            $this->port = $port;
+            $this->timeout = $timeout;
+        }
+    }
+
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @param mixed $host
+     * @param int $port
+     * @param int $timeout
+     * @access public
+     */
+    function Net_SSH2($host, $port = 22, $timeout = 10)
+    {
+        $this->__construct($host, $port, $timeout);
+    }
+
+    /**
+     * Set Crypto Engine Mode
+     *
+     * Possible $engine values:
+     * CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT
+     *
+     * @param int $engine
+     * @access private
+     */
+    function setCryptoEngine($engine)
+    {
+        $this->crypto_engine = $engine;
     }
 
     /**
      * Connect to an SSHv2 server
      *
-     * @return Boolean
+     * @return bool
      * @access private
      */
     function _connect()
@@ -955,37 +1034,26 @@ class Net_SSH2
 
         $this->bitmap |= NET_SSH2_MASK_CONSTRUCTOR;
 
-        $timeout = $this->connectionTimeout;
-        $host = $this->host . ':' . $this->port;
+        $this->curTimeout = $this->timeout;
 
         $this->last_packet = strtok(microtime(), ' ') + strtok(''); // == microtime(true) in PHP5
 
-        $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
-        $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $timeout);
-        if (!$this->fsock) {
-            user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"));
-            return false;
-        }
-        $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
-
-        $timeout-= $elapsed;
-
-        if ($timeout <= 0) {
-            user_error("Cannot connect to $host. Timeout error");
-            return false;
-        }
-
-        $read = array($this->fsock);
-        $write = $except = null;
+        if (!is_resource($this->fsock)) {
+            $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+            $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout);
+            if (!$this->fsock) {
+                $host = $this->host . ':' . $this->port;
+                user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"));
+                return false;
+            }
+            $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
 
-        $sec = floor($timeout);
-        $usec = 1000000 * ($timeout - $sec);
+            $this->curTimeout-= $elapsed;
 
-        // on windows this returns a "Warning: Invalid CRT parameters detected" error
-        // the !count() is done as a workaround for <https://bugs.php.net/42682>
-        if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
-            user_error("Cannot connect to $host. Banner timeout");
-            return false;
+            if ($this->curTimeout <= 0) {
+                $this->is_timeout = true;
+                return false;
+            }
         }
 
         /* According to the SSH2 specs,
@@ -1002,6 +1070,27 @@ class Net_SSH2
                 $extra.= $temp;
                 $temp = '';
             }
+
+            if ($this->curTimeout) {
+                if ($this->curTimeout < 0) {
+                    $this->is_timeout = true;
+                    return false;
+                }
+                $read = array($this->fsock);
+                $write = $except = null;
+                $start = strtok(microtime(), ' ') + strtok('');
+                $sec = floor($this->curTimeout);
+                $usec = 1000000 * ($this->curTimeout - $sec);
+                // on windows this returns a "Warning: Invalid CRT parameters detected" error
+                // the !count() is done as a workaround for <https://bugs.php.net/42682>
+                if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
+                    $this->is_timeout = true;
+                    return false;
+                }
+                $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
+                $this->curTimeout-= $elapsed;
+            }
+
             $temp.= fgets($this->fsock, 255);
         }
 
@@ -1055,14 +1144,16 @@ class Net_SSH2
      * You should overwrite this method in your own class if you want to use another identifier
      *
      * @access protected
-     * @return String
+     * @return string
      */
     function _generate_identifier()
     {
-        $identifier = 'SSH-2.0-phpseclib_0.3';
+        $identifier = 'SSH-2.0-phpseclib_1.0';
 
         $ext = array();
-        if (extension_loaded('mcrypt')) {
+        if (extension_loaded('openssl')) {
+            $ext[] = 'openssl';
+        } elseif (extension_loaded('mcrypt')) {
             $ext[] = 'mcrypt';
         }
 
@@ -1082,14 +1173,16 @@ class Net_SSH2
     /**
      * Key Exchange
      *
-     * @param String $kexinit_payload_server
+     * @param string $kexinit_payload_server
      * @access private
      */
     function _key_exchange($kexinit_payload_server)
     {
         static $kex_algorithms = array(
             'diffie-hellman-group1-sha1', // REQUIRED
-            'diffie-hellman-group14-sha1' // REQUIRED
+            'diffie-hellman-group14-sha1', // REQUIRED
+            'diffie-hellman-group-exchange-sha1', // RFC 4419
+            'diffie-hellman-group-exchange-sha256', // RFC 4419
         );
 
         static $server_host_key_algorithms = array(
@@ -1104,7 +1197,7 @@ class Net_SSH2
                 'arcfour256',
                 'arcfour128',
 
-                //'arcfour',        // OPTIONAL          the ARCFOUR stream cipher with a 128-bit key
+                //'arcfour',      // OPTIONAL          the ARCFOUR stream cipher with a 128-bit key
 
                 // CTR modes from <http://tools.ietf.org/html/rfc4344#section-4>:
                 'aes128-ctr',     // RECOMMENDED       AES (Rijndael) in SDCTR mode, with 128-bit key
@@ -1132,9 +1225,18 @@ class Net_SSH2
                 '3des-ctr',       // RECOMMENDED       Three-key 3DES in SDCTR mode
 
                 '3des-cbc',       // REQUIRED          three-key 3DES in CBC mode
-                //'none'            // OPTIONAL          no encryption; NOT RECOMMENDED
+                 //'none'         // OPTIONAL          no encryption; NOT RECOMMENDED
             );
 
+            if (extension_loaded('openssl') && !extension_loaded('mcrypt')) {
+                // OpenSSL does not support arcfour256 in any capacity and arcfour128 / arcfour support is limited to
+                // instances that do not use continuous buffers
+                $encryption_algorithms = array_diff(
+                    $encryption_algorithms,
+                    array('arcfour256', 'arcfour128', 'arcfour')
+                );
+            }
+
             if (phpseclib_resolve_include_path('Crypt/RC4.php') === false) {
                 $encryption_algorithms = array_diff(
                     $encryption_algorithms,
@@ -1245,14 +1347,32 @@ class Net_SSH2
         $first_kex_packet_follows = $first_kex_packet_follows != 0;
 
         // the sending of SSH2_MSG_KEXINIT could go in one of two places.  this is the second place.
-        $kexinit_payload_client = pack('Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
-            NET_SSH2_MSG_KEXINIT, $client_cookie, strlen($str_kex_algorithms), $str_kex_algorithms,
-            strlen($str_server_host_key_algorithms), $str_server_host_key_algorithms, strlen($encryption_algorithms_client_to_server),
-            $encryption_algorithms_client_to_server, strlen($encryption_algorithms_server_to_client), $encryption_algorithms_server_to_client,
-            strlen($mac_algorithms_client_to_server), $mac_algorithms_client_to_server, strlen($mac_algorithms_server_to_client),
-            $mac_algorithms_server_to_client, strlen($compression_algorithms_client_to_server), $compression_algorithms_client_to_server,
-            strlen($compression_algorithms_server_to_client), $compression_algorithms_server_to_client, 0, '', 0, '',
-            0, 0
+        $kexinit_payload_client = pack(
+            'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
+            NET_SSH2_MSG_KEXINIT,
+            $client_cookie,
+            strlen($str_kex_algorithms),
+            $str_kex_algorithms,
+            strlen($str_server_host_key_algorithms),
+            $str_server_host_key_algorithms,
+            strlen($encryption_algorithms_client_to_server),
+            $encryption_algorithms_client_to_server,
+            strlen($encryption_algorithms_server_to_client),
+            $encryption_algorithms_server_to_client,
+            strlen($mac_algorithms_client_to_server),
+            $mac_algorithms_client_to_server,
+            strlen($mac_algorithms_server_to_client),
+            $mac_algorithms_server_to_client,
+            strlen($compression_algorithms_client_to_server),
+            $compression_algorithms_client_to_server,
+            strlen($compression_algorithms_server_to_client),
+            $compression_algorithms_server_to_client,
+            0,
+            '',
+            0,
+            '',
+            0,
+            0
         );
 
         if (!$this->_send_binary_packet($kexinit_payload_client)) {
@@ -1261,134 +1381,115 @@ class Net_SSH2
         // here ends the second place.
 
         // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
-        for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_server_to_client); $i++);
-        if ($i == count($encryption_algorithms)) {
-            user_error('No compatible server to client encryption algorithms found');
-            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
-        }
-
         // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
         // diffie-hellman key exchange as fast as possible
-        $decrypt = $encryption_algorithms[$i];
-        switch ($decrypt) {
-            case '3des-cbc':
-            case '3des-ctr':
-                $decryptKeyLength = 24; // eg. 192 / 8
-                break;
-            case 'aes256-cbc':
-            case 'aes256-ctr':
-            case 'twofish-cbc':
-            case 'twofish256-cbc':
-            case 'twofish256-ctr':
-                $decryptKeyLength = 32; // eg. 256 / 8
-                break;
-            case 'aes192-cbc':
-            case 'aes192-ctr':
-            case 'twofish192-cbc':
-            case 'twofish192-ctr':
-                $decryptKeyLength = 24; // eg. 192 / 8
-                break;
-            case 'aes128-cbc':
-            case 'aes128-ctr':
-            case 'twofish128-cbc':
-            case 'twofish128-ctr':
-            case 'blowfish-cbc':
-            case 'blowfish-ctr':
-                $decryptKeyLength = 16; // eg. 128 / 8
-                break;
-            case 'arcfour':
-            case 'arcfour128':
-                $decryptKeyLength = 16; // eg. 128 / 8
-                break;
-            case 'arcfour256':
-                $decryptKeyLength = 32; // eg. 128 / 8
-                break;
-            case 'none';
-                $decryptKeyLength = 0;
+        $decrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_server_to_client);
+        $decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt);
+        if ($decryptKeyLength === null) {
+            user_error('No compatible server to client encryption algorithms found');
+            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
         }
 
-        for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_client_to_server); $i++);
-        if ($i == count($encryption_algorithms)) {
+        $encrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_client_to_server);
+        $encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt);
+        if ($encryptKeyLength === null) {
             user_error('No compatible client to server encryption algorithms found');
             return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
         }
 
-        $encrypt = $encryption_algorithms[$i];
-        switch ($encrypt) {
-            case '3des-cbc':
-            case '3des-ctr':
-                $encryptKeyLength = 24;
-                break;
-            case 'aes256-cbc':
-            case 'aes256-ctr':
-            case 'twofish-cbc':
-            case 'twofish256-cbc':
-            case 'twofish256-ctr':
-                $encryptKeyLength = 32;
-                break;
-            case 'aes192-cbc':
-            case 'aes192-ctr':
-            case 'twofish192-cbc':
-            case 'twofish192-ctr':
-                $encryptKeyLength = 24;
-                break;
-            case 'aes128-cbc':
-            case 'aes128-ctr':
-            case 'twofish128-cbc':
-            case 'twofish128-ctr':
-            case 'blowfish-cbc':
-            case 'blowfish-ctr':
-                $encryptKeyLength = 16;
-                break;
-            case 'arcfour':
-            case 'arcfour128':
-                $encryptKeyLength = 16;
-                break;
-            case 'arcfour256':
-                $encryptKeyLength = 32;
-                break;
-            case 'none';
-                $encryptKeyLength = 0;
-        }
-
         $keyLength = $decryptKeyLength > $encryptKeyLength ? $decryptKeyLength : $encryptKeyLength;
 
         // through diffie-hellman key exchange a symmetric key is obtained
-        for ($i = 0; $i < count($kex_algorithms) && !in_array($kex_algorithms[$i], $this->kex_algorithms); $i++);
-        if ($i == count($kex_algorithms)) {
+        $kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms);
+        if ($kex_algorithm === false) {
             user_error('No compatible key exchange algorithms found');
             return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
         }
+        if (strpos($kex_algorithm, 'diffie-hellman-group-exchange') === 0) {
+            $dh_group_sizes_packed = pack(
+                'NNN',
+                $this->kex_dh_group_size_min,
+                $this->kex_dh_group_size_preferred,
+                $this->kex_dh_group_size_max
+            );
+            $packet = pack(
+                'Ca*',
+                NET_SSH2_MSG_KEXDH_GEX_REQUEST,
+                $dh_group_sizes_packed
+            );
+            if (!$this->_send_binary_packet($packet)) {
+                return false;
+            }
 
-        switch ($kex_algorithms[$i]) {
-            // see http://tools.ietf.org/html/rfc2409#section-6.2 and
-            // http://tools.ietf.org/html/rfc2412, appendex E
-            case 'diffie-hellman-group1-sha1':
-                $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
-                         '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
-                         '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
-                         'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF';
-                break;
-            // see http://tools.ietf.org/html/rfc3526#section-3
-            case 'diffie-hellman-group14-sha1':
-                $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
-                         '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
-                         '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
-                         'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' .
-                         '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' .
-                         '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' .
-                         'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' .
-                         '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF';
+            $response = $this->_get_binary_packet();
+            if ($response === false) {
+                user_error('Connection closed by server');
+                return false;
+            }
+            extract(unpack('Ctype', $this->_string_shift($response, 1)));
+            if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) {
+                user_error('Expected SSH_MSG_KEX_DH_GEX_GROUP');
+                return false;
+            }
+
+            extract(unpack('NprimeLength', $this->_string_shift($response, 4)));
+            $primeBytes = $this->_string_shift($response, $primeLength);
+            $prime = new Math_BigInteger($primeBytes, -256);
+
+            extract(unpack('NgLength', $this->_string_shift($response, 4)));
+            $gBytes = $this->_string_shift($response, $gLength);
+            $g = new Math_BigInteger($gBytes, -256);
+
+            $exchange_hash_rfc4419 = pack(
+                'a*Na*Na*',
+                $dh_group_sizes_packed,
+                $primeLength,
+                $primeBytes,
+                $gLength,
+                $gBytes
+            );
+
+            $clientKexInitMessage = NET_SSH2_MSG_KEXDH_GEX_INIT;
+            $serverKexReplyMessage = NET_SSH2_MSG_KEXDH_GEX_REPLY;
+        } else {
+            switch ($kex_algorithm) {
+                // see http://tools.ietf.org/html/rfc2409#section-6.2 and
+                // http://tools.ietf.org/html/rfc2412, appendex E
+                case 'diffie-hellman-group1-sha1':
+                    $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
+                            '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
+                            '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
+                            'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF';
+                    break;
+                // see http://tools.ietf.org/html/rfc3526#section-3
+                case 'diffie-hellman-group14-sha1':
+                    $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
+                            '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
+                            '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
+                            'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' .
+                            '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' .
+                            '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' .
+                            'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' .
+                            '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF';
+                    break;
+            }
+            // For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1
+            // the generator field element is 2 (decimal) and the hash function is sha1.
+            $g = new Math_BigInteger(2);
+            $prime = new Math_BigInteger($prime, 16);
+            $exchange_hash_rfc4419 = '';
+            $clientKexInitMessage = NET_SSH2_MSG_KEXDH_INIT;
+            $serverKexReplyMessage = NET_SSH2_MSG_KEXDH_REPLY;
+        }
+
+        switch ($kex_algorithm) {
+            case 'diffie-hellman-group-exchange-sha256':
+                $kexHash = new Crypt_Hash('sha256');
                 break;
+            default:
+                $kexHash = new Crypt_Hash('sha1');
         }
 
-        // For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1
-        // the generator field element is 2 (decimal) and the hash function is sha1.
-        $g = new Math_BigInteger(2);
-        $prime = new Math_BigInteger($prime, 16);
-        $kexHash = new Crypt_Hash('sha1');
-        //$q = $p->bitwise_rightShift(1);
-
         /* To increase the speed of the key exchange, both client and server may
            reduce the size of their private exponents.  It should be at least
            twice as long as the key material that is generated from the shared
@@ -1405,7 +1506,7 @@ class Net_SSH2
         $e = $g->modPow($x, $prime);
 
         $eBytes = $e->toBytes(true);
-        $data = pack('CNa*', NET_SSH2_MSG_KEXDH_INIT, strlen($eBytes), $eBytes);
+        $data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
 
         if (!$this->_send_binary_packet($data)) {
             user_error('Connection closed by server');
@@ -1419,7 +1520,7 @@ class Net_SSH2
         }
         extract(unpack('Ctype', $this->_string_shift($response, 1)));
 
-        if ($type != NET_SSH2_MSG_KEXDH_REPLY) {
+        if ($type != $serverKexReplyMessage) {
             user_error('Expected SSH_MSG_KEXDH_REPLY');
             return false;
         }
@@ -1443,11 +1544,25 @@ class Net_SSH2
         $key = $f->modPow($x, $prime);
         $keyBytes = $key->toBytes(true);
 
-        $this->exchange_hash = pack('Na*Na*Na*Na*Na*Na*Na*Na*',
-            strlen($this->identifier), $this->identifier, strlen($this->server_identifier), $this->server_identifier,
-            strlen($kexinit_payload_client), $kexinit_payload_client, strlen($kexinit_payload_server),
-            $kexinit_payload_server, strlen($this->server_public_host_key), $this->server_public_host_key, strlen($eBytes),
-            $eBytes, strlen($fBytes), $fBytes, strlen($keyBytes), $keyBytes
+        $this->exchange_hash = pack(
+            'Na*Na*Na*Na*Na*a*Na*Na*Na*',
+            strlen($this->identifier),
+            $this->identifier,
+            strlen($this->server_identifier),
+            $this->server_identifier,
+            strlen($kexinit_payload_client),
+            $kexinit_payload_client,
+            strlen($kexinit_payload_server),
+            $kexinit_payload_server,
+            strlen($this->server_public_host_key),
+            $this->server_public_host_key,
+            $exchange_hash_rfc4419,
+            strlen($eBytes),
+            $eBytes,
+            strlen($fBytes),
+            $fBytes,
+            strlen($keyBytes),
+            $keyBytes
         );
 
         $this->exchange_hash = $kexHash->hash($this->exchange_hash);
@@ -1456,18 +1571,19 @@ class Net_SSH2
             $this->session_id = $this->exchange_hash;
         }
 
-        for ($i = 0; $i < count($server_host_key_algorithms) && !in_array($server_host_key_algorithms[$i], $this->server_host_key_algorithms); $i++);
-        if ($i == count($server_host_key_algorithms)) {
+        $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms);
+        if ($server_host_key_algorithm === false) {
             user_error('No compatible server host key algorithms found');
             return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
         }
 
-        if ($public_key_format != $server_host_key_algorithms[$i] || $this->signature_format != $server_host_key_algorithms[$i]) {
+        if ($public_key_format != $server_host_key_algorithm || $this->signature_format != $server_host_key_algorithm) {
             user_error('Server Host Key Algorithm Mismatch');
             return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
         }
 
-        $packet = pack('C',
+        $packet = pack(
+            'C',
             NET_SSH2_MSG_NEWKEYS
         );
 
@@ -1563,7 +1679,7 @@ class Net_SSH2
                 }
                 $this->encrypt = new Crypt_RC4();
                 break;
-            case 'none';
+            case 'none':
                 //$this->encrypt = new Crypt_Null();
         }
 
@@ -1639,13 +1755,16 @@ class Net_SSH2
                 }
                 $this->decrypt = new Crypt_RC4();
                 break;
-            case 'none';
+            case 'none':
                 //$this->decrypt = new Crypt_Null();
         }
 
         $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
 
         if ($this->encrypt) {
+            if ($this->crypto_engine) {
+                $this->encrypt->setEngine($this->crypto_engine);
+            }
             $this->encrypt->enableContinuousBuffer();
             $this->encrypt->disablePadding();
 
@@ -1663,6 +1782,9 @@ class Net_SSH2
         }
 
         if ($this->decrypt) {
+            if ($this->crypto_engine) {
+                $this->decrypt->setEngine($this->crypto_engine);
+            }
             $this->decrypt->enableContinuousBuffer();
             $this->decrypt->disablePadding();
 
@@ -1693,14 +1815,14 @@ class Net_SSH2
             $this->decrypt->decrypt(str_repeat("\0", 1536));
         }
 
-        for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_client_to_server); $i++);
-        if ($i == count($mac_algorithms)) {
+        $mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_client_to_server);
+        if ($mac_algorithm === false) {
             user_error('No compatible client to server message authentication algorithms found');
             return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
         }
 
-        $createKeyLength = 0; // ie. $mac_algorithms[$i] == 'none'
-        switch ($mac_algorithms[$i]) {
+        $createKeyLength = 0; // ie. $mac_algorithm == 'none'
+        switch ($mac_algorithm) {
             case 'hmac-sha2-256':
                 $this->hmac_create = new Crypt_Hash('sha256');
                 $createKeyLength = 32;
@@ -1722,15 +1844,15 @@ class Net_SSH2
                 $createKeyLength = 16;
         }
 
-        for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_server_to_client); $i++);
-        if ($i == count($mac_algorithms)) {
+        $mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_server_to_client);
+        if ($mac_algorithm === false) {
             user_error('No compatible server to client message authentication algorithms found');
             return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
         }
 
         $checkKeyLength = 0;
         $this->hmac_size = 0;
-        switch ($mac_algorithms[$i]) {
+        switch ($mac_algorithm) {
             case 'hmac-sha2-256':
                 $this->hmac_check = new Crypt_Hash('sha256');
                 $checkKeyLength = 32;
@@ -1769,33 +1891,72 @@ class Net_SSH2
         }
         $this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
 
-        for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_server_to_client); $i++);
-        if ($i == count($compression_algorithms)) {
+        $compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_server_to_client);
+        if ($compression_algorithm === false) {
             user_error('No compatible server to client compression algorithms found');
             return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
         }
-        $this->decompress = $compression_algorithms[$i] == 'zlib';
+        $this->decompress = $compression_algorithm == 'zlib';
 
-        for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_client_to_server); $i++);
-        if ($i == count($compression_algorithms)) {
+        $compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_client_to_server);
+        if ($compression_algorithm === false) {
             user_error('No compatible client to server compression algorithms found');
             return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
         }
-        $this->compress = $compression_algorithms[$i] == 'zlib';
+        $this->compress = $compression_algorithm == 'zlib';
 
         return true;
     }
 
+    /**
+     * Maps an encryption algorithm name to the number of key bytes.
+     *
+     * @param string $algorithm Name of the encryption algorithm
+     * @return int|null Number of bytes as an integer or null for unknown
+     * @access private
+     */
+    function _encryption_algorithm_to_key_size($algorithm)
+    {
+        switch ($algorithm) {
+            case 'none':
+                return 0;
+            case 'aes128-cbc':
+            case 'aes128-ctr':
+            case 'arcfour':
+            case 'arcfour128':
+            case 'blowfish-cbc':
+            case 'blowfish-ctr':
+            case 'twofish128-cbc':
+            case 'twofish128-ctr':
+                return 16;
+            case '3des-cbc':
+            case '3des-ctr':
+            case 'aes192-cbc':
+            case 'aes192-ctr':
+            case 'twofish192-cbc':
+            case 'twofish192-ctr':
+                return 24;
+            case 'aes256-cbc':
+            case 'aes256-ctr':
+            case 'arcfour256':
+            case 'twofish-cbc':
+            case 'twofish256-cbc':
+            case 'twofish256-ctr':
+                return 32;
+        }
+        return null;
+    }
+
     /**
      * Login
      *
      * The $password parameter can be a plaintext password, a Crypt_RSA object or an array
      *
-     * @param String $username
-     * @param Mixed $password
-     * @param Mixed $...
-     * @return Boolean
-     * @see _login
+     * @param string $username
+     * @param mixed $password
+     * @param mixed $...
+     * @return bool
+     * @see self::_login()
      * @access public
      */
     function login($username)
@@ -1807,11 +1968,11 @@ class Net_SSH2
     /**
      * Login Helper
      *
-     * @param String $username
-     * @param Mixed $password
-     * @param Mixed $...
-     * @return Boolean
-     * @see _login_helper
+     * @param string $username
+     * @param mixed $password
+     * @param mixed $...
+     * @return bool
+     * @see self::_login_helper()
      * @access private
      */
     function _login($username)
@@ -1838,9 +1999,9 @@ class Net_SSH2
     /**
      * Login Helper
      *
-     * @param String $username
-     * @param optional String $password
-     * @return Boolean
+     * @param string $username
+     * @param string $password
+     * @return bool
      * @access private
      * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
      *           by sending dummy SSH_MSG_IGNORE messages.
@@ -1852,8 +2013,11 @@ class Net_SSH2
         }
 
         if (!($this->bitmap & NET_SSH2_MASK_LOGIN_REQ)) {
-            $packet = pack('CNa*',
-                NET_SSH2_MSG_SERVICE_REQUEST, strlen('ssh-userauth'), 'ssh-userauth'
+            $packet = pack(
+                'CNa*',
+                NET_SSH2_MSG_SERVICE_REQUEST,
+                strlen('ssh-userauth'),
+                'ssh-userauth'
             );
 
             if (!$this->_send_binary_packet($packet)) {
@@ -1898,9 +2062,15 @@ class Net_SSH2
         }
 
         if (!isset($password)) {
-            $packet = pack('CNa*Na*Na*',
-                NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
-                strlen('none'), 'none'
+            $packet = pack(
+                'CNa*Na*Na*',
+                NET_SSH2_MSG_USERAUTH_REQUEST,
+                strlen($username),
+                $username,
+                strlen('ssh-connection'),
+                'ssh-connection',
+                strlen('none'),
+                'none'
             );
 
             if (!$this->_send_binary_packet($packet)) {
@@ -1925,18 +2095,36 @@ class Net_SSH2
             }
         }
 
-        $packet = pack('CNa*Na*Na*CNa*',
-            NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
-            strlen('password'), 'password', 0, strlen($password), $password
+        $packet = pack(
+            'CNa*Na*Na*CNa*',
+            NET_SSH2_MSG_USERAUTH_REQUEST,
+            strlen($username),
+            $username,
+            strlen('ssh-connection'),
+            'ssh-connection',
+            strlen('password'),
+            'password',
+            0,
+            strlen($password),
+            $password
         );
 
         // remove the username and password from the logged packet
         if (!defined('NET_SSH2_LOGGING')) {
             $logged = null;
         } else {
-            $logged = pack('CNa*Na*Na*CNa*',
-                NET_SSH2_MSG_USERAUTH_REQUEST, strlen('username'), 'username', strlen('ssh-connection'), 'ssh-connection',
-                strlen('password'), 'password', 0, strlen('password'), 'password'
+            $logged = pack(
+                'CNa*Na*Na*CNa*',
+                NET_SSH2_MSG_USERAUTH_REQUEST,
+                strlen('username'),
+                'username',
+                strlen('ssh-connection'),
+                'ssh-connection',
+                strlen('password'),
+                'password',
+                0,
+                strlen('password'),
+                'password'
             );
         }
 
@@ -1989,16 +2177,26 @@ class Net_SSH2
      *
      * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details.  This is not a full-featured keyboard-interactive authenticator.
      *
-     * @param String $username
-     * @param String $password
-     * @return Boolean
+     * @param string $username
+     * @param string $password
+     * @return bool
      * @access private
      */
     function _keyboard_interactive_login($username, $password)
     {
-        $packet = pack('CNa*Na*Na*Na*Na*',
-            NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
-            strlen('keyboard-interactive'), 'keyboard-interactive', 0, '', 0, ''
+        $packet = pack(
+            'CNa*Na*Na*Na*Na*',
+            NET_SSH2_MSG_USERAUTH_REQUEST,
+            strlen($username),
+            $username,
+            strlen('ssh-connection'),
+            'ssh-connection',
+            strlen('keyboard-interactive'),
+            'keyboard-interactive',
+            0,
+            '',
+            0,
+            ''
         );
 
         if (!$this->_send_binary_packet($packet)) {
@@ -2011,8 +2209,8 @@ class Net_SSH2
     /**
      * Handle the keyboard-interactive requests / responses.
      *
-     * @param String $responses...
-     * @return Boolean
+     * @param string $responses...
+     * @return bool
      * @access private
      */
     function _keyboard_interactive_process()
@@ -2069,7 +2267,7 @@ class Net_SSH2
                 // see http://tools.ietf.org/html/rfc4256#section-3.2
                 if (strlen($this->last_interactive_response)) {
                     $this->last_interactive_response = '';
-                } else if (defined('NET_SSH2_LOGGING')) {
+                } elseif (defined('NET_SSH2_LOGGING')) {
                     $this->message_number_log[count($this->message_number_log) - 1] = str_replace(
                         'UNKNOWN',
                         'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
@@ -2125,13 +2323,14 @@ class Net_SSH2
     /**
      * Login with an ssh-agent provided key
      *
-     * @param String $username
+     * @param string $username
      * @param System_SSH_Agent $agent
-     * @return Boolean
+     * @return bool
      * @access private
      */
     function _ssh_agent_login($username, $agent)
     {
+        $this->agent = $agent;
         $keys = $agent->requestIdentities();
         foreach ($keys as $key) {
             if ($this->_privatekey_login($username, $key)) {
@@ -2145,9 +2344,9 @@ class Net_SSH2
     /**
      * Login with an RSA private key
      *
-     * @param String $username
+     * @param string $username
      * @param Crypt_RSA $password
-     * @return Boolean
+     * @return bool
      * @access private
      * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
      *           by sending dummy SSH_MSG_IGNORE messages.
@@ -2164,13 +2363,25 @@ class Net_SSH2
             'e' => $publickey['e']->toBytes(true),
             'n' => $publickey['n']->toBytes(true)
         );
-        $publickey = pack('Na*Na*Na*',
-            strlen('ssh-rsa'), 'ssh-rsa', strlen($publickey['e']), $publickey['e'], strlen($publickey['n']), $publickey['n']
+        $publickey = pack(
+            'Na*Na*Na*',
+            strlen('ssh-rsa'),
+            'ssh-rsa',
+            strlen($publickey['e']),
+            $publickey['e'],
+            strlen($publickey['n']),
+            $publickey['n']
         );
 
-        $part1 = pack('CNa*Na*Na*',
-            NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
-            strlen('publickey'), 'publickey'
+        $part1 = pack(
+            'CNa*Na*Na*',
+            NET_SSH2_MSG_USERAUTH_REQUEST,
+            strlen($username),
+            $username,
+            strlen('ssh-connection'),
+            'ssh-connection',
+            strlen('publickey'),
+            'publickey'
         );
         $part2 = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publickey), $publickey);
 
@@ -2240,7 +2451,7 @@ class Net_SSH2
      * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely.  setTimeout() makes it so it'll timeout.
      * Setting $timeout to false or 0 will mean there is no timeout.
      *
-     * @param Mixed $timeout
+     * @param mixed $timeout
      * @access public
      */
     function setTimeout($timeout)
@@ -2264,9 +2475,9 @@ class Net_SSH2
      * If $callback is set to false then Net_SSH2::_get_channel_packet(NET_SSH2_CHANNEL_EXEC) will need to be called manually.
      * In all likelihood, this is not a feature you want to be taking advantage of.
      *
-     * @param String $command
-     * @param optional Callback $callback
-     * @return String
+     * @param string $command
+     * @param Callback $callback
+     * @return string
      * @access public
      */
     function exec($command, $callback = null)
@@ -2281,15 +2492,22 @@ class Net_SSH2
 
         // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to
         // be adjusted".  0x7FFFFFFF is, at 2GB, the max size.  technically, it should probably be decremented, but,
-        // honestly, if you're transfering more than 2GB, you probably shouldn't be using phpseclib, anyway.
+        // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway.
         // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info
         $this->window_size_server_to_client[NET_SSH2_CHANNEL_EXEC] = $this->window_size;
         // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy
         // uses 0x4000, that's what will be used here, as well.
         $packet_size = 0x4000;
 
-        $packet = pack('CNa*N3',
-            NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', NET_SSH2_CHANNEL_EXEC, $this->window_size_server_to_client[NET_SSH2_CHANNEL_EXEC], $packet_size);
+        $packet = pack(
+            'CNa*N3',
+            NET_SSH2_MSG_CHANNEL_OPEN,
+            strlen('session'),
+            'session',
+            NET_SSH2_CHANNEL_EXEC,
+            $this->window_size_server_to_client[NET_SSH2_CHANNEL_EXEC],
+            $packet_size
+        );
 
         if (!$this->_send_binary_packet($packet)) {
             return false;
@@ -2304,13 +2522,27 @@ class Net_SSH2
 
         if ($this->request_pty === true) {
             $terminal_modes = pack('C', NET_SSH2_TTY_OP_END);
-            $packet = pack('CNNa*CNa*N5a*',
-                NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SSH2_CHANNEL_EXEC], strlen('pty-req'), 'pty-req', 1, strlen('vt100'), 'vt100',
-                $this->windowColumns, $this->windowRows, 0, 0, strlen($terminal_modes), $terminal_modes);
+            $packet = pack(
+                'CNNa*CNa*N5a*',
+                NET_SSH2_MSG_CHANNEL_REQUEST,
+                $this->server_channels[NET_SSH2_CHANNEL_EXEC],
+                strlen('pty-req'),
+                'pty-req',
+                1,
+                strlen('vt100'),
+                'vt100',
+                $this->windowColumns,
+                $this->windowRows,
+                0,
+                0,
+                strlen($terminal_modes),
+                $terminal_modes
+            );
 
             if (!$this->_send_binary_packet($packet)) {
                 return false;
             }
+
             $response = $this->_get_binary_packet();
             if ($response === false) {
                 user_error('Connection closed by server');
@@ -2339,8 +2571,17 @@ class Net_SSH2
         // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by
         // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the
         // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA.  RFC4254#section-5.2 corroborates.
-        $packet = pack('CNNa*CNa*',
-            NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SSH2_CHANNEL_EXEC], strlen('exec'), 'exec', 1, strlen($command), $command);
+        $packet = pack(
+            'CNNa*CNa*',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $this->server_channels[NET_SSH2_CHANNEL_EXEC],
+            strlen('exec'),
+            'exec',
+            1,
+            strlen($command),
+            $command
+        );
+
         if (!$this->_send_binary_packet($packet)) {
             return false;
         }
@@ -2382,9 +2623,9 @@ class Net_SSH2
     /**
      * Creates an interactive shell
      *
-     * @see Net_SSH2::read()
-     * @see Net_SSH2::write()
-     * @return Boolean
+     * @see self::read()
+     * @see self::write()
+     * @return bool
      * @access private
      */
     function _initShell()
@@ -2396,8 +2637,15 @@ class Net_SSH2
         $this->window_size_server_to_client[NET_SSH2_CHANNEL_SHELL] = $this->window_size;
         $packet_size = 0x4000;
 
-        $packet = pack('CNa*N3',
-            NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', NET_SSH2_CHANNEL_SHELL, $this->window_size_server_to_client[NET_SSH2_CHANNEL_SHELL], $packet_size);
+        $packet = pack(
+            'CNa*N3',
+            NET_SSH2_MSG_CHANNEL_OPEN,
+            strlen('session'),
+            'session',
+            NET_SSH2_CHANNEL_SHELL,
+            $this->window_size_server_to_client[NET_SSH2_CHANNEL_SHELL],
+            $packet_size
+        );
 
         if (!$this->_send_binary_packet($packet)) {
             return false;
@@ -2411,9 +2659,22 @@ class Net_SSH2
         }
 
         $terminal_modes = pack('C', NET_SSH2_TTY_OP_END);
-        $packet = pack('CNNa*CNa*N5a*',
-            NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SSH2_CHANNEL_SHELL], strlen('pty-req'), 'pty-req', 1, strlen('vt100'), 'vt100',
-            $this->windowColumns, $this->windowRows, 0, 0, strlen($terminal_modes), $terminal_modes);
+        $packet = pack(
+            'CNNa*CNa*N5a*',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $this->server_channels[NET_SSH2_CHANNEL_SHELL],
+            strlen('pty-req'),
+            'pty-req',
+            1,
+            strlen('vt100'),
+            'vt100',
+            $this->windowColumns,
+            $this->windowRows,
+            0,
+            0,
+            strlen($terminal_modes),
+            $terminal_modes
+        );
 
         if (!$this->_send_binary_packet($packet)) {
             return false;
@@ -2437,8 +2698,14 @@ class Net_SSH2
                 return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
         }
 
-        $packet = pack('CNNa*C',
-            NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SSH2_CHANNEL_SHELL], strlen('shell'), 'shell', 1);
+        $packet = pack(
+            'CNNa*C',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $this->server_channels[NET_SSH2_CHANNEL_SHELL],
+            strlen('shell'),
+            'shell',
+            1
+        );
         if (!$this->_send_binary_packet($packet)) {
             return false;
         }
@@ -2460,9 +2727,9 @@ class Net_SSH2
     /**
      * Return the channel to be used with read() / write()
      *
-     * @see Net_SSH2::read()
-     * @see Net_SSH2::write()
-     * @return Integer
+     * @see self::read()
+     * @see self::write()
+     * @return int
      * @access public
      */
     function _get_interactive_channel()
@@ -2477,16 +2744,34 @@ class Net_SSH2
         }
     }
 
+    /**
+     * Return an available open channel
+     *
+     * @return int
+     * @access public
+     */
+    function _get_open_channel()
+    {
+        $channel = NET_SSH2_CHANNEL_EXEC;
+        do {
+            if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_OPEN) {
+                return $channel;
+            }
+        } while ($channel++ < NET_SSH2_CHANNEL_SUBSYSTEM);
+
+        return false;
+    }
+
     /**
      * Returns the output of an interactive shell
      *
      * Returns when there's a match for $expect, which can take the form of a string literal or,
      * if $mode == NET_SSH2_READ_REGEX, a regular expression.
      *
-     * @see Net_SSH2::write()
-     * @param String $expect
-     * @param Integer $mode
-     * @return String
+     * @see self::write()
+     * @param string $expect
+     * @param int $mode
+     * @return string
      * @access public
      */
     function read($expect = '', $mode = NET_SSH2_READ_SIMPLE)
@@ -2509,7 +2794,7 @@ class Net_SSH2
         $match = $expect;
         while (true) {
             if ($mode == NET_SSH2_READ_REGEX) {
-                preg_match($expect, $this->interactiveBuffer, $matches);
+                preg_match($expect, substr($this->interactiveBuffer, -1024), $matches);
                 $match = isset($matches[0]) ? $matches[0] : '';
             }
             $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false;
@@ -2529,9 +2814,9 @@ class Net_SSH2
     /**
      * Inputs a command into an interactive shell.
      *
-     * @see Net_SSH2::read()
-     * @param String $cmd
-     * @return Boolean
+     * @see self::read()
+     * @param string $cmd
+     * @return bool
      * @access public
      */
     function write($cmd)
@@ -2558,17 +2843,24 @@ class Net_SSH2
      * returns that and then that that was passed into stopSubsystem() but that'll be saved for a future date and implemented
      * if there's sufficient demand for such a feature.
      *
-     * @see Net_SSH2::stopSubsystem()
-     * @param String $subsystem
-     * @return Boolean
+     * @see self::stopSubsystem()
+     * @param string $subsystem
+     * @return bool
      * @access public
      */
     function startSubsystem($subsystem)
     {
         $this->window_size_server_to_client[NET_SSH2_CHANNEL_SUBSYSTEM] = $this->window_size;
 
-        $packet = pack('CNa*N3',
-            NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', NET_SSH2_CHANNEL_SUBSYSTEM, $this->window_size, 0x4000);
+        $packet = pack(
+            'CNa*N3',
+            NET_SSH2_MSG_CHANNEL_OPEN,
+            strlen('session'),
+            'session',
+            NET_SSH2_CHANNEL_SUBSYSTEM,
+            $this->window_size,
+            0x4000
+        );
 
         if (!$this->_send_binary_packet($packet)) {
             return false;
@@ -2581,8 +2873,16 @@ class Net_SSH2
             return false;
         }
 
-        $packet = pack('CNNa*CNa*',
-            NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SSH2_CHANNEL_SUBSYSTEM], strlen('subsystem'), 'subsystem', 1, strlen($subsystem), $subsystem);
+        $packet = pack(
+            'CNNa*CNa*',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $this->server_channels[NET_SSH2_CHANNEL_SUBSYSTEM],
+            strlen('subsystem'),
+            'subsystem',
+            1,
+            strlen($subsystem),
+            $subsystem
+        );
         if (!$this->_send_binary_packet($packet)) {
             return false;
         }
@@ -2592,7 +2892,7 @@ class Net_SSH2
         $response = $this->_get_channel_packet(NET_SSH2_CHANNEL_SUBSYSTEM);
 
         if ($response === false) {
-           return false;
+            return false;
         }
 
         $this->channel_status[NET_SSH2_CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA;
@@ -2606,8 +2906,8 @@ class Net_SSH2
     /**
      * Stops a subsystem.
      *
-     * @see Net_SSH2::startSubsystem()
-     * @return Boolean
+     * @see self::startSubsystem()
+     * @return bool
      * @access public
      */
     function stopSubsystem()
@@ -2670,7 +2970,7 @@ class Net_SSH2
     /**
      * Is the connection still active?
      *
-     * @return boolean
+     * @return bool
      * @access public
      */
     function isConnected()
@@ -2678,13 +2978,24 @@ class Net_SSH2
         return (bool) ($this->bitmap & NET_SSH2_MASK_CONNECTED);
     }
 
+    /**
+     * Have you successfully been logged in?
+     *
+     * @return bool
+     * @access public
+     */
+    function isAuthenticated()
+    {
+        return (bool) ($this->bitmap & NET_SSH2_MASK_LOGIN);
+    }
+
     /**
      * Gets Binary Packets
      *
      * See '6. Binary Packet Protocol' of rfc4253 for more info.
      *
-     * @see Net_SSH2::_send_binary_packet()
-     * @return String
+     * @see self::_send_binary_packet()
+     * @return string
      * @access private
      */
     function _get_binary_packet()
@@ -2776,8 +3087,8 @@ class Net_SSH2
      *
      * Because some binary packets need to be ignored...
      *
-     * @see Net_SSH2::_get_binary_packet()
-     * @return String
+     * @see self::_get_binary_packet()
+     * @return string
      * @access private
      */
     function _filter($payload)
@@ -2822,9 +3133,8 @@ class Net_SSH2
         if (($this->bitmap & NET_SSH2_MASK_CONNECTED) && ($this->bitmap & NET_SSH2_MASK_LOGIN)) {
             switch (ord($payload[0])) {
                 case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
-                    $this->_string_shift($payload, 1);
-                    extract(unpack('Nlength', $this->_string_shift($payload)));
-                    $this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . utf8_decode($this->_string_shift($payload, $length));
+                    extract(unpack('Nlength', $this->_string_shift($payload, 4)));
+                    $this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . $this->_string_shift($payload, $length);
 
                     if (!$this->_send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE))) {
                         return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
@@ -2835,18 +3145,55 @@ class Net_SSH2
                 case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
                     $this->_string_shift($payload, 1);
                     extract(unpack('Nlength', $this->_string_shift($payload, 4)));
-                    $this->errors[] = 'SSH_MSG_CHANNEL_OPEN: ' . utf8_decode($this->_string_shift($payload, $length));
-
-                    $this->_string_shift($payload, 4); // skip over client channel
+                    $data = $this->_string_shift($payload, $length);
                     extract(unpack('Nserver_channel', $this->_string_shift($payload, 4)));
-
-                    $packet = pack('CN3a*Na*',
-                        NET_SSH2_MSG_REQUEST_FAILURE, $server_channel, NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, 0, '', 0, '');
-
-                    if (!$this->_send_binary_packet($packet)) {
-                        return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+                    switch ($data) {
+                        case 'auth-agent':
+                        case 'auth-agent@openssh.com':
+                            if (isset($this->agent)) {
+                                $new_channel = NET_SSH2_CHANNEL_AGENT_FORWARD;
+
+                                extract(unpack('Nremote_window_size', $this->_string_shift($payload, 4)));
+                                extract(unpack('Nremote_maximum_packet_size', $this->_string_shift($payload, 4)));
+
+                                $this->packet_size_client_to_server[$new_channel] = $remote_window_size;
+                                $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size;
+                                $this->window_size_client_to_server[$new_channel] = $this->window_size;
+
+                                $packet_size = 0x4000;
+
+                                $packet = pack(
+                                    'CN4',
+                                    NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
+                                    $server_channel,
+                                    $new_channel,
+                                    $packet_size,
+                                    $packet_size
+                                );
+
+                                $this->server_channels[$new_channel] = $server_channel;
+                                $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION;
+                                if (!$this->_send_binary_packet($packet)) {
+                                    return false;
+                                }
+                            }
+                            break;
+                        default:
+                            $packet = pack(
+                                'CN3a*Na*',
+                                NET_SSH2_MSG_REQUEST_FAILURE,
+                                $server_channel,
+                                NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED,
+                                0,
+                                '',
+                                0,
+                                ''
+                            );
+
+                            if (!$this->_send_binary_packet($packet)) {
+                                return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+                            }
                     }
-
                     $payload = $this->_get_binary_packet();
                     break;
                 case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
@@ -2889,11 +3236,11 @@ class Net_SSH2
     /**
      * Returns whether Quiet Mode is enabled or not
      *
-     * @see Net_SSH2::enableQuietMode()
-     * @see Net_SSH2::disableQuietMode()
+     * @see self::enableQuietMode()
+     * @see self::disableQuietMode()
      *
      * @access public
-     * @return boolean
+     * @return bool
      */
     function isQuietModeEnabled()
     {
@@ -2923,11 +3270,11 @@ class Net_SSH2
     /**
      * Returns whether request-pty is enabled or not
      *
-     * @see Net_SSH2::enablePTY()
-     * @see Net_SSH2::disablePTY()
+     * @see self::enablePTY()
+     * @see self::disablePTY()
      *
      * @access public
-     * @return boolean
+     * @return bool
      */
     function isPTYEnabled()
     {
@@ -2940,7 +3287,7 @@ class Net_SSH2
      * Returns the data as a string if it's available and false if not.
      *
      * @param $client_channel
-     * @return Mixed
+     * @return mixed
      * @access private
      */
     function _get_channel_packet($client_channel, $skip_extended = false)
@@ -2983,48 +3330,63 @@ class Net_SSH2
                 return '';
             }
 
-            extract(unpack('Ctype/Nchannel', $this->_string_shift($response, 5)));
-
-            $this->window_size_server_to_client[$channel]-= strlen($response);
+            extract(unpack('Ctype', $this->_string_shift($response, 1)));
 
-            // resize the window, if appropriate
-            if ($this->window_size_server_to_client[$channel] < 0) {
-                $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_size);
-                if (!$this->_send_binary_packet($packet)) {
-                    return false;
-                }
-                $this->window_size_server_to_client[$channel]+= $this->window_size;
+            if ($type == NET_SSH2_MSG_CHANNEL_OPEN) {
+                extract(unpack('Nlength', $this->_string_shift($response, 4)));
+            } else {
+                extract(unpack('Nchannel', $this->_string_shift($response, 4)));
             }
 
-            switch ($this->channel_status[$channel]) {
-                case NET_SSH2_MSG_CHANNEL_OPEN:
-                    switch ($type) {
-                        case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
-                            extract(unpack('Nserver_channel', $this->_string_shift($response, 4)));
-                            $this->server_channels[$channel] = $server_channel;
-                            extract(unpack('Nwindow_size', $this->_string_shift($response, 4)));
-                            $this->window_size_client_to_server[$channel] = $window_size;
-                            $temp = unpack('Npacket_size_client_to_server', $this->_string_shift($response, 4));
-                            $this->packet_size_client_to_server[$channel] = $temp['packet_size_client_to_server'];
-                            return $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended);
-                        //case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
-                        default:
-                            user_error('Unable to open channel');
-                            return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
-                    }
-                    break;
-                case NET_SSH2_MSG_CHANNEL_REQUEST:
-                    switch ($type) {
-                        case NET_SSH2_MSG_CHANNEL_SUCCESS:
-                            return true;
-                        case NET_SSH2_MSG_CHANNEL_FAILURE:
-                            return false;
-                        default:
-                            user_error('Unable to fulfill channel request');
-                            return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+            // will not be setup yet on incoming channel open request
+            if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) {
+                $this->window_size_server_to_client[$channel]-= strlen($response);
+
+                // resize the window, if appropriate
+                if ($this->window_size_server_to_client[$channel] < 0) {
+                    $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_size);
+                    if (!$this->_send_binary_packet($packet)) {
+                        return false;
                     }
-                case NET_SSH2_MSG_CHANNEL_CLOSE:
-                    return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended);
+                    $this->window_size_server_to_client[$channel]+= $this->window_size;
+                }
+
+                switch ($this->channel_status[$channel]) {
+                    case NET_SSH2_MSG_CHANNEL_OPEN:
+                        switch ($type) {
+                            case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
+                                extract(unpack('Nserver_channel', $this->_string_shift($response, 4)));
+                                $this->server_channels[$channel] = $server_channel;
+                                extract(unpack('Nwindow_size', $this->_string_shift($response, 4)));
+                                if ($window_size < 0) {
+                                    $window_size&= 0x7FFFFFFF;
+                                    $window_size+= 0x80000000;
+                                }
+                                $this->window_size_client_to_server[$channel] = $window_size;
+                                $temp = unpack('Npacket_size_client_to_server', $this->_string_shift($response, 4));
+                                $this->packet_size_client_to_server[$channel] = $temp['packet_size_client_to_server'];
+                                $result = $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended);
+                                $this->_on_channel_open();
+                                return $result;
+                            //case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
+                            default:
+                                user_error('Unable to open channel');
+                                return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+                        }
+                        break;
+                    case NET_SSH2_MSG_CHANNEL_REQUEST:
+                        switch ($type) {
+                            case NET_SSH2_MSG_CHANNEL_SUCCESS:
+                                return true;
+                            case NET_SSH2_MSG_CHANNEL_FAILURE:
+                                return false;
+                            default:
+                                user_error('Unable to fulfill channel request');
+                                return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+                        }
+                    case NET_SSH2_MSG_CHANNEL_CLOSE:
+                        return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended);
+                }
             }
 
             // ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA
@@ -3042,6 +3404,15 @@ class Net_SSH2
                     */
                     extract(unpack('Nlength', $this->_string_shift($response, 4)));
                     $data = $this->_string_shift($response, $length);
+
+                    if ($channel == NET_SSH2_CHANNEL_AGENT_FORWARD) {
+                        $agent_response = $this->agent->_forward_data($data);
+                        if (!is_bool($agent_response)) {
+                            $this->_send_channel_packet($channel, $agent_response);
+                        }
+                        break;
+                    }
+
                     if ($client_channel == $channel) {
                         return $data;
                     }
@@ -3116,7 +3487,9 @@ class Net_SSH2
                     }
 
                     $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE;
-                    return true;
+                    if ($client_channel == $channel) {
+                        return true;
+                    }
                 case NET_SSH2_MSG_CHANNEL_EOF:
                     break;
                 default:
@@ -3131,10 +3504,10 @@ class Net_SSH2
      *
      * See '6. Binary Packet Protocol' of rfc4253 for more info.
      *
-     * @param String $data
-     * @param optional String $logged
-     * @see Net_SSH2::_get_binary_packet()
-     * @return Boolean
+     * @param string $data
+     * @param string $logged
+     * @see self::_get_binary_packet()
+     * @return bool
      * @access private
      */
     function _send_binary_packet($data, $logged = null)
@@ -3192,7 +3565,7 @@ class Net_SSH2
      *
      * Makes sure that only the last 1MB worth of packets will be logged
      *
-     * @param String $data
+     * @param string $data
      * @access private
      */
     function _append_log($message_number, $message)
@@ -3268,9 +3641,9 @@ class Net_SSH2
      *
      * Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate
      *
-     * @param Integer $client_channel
-     * @param String $data
-     * @return Boolean
+     * @param int $client_channel
+     * @param string $data
+     * @return bool
      * @access private
      */
     function _send_channel_packet($client_channel, $data)
@@ -3293,7 +3666,8 @@ class Net_SSH2
             );
 
             $temp = $this->_string_shift($data, $max_size);
-            $packet = pack('CN2a*',
+            $packet = pack(
+                'CN2a*',
                 NET_SSH2_MSG_CHANNEL_DATA,
                 $this->server_channels[$client_channel],
                 strlen($temp),
@@ -3315,9 +3689,9 @@ class Net_SSH2
      * and for SFTP channels are presumably closed when the client disconnects.  This functions is intended
      * for SCP more than anything.
      *
-     * @param Integer $client_channel
-     * @param Boolean $want_reply
-     * @return Boolean
+     * @param int $client_channel
+     * @param bool $want_reply
+     * @return bool
      * @access private
      */
     function _close_channel($client_channel, $want_reply = false)
@@ -3334,7 +3708,8 @@ class Net_SSH2
 
         $this->curTimeout = 0;
 
-        while (!is_bool($this->_get_channel_packet($client_channel)));
+        while (!is_bool($this->_get_channel_packet($client_channel))) {
+        }
 
         if ($want_reply) {
             $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel]));
@@ -3348,8 +3723,8 @@ class Net_SSH2
     /**
      * Disconnect
      *
-     * @param Integer $reason
-     * @return Boolean
+     * @param int $reason
+     * @return bool
      * @access private
      */
     function _disconnect($reason)
@@ -3368,9 +3743,9 @@ class Net_SSH2
      *
      * Inspired by array_shift
      *
-     * @param String $string
-     * @param optional Integer $index
-     * @return String
+     * @param string $string
+     * @param int $index
+     * @return string
      * @access private
      */
     function _string_shift(&$string, $index = 1)
@@ -3387,14 +3762,14 @@ class Net_SSH2
      * named constants from it, using the value as the name of the constant and the index as the value of the constant.
      * If any of the constants that would be defined already exists, none of the constants will be defined.
      *
-     * @param Array $array
+     * @param array $array
      * @access private
      */
     function _define_array()
     {
         $args = func_get_args();
         foreach ($args as $arg) {
-            foreach ($arg as $key=>$value) {
+            foreach ($arg as $key => $value) {
                 if (!defined($value)) {
                     define($value, $key);
                 } else {
@@ -3410,7 +3785,7 @@ class Net_SSH2
      * Returns a string if NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX, an array if NET_SSH2_LOGGING == NET_SSH2_LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING')
      *
      * @access public
-     * @return String or Array
+     * @return array|false|string
      */
     function getLog()
     {
@@ -3433,10 +3808,10 @@ class Net_SSH2
     /**
      * Formats a log for printing
      *
-     * @param Array $message_log
-     * @param Array $message_number_log
+     * @param array $message_log
+     * @param array $message_number_log
      * @access private
-     * @return String
+     * @return string
      */
     function _format_log($message_log, $message_number_log)
     {
@@ -3469,19 +3844,54 @@ class Net_SSH2
      *
      * For use with preg_replace_callback()
      *
-     * @param Array $matches
+     * @param array $matches
      * @access private
-     * @return String
+     * @return string
      */
     function _format_log_helper($matches)
     {
         return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT);
     }
 
+    /**
+     * Helper function for agent->_on_channel_open()
+     *
+     * Used when channels are created to inform agent
+     * of said channel opening. Must be called after
+     * channel open confirmation received
+     *
+     * @access private
+     */
+    function _on_channel_open()
+    {
+        if (isset($this->agent)) {
+            $this->agent->_on_channel_open($this);
+        }
+    }
+
+    /**
+     * Returns the first value of the intersection of two arrays or false if
+     * the intersection is empty. The order is defined by the first parameter.
+     *
+     * @param array $array1
+     * @param array $array2
+     * @return mixed False if intersection is empty, else intersected value.
+     * @access private
+     */
+    function _array_intersect_first($array1, $array2)
+    {
+        foreach ($array1 as $value) {
+            if (in_array($value, $array2)) {
+                return $value;
+            }
+        }
+        return false;
+    }
+
     /**
      * Returns all errors
      *
-     * @return String
+     * @return string[]
      * @access public
      */
     function getErrors()
@@ -3492,18 +3902,22 @@ class Net_SSH2
     /**
      * Returns the last error
      *
-     * @return String
+     * @return string
      * @access public
      */
     function getLastError()
     {
-        return $this->errors[count($this->errors) - 1];
+        $count = count($this->errors);
+
+        if ($count > 0) {
+            return $this->errors[$count - 1];
+        }
     }
 
     /**
      * Return the server identification.
      *
-     * @return String
+     * @return string
      * @access public
      */
     function getServerIdentification()
@@ -3516,7 +3930,7 @@ class Net_SSH2
     /**
      * Return a list of the key exchange algorithms the server supports.
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getKexAlgorithms()
@@ -3529,7 +3943,7 @@ class Net_SSH2
     /**
      * Return a list of the host key (public key) algorithms the server supports.
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getServerHostKeyAlgorithms()
@@ -3542,7 +3956,7 @@ class Net_SSH2
     /**
      * Return a list of the (symmetric key) encryption algorithms the server supports, when receiving stuff from the client.
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getEncryptionAlgorithmsClient2Server()
@@ -3555,7 +3969,7 @@ class Net_SSH2
     /**
      * Return a list of the (symmetric key) encryption algorithms the server supports, when sending stuff to the client.
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getEncryptionAlgorithmsServer2Client()
@@ -3568,7 +3982,7 @@ class Net_SSH2
     /**
      * Return a list of the MAC algorithms the server supports, when receiving stuff from the client.
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getMACAlgorithmsClient2Server()
@@ -3581,7 +3995,7 @@ class Net_SSH2
     /**
      * Return a list of the MAC algorithms the server supports, when sending stuff to the client.
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getMACAlgorithmsServer2Client()
@@ -3594,7 +4008,7 @@ class Net_SSH2
     /**
      * Return a list of the compression algorithms the server supports, when receiving stuff from the client.
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getCompressionAlgorithmsClient2Server()
@@ -3607,7 +4021,7 @@ class Net_SSH2
     /**
      * Return a list of the compression algorithms the server supports, when sending stuff to the client.
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getCompressionAlgorithmsServer2Client()
@@ -3620,7 +4034,7 @@ class Net_SSH2
     /**
      * Return a list of the languages the server supports, when sending stuff to the client.
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getLanguagesServer2Client()
@@ -3633,7 +4047,7 @@ class Net_SSH2
     /**
      * Return a list of the languages the server supports, when receiving stuff from the client.
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function getLanguagesClient2Server()
@@ -3649,7 +4063,7 @@ class Net_SSH2
      * Quoting from the RFC, "in some jurisdictions, sending a warning message before
      * authentication may be relevant for getting legal protection."
      *
-     * @return String
+     * @return string
      * @access public
      */
     function getBannerMessage()
@@ -3663,7 +4077,7 @@ class Net_SSH2
      * Caching this the first time you connect to a server and checking the result on subsequent connections
      * is recommended.  Returns false if the server signature is not signed correctly with the public host key.
      *
-     * @return Mixed
+     * @return mixed
      * @access public
      */
     function getServerPublicHostKey()
@@ -3808,7 +4222,7 @@ class Net_SSH2
     /**
      * Returns the exit status of an SSH command or false.
      *
-     * @return Integer or false
+     * @return false|int
      * @access public
      */
     function getExitStatus()
@@ -3822,7 +4236,7 @@ class Net_SSH2
     /**
      * Returns the number of columns for the terminal window size.
      *
-     * @return Integer
+     * @return int
      * @access public
      */
     function getWindowColumns()
@@ -3833,7 +4247,7 @@ class Net_SSH2
     /**
      * Returns the number of rows for the terminal window size.
      *
-     * @return Integer
+     * @return int
      * @access public
      */
     function getWindowRows()
@@ -3844,7 +4258,7 @@ class Net_SSH2
     /**
      * Sets the number of columns for the terminal window size.
      *
-     * @param Integer $value
+     * @param int $value
      * @access public
      */
     function setWindowColumns($value)
@@ -3855,7 +4269,7 @@ class Net_SSH2
     /**
      * Sets the number of rows for the terminal window size.
      *
-     * @param Integer $value
+     * @param int $value
      * @access public
      */
     function setWindowRows($value)
@@ -3866,8 +4280,8 @@ class Net_SSH2
     /**
      * Sets the number of columns and rows for the terminal window size.
      *
-     * @param Integer $columns
-     * @param Integer $rows
+     * @param int $columns
+     * @param int $rows
      * @access public
      */
     function setWindowSize($columns = 80, $rows = 24)
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
index 4c0ef733d6dc787dd7bfce3641284875bce290c2..7388cb47e8091f316e195c8ff4f03fdef68cc6eb 100644
--- a/civicrm/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Pure-PHP ssh-agent client.
  *
@@ -63,6 +64,20 @@ define('SYSTEM_SSH_AGENT_FAILURE', 5);
 define('SYSTEM_SSH_AGENTC_SIGN_REQUEST', 13);
 // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
 define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14);
+
+
+/**@+
+ * Agent forwarding status
+ *
+ * @access private
+ */
+// no forwarding requested and not active
+define('SYSTEM_SSH_AGENT_FORWARD_NONE', 0);
+// request agent forwarding when opportune
+define('SYSTEM_SSH_AGENT_FORWARD_REQUEST', 1);
+// forwarding has been request and is active
+define('SYSTEM_SSH_AGENT_FORWARD_ACTIVE', 2);
+
 /**#@-*/
 
 /**
@@ -86,40 +101,52 @@ class System_SSH_Agent_Identity
      *
      * @var Crypt_RSA
      * @access private
-     * @see System_SSH_Agent_Identity::getPublicKey()
+     * @see self::getPublicKey()
      */
     var $key;
 
     /**
      * Key Blob
      *
-     * @var String
+     * @var string
      * @access private
-     * @see System_SSH_Agent_Identity::sign()
+     * @see self::sign()
      */
     var $key_blob;
 
     /**
      * Socket Resource
      *
-     * @var Resource
+     * @var resource
      * @access private
-     * @see System_SSH_Agent_Identity::sign()
+     * @see self::sign()
      */
     var $fsock;
 
     /**
      * Default Constructor.
      *
-     * @param Resource $fsock
+     * @param resource $fsock
      * @return System_SSH_Agent_Identity
      * @access private
      */
-    function System_SSH_Agent_Identity($fsock)
+    function __construct($fsock)
     {
         $this->fsock = $fsock;
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @param resource $fsock
+     * @access public
+     */
+    function System_SSH_Agent_Identity($fsock)
+    {
+        $this->__construct($fsock);
+    }
+
     /**
      * Set Public Key
      *
@@ -140,7 +167,7 @@ class System_SSH_Agent_Identity
      * Called by System_SSH_Agent::requestIdentities(). The key blob could be extracted from $this->key
      * but this saves a small amount of computation.
      *
-     * @param String $key_blob
+     * @param string $key_blob
      * @access private
      */
     function setPublicKeyBlob($key_blob)
@@ -153,8 +180,8 @@ class System_SSH_Agent_Identity
      *
      * Wrapper for $this->key->getPublicKey()
      *
-     * @param Integer $format optional
-     * @return Mixed
+     * @param int $format optional
+     * @return mixed
      * @access public
      */
     function getPublicKey($format = null)
@@ -168,7 +195,7 @@ class System_SSH_Agent_Identity
      * Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie.
      * ssh-agent's only supported mode is CRYPT_RSA_SIGNATURE_PKCS1
      *
-     * @param Integer $mode
+     * @param int $mode
      * @access public
      */
     function setSignatureMode($mode)
@@ -180,8 +207,8 @@ class System_SSH_Agent_Identity
      *
      * See "2.6.2 Protocol 2 private key signature request"
      *
-     * @param String $message
-     * @return String
+     * @param string $message
+     * @return string
      * @access public
      */
     function sign($message)
@@ -220,18 +247,41 @@ class System_SSH_Agent
     /**
      * Socket Resource
      *
-     * @var Resource
+     * @var resource
      * @access private
      */
     var $fsock;
 
+    /**
+     * Agent forwarding status
+     *
+     * @access private
+     */
+    var $forward_status = SYSTEM_SSH_AGENT_FORWARD_NONE;
+
+    /**
+     * Buffer for accumulating forwarded authentication
+     * agent data arriving on SSH data channel destined
+     * for agent unix socket
+     *
+     * @access private
+     */
+    var $socket_buffer = '';
+
+    /**
+     * Tracking the number of bytes we are expecting
+     * to arrive for the agent socket on the SSH data
+     * channel
+     */
+    var $expected_bytes = 0;
+
     /**
      * Default Constructor
      *
      * @return System_SSH_Agent
      * @access public
      */
-    function System_SSH_Agent()
+    function __construct()
     {
         switch (true) {
             case isset($_SERVER['SSH_AUTH_SOCK']):
@@ -251,13 +301,24 @@ class System_SSH_Agent
         }
     }
 
+    /**
+     * PHP4 compatible Default Constructor.
+     *
+     * @see self::__construct()
+     * @access public
+     */
+    function System_SSH_Agent()
+    {
+        $this->__construct();
+    }
+
     /**
      * Request Identities
      *
      * See "2.5.2 Requesting a list of protocol 2 keys"
      * Returns an array containing zero or more System_SSH_Agent_Identity objects
      *
-     * @return Array
+     * @return array
      * @access public
      */
     function requestIdentities()
@@ -282,8 +343,11 @@ class System_SSH_Agent
         for ($i = 0; $i < $keyCount; $i++) {
             $length = current(unpack('N', fread($this->fsock, 4)));
             $key_blob = fread($this->fsock, $length);
+            $key_str = 'ssh-rsa ' . base64_encode($key_blob);
             $length = current(unpack('N', fread($this->fsock, 4)));
-            $key_comment = fread($this->fsock, $length);
+            if ($length) {
+                $key_str.= ' ' . fread($this->fsock, $length);
+            }
             $length = current(unpack('N', substr($key_blob, 0, 4)));
             $key_type = substr($key_blob, 4, $length);
             switch ($key_type) {
@@ -292,7 +356,7 @@ class System_SSH_Agent
                         include_once 'Crypt/RSA.php';
                     }
                     $key = new Crypt_RSA();
-                    $key->loadKey('ssh-rsa ' . base64_encode($key_blob) . ' ' . $key_comment);
+                    $key->loadKey($key_str);
                     break;
                 case 'ssh-dss':
                     // not currently supported
@@ -310,4 +374,113 @@ class System_SSH_Agent
 
         return $identities;
     }
+
+    /**
+     * Signal that agent forwarding should
+     * be requested when a channel is opened
+     *
+     * @param Net_SSH2 $ssh
+     * @return bool
+     * @access public
+     */
+    function startSSHForwarding($ssh)
+    {
+        if ($this->forward_status == SYSTEM_SSH_AGENT_FORWARD_NONE) {
+            $this->forward_status = SYSTEM_SSH_AGENT_FORWARD_REQUEST;
+        }
+    }
+
+    /**
+     * Request agent forwarding of remote server
+     *
+     * @param Net_SSH2 $ssh
+     * @return bool
+     * @access private
+     */
+    function _request_forwarding($ssh)
+    {
+        $request_channel = $ssh->_get_open_channel();
+        if ($request_channel === false) {
+            return false;
+        }
+
+        $packet = pack(
+            'CNNa*C',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $ssh->server_channels[$request_channel],
+            strlen('auth-agent-req@openssh.com'),
+            'auth-agent-req@openssh.com',
+            1
+        );
+
+        $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+        if (!$ssh->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $response = $ssh->_get_channel_packet($request_channel);
+        if ($response === false) {
+            return false;
+        }
+
+        $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN;
+        $this->forward_status = SYSTEM_SSH_AGENT_FORWARD_ACTIVE;
+
+        return true;
+    }
+
+    /**
+     * On successful channel open
+     *
+     * This method is called upon successful channel
+     * open to give the SSH Agent an opportunity
+     * to take further action. i.e. request agent forwarding
+     *
+     * @param Net_SSH2 $ssh
+     * @access private
+     */
+    function _on_channel_open($ssh)
+    {
+        if ($this->forward_status == SYSTEM_SSH_AGENT_FORWARD_REQUEST) {
+            $this->_request_forwarding($ssh);
+        }
+    }
+
+    /**
+     * Forward data to SSH Agent and return data reply
+     *
+     * @param string $data
+     * @return data from SSH Agent
+     * @access private
+     */
+    function _forward_data($data)
+    {
+        if ($this->expected_bytes > 0) {
+            $this->socket_buffer.= $data;
+            $this->expected_bytes -= strlen($data);
+        } else {
+            $agent_data_bytes = current(unpack('N', $data));
+            $current_data_bytes = strlen($data);
+            $this->socket_buffer = $data;
+            if ($current_data_bytes != $agent_data_bytes + 4) {
+                $this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes;
+                return false;
+            }
+        }
+
+        if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
+            user_error('Connection closed attempting to forward data to SSH agent');
+        }
+
+        $this->socket_buffer = '';
+        $this->expected_bytes = 0;
+
+        $agent_reply_bytes = current(unpack('N', fread($this->fsock, 4)));
+
+        $agent_reply_data = fread($this->fsock, $agent_reply_bytes);
+        $agent_reply_data = current(unpack('a*', $agent_reply_data));
+
+        return pack('Na*', $agent_reply_bytes, $agent_reply_data);
+    }
 }
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php b/civicrm/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php
new file mode 100644
index 0000000000000000000000000000000000000000..0da0999fd210da027eeb1bc49ba975a7ff6e11ae
--- /dev/null
+++ b/civicrm/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Bootstrapping File for phpseclib
+ *
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ */
+
+if (extension_loaded('mbstring')) {
+    // 2 - MB_OVERLOAD_STRING
+    if (ini_get('mbstring.func_overload') & 2) {
+        throw new \UnexpectedValueException(
+            'Overloading of string functions using mbstring.func_overload ' .
+            'is not supported by phpseclib.'
+        );
+    }
+}
diff --git a/civicrm/vendor/phpseclib/phpseclib/phpunit.xml.dist b/civicrm/vendor/phpseclib/phpseclib/phpunit.xml.dist
deleted file mode 100644
index 09f8b8ffba11eca5c1ab41b9504f8a122bfca1fd..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/phpunit.xml.dist
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<phpunit bootstrap="tests/bootstrap.php"
-         colors="true"
->
-    <testsuites>
-        <testsuite name="phpseclib Unit Test Suite">
-            <directory>./tests/Unit/</directory>
-        </testsuite>
-        <testsuite name="phpseclib Functional Test Suite">
-            <directory>./tests/Functional/</directory>
-        </testsuite>
-    </testsuites>
-
-    <!-- Code Coverage -->
-    <filter>
-        <whitelist>
-            <directory>./phpseclib/</directory>
-        </whitelist>
-    </filter>
-</phpunit>
diff --git a/civicrm/vendor/phpseclib/phpseclib/travis/code_coverage_id_rsa b/civicrm/vendor/phpseclib/phpseclib/travis/code_coverage_id_rsa
deleted file mode 100644
index 25d4094cebefc2314965787d3448d34490baffa0..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/travis/code_coverage_id_rsa
+++ /dev/null
@@ -1,30 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: AES-128-CBC,2F15FCF0B21FCFB5A37D709322F9B9EB
-
-JpGgJqRnr0+3mHQoeYXXUzSWeA1wGwMzm6KOPnQLEmA9ztPlBQulzZRh6QJckCwy
-TC7BMo+XRnYVXF3e0rjji0k7cfEk5Gs8saNcxxOa0u0SUOCXelGnZeqzwiT0a6Fe
-qAc7NLgTEo9zul9s+MHsplkVk71Oke+1dL7kksMRT0TdXIaqSvk/+nyAeLzAot04
-wo61T3+Y7/v/8oVxlCbxI5YfYZkm/4jTy7AfbXZBvC0R+F0ZYvIDRCuBe6h6XvcH
-AiYtw5+Qek6FwIa2CFVxsefvsEnZQYaiJpEFAq2xVHlTjQHHYrfd5cgu1koUNsAt
-nX1zpsK7tIregXFa07KfDaBBPxfEBqVJQInzj0Rc8HUt0AZ+MrPldrZ28+YQ4RXk
-/qk5UyKkdHMSKBb4va3mxcpDq1As9HREfeUeOjjduRh1LnNQCJaOhydXBqCFvhFy
-+Q9utDXP6q4OUxeDHCPGQ7K1I7erwiwuTeSXB3BEDZyZywHXABvJpsidkDlD/aNo
-QmM19V8y0IAxEAZvc8N0MIOO8hmd8R9U1RK4S24o9M8mgRrmuXjViJjZd5E3h6tX
-Mgxm8dpOiT77i+NsJwyp2A+MhkAHg2ruwlCIrSCC81zvdphVTfuc/vx3JpXYvhTP
-Xf9R8ppGnDUFauroN7E7odJKDhLVuAbmU1lWwue2iaNEKZ3L/o9dpRz4Td4NzzSf
-HKvKbJR35FCsqZq2krmNVd6ynF5PzWfYmz850yn/qdU8zwnW0fV+iHKS2oXuH9X1
-ZW02/MDdCylpRftNJMntR4Yxim7WEZ5Dif9ZLj8IGRQdWbbIn0WjtiVrFrcUbIfk
-TCP/3GeEcUa/XbE9hO9APw+7rO3sOehGJ84n4tXxFTFSnOJ5ZxTKpLvxRrmC8DaD
-cvqy8bbjPfn1EjZmRpCjanLZ1UJbLitFfpUT55aTrcozS4FMHmFm74X2xZGeBhxC
-CpWQe/agxhWxG+ZXdxt9ExI78ftQCQoGE0Si1KZXH5KQ/xiGmebY9wbtEHWG+q25
-sKqvjQHQsE3NZq7kne3mnyvjzMDDFYPLDlQLgcKInNrLZ3GszyemtzqcVf3YVur4
-N+nN0gu6LCx0vtw3yNRqjjmGN1V6sKMCqmIAtFDh9zRTlDTs7ZUBGPgakmmJLLVM
-ESme0JrRxCP+eEU8JNti9pKlKPGOFVpu4shLjmnmKuDpOytFNpcB/NylkGwZCxvE
-1KI+EQMZOE5VROAfkvwBLE0SsVxMq7H87zSEOtOqr+QN8RoY1V6N/woBVWda9GFk
-HI44PM2ZywQbLGthaQV/Kxwf9YZruJdunNoTfEufZgv2Vp+3VAs+gCTGIsbblTnH
-J8QGfs/lHRBqK1pMZrYy0ubFqifA+b9Xa6VJWToCgcQuWbOVWn1zKQTTXZPksVbB
-qyE8BJkQCDGgoeq4kdxm0XUR5p3UZWQv0HoykQt33U06TCzU9HOcp0z+Glhrzsvd
-rbNBhRK0zXF/BFSNBHwKEg02TNlj7gSFJXmvZqvyCAFo5D6nSDbzqm6ARuscsrF0
-6Zd3toOZTWmrVsKvTlsNPfHXyoGqP3+0NXcTY+kKXG58u4TbEtw8pVyPikuVdh/m
------END RSA PRIVATE KEY-----
diff --git a/civicrm/vendor/phpseclib/phpseclib/travis/install-php-extensions.sh b/civicrm/vendor/phpseclib/phpseclib/travis/install-php-extensions.sh
deleted file mode 100755
index 2acfdfd7581aea23bc08b04e53ea2e1d67aa080f..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/travis/install-php-extensions.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-#
-# This file is part of the phpseclib project.
-#
-# (c) Andreas Fischer <bantu@phpbb.com>
-#
-# For the full copyright and license information, please view the LICENSE
-# file that was distributed with this source code.
-#
-set -e
-
-function install_php_extension
-{
-    cd "$1"
-    phpize
-    ./configure
-    make
-    make install
-    cd ..
-    echo "extension=$1.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
-}
-
-# runkit
-if [ "$TRAVIS_PHP_VERSION" == "5.6" ]
-then
-    git clone https://github.com/adrianguenter/runkit.git
-else
-    git clone https://github.com/zenovich/runkit.git
-fi
-install_php_extension 'runkit'
diff --git a/civicrm/vendor/phpseclib/phpseclib/travis/run-phpunit.sh b/civicrm/vendor/phpseclib/phpseclib/travis/run-phpunit.sh
deleted file mode 100755
index 600a1d94c03a24f9f5eb9d69c8c2cd136e2e3871..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/travis/run-phpunit.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-set -e
-set -x
-
-export PHPSECLIB_SSH_HOSTNAME='localhost'
-export PHPSECLIB_SSH_USERNAME='phpseclib'
-export PHPSECLIB_SSH_PASSWORD='EePoov8po1aethu2kied1ne0'
-export PHPSECLIB_SSH_HOME='/home/phpseclib'
-
-if [ "$TRAVIS_PHP_VERSION" = '5.2' ]
-then
-  PHPUNIT="phpunit"
-else
-  PHPUNIT="$(dirname "$0")/../vendor/bin/phpunit"
-fi
-
-PHPUNIT_ARGS='--verbose'
-if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.4', '<');"` = "1" ]
-then
-  PHPUNIT_ARGS="$PHPUNIT_ARGS -d zend.enable_gc=0"
-fi
-
-if [ "$TRAVIS_PHP_VERSION" = 'hhvm' ]
-then
-  find tests -type f -name "*Test.php" | \
-    parallel --gnu --keep-order \
-      "echo '== {} =='; \"$PHPUNIT\" $PHPUNIT_ARGS {};"
-else
-  "$PHPUNIT" \
-    $PHPUNIT_ARGS \
-    --coverage-text \
-    --coverage-clover code_coverage/clover.xml \
-    --coverage-html code_coverage/
-fi
diff --git a/civicrm/vendor/phpseclib/phpseclib/travis/setup-composer.sh b/civicrm/vendor/phpseclib/phpseclib/travis/setup-composer.sh
deleted file mode 100755
index 3416074cc51f75be5ce0afc74e1703ba2778daf9..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/travis/setup-composer.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-composer self-update --no-interaction
-composer install --no-interaction
diff --git a/civicrm/vendor/phpseclib/phpseclib/travis/setup-secure-shell.sh b/civicrm/vendor/phpseclib/phpseclib/travis/setup-secure-shell.sh
deleted file mode 100755
index fdcaaa0dc5fd4429b3f9ffee99e0a03b9e79875b..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/travis/setup-secure-shell.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-#
-# This file is part of the phpseclib project.
-#
-# (c) Andreas Fischer <bantu@phpbb.com>
-#
-# For the full copyright and license information, please view the LICENSE
-# file that was distributed with this source code.
-#
-set -e
-set -x
-
-USERNAME='phpseclib'
-PASSWORD='EePoov8po1aethu2kied1ne0'
-
-# Create phpseclib user and home directory
-sudo useradd --create-home --base-dir /home "$USERNAME"
-
-# Set phpseclib user password
-echo "$USERNAME:$PASSWORD" | sudo chpasswd
-
-# Create a 1024 bit RSA SSH key pair without passphrase for the travis user
-ssh-keygen -t rsa -b 1024 -f "$HOME/.ssh/id_rsa" -q -N ""
-
-# Add the generated private key to SSH agent of travis user
-ssh-add "$HOME/.ssh/id_rsa"
-
-# Allow the private key of the travis user to log in as phpseclib user
-sudo mkdir -p "/home/$USERNAME/.ssh/"
-sudo cp "$HOME/.ssh/id_rsa.pub" "/home/$USERNAME/.ssh/authorized_keys"
-sudo chown "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh/" -R
diff --git a/civicrm/vendor/phpseclib/phpseclib/travis/upload-code-coverage-html.sh b/civicrm/vendor/phpseclib/phpseclib/travis/upload-code-coverage-html.sh
deleted file mode 100755
index 668fb6a285d43f9ada4a7fc7b7c5529c091a4547..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/travis/upload-code-coverage-html.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/sh
-#
-# This file is part of the phpseclib project.
-#
-# (c) Andreas Fischer <bantu@phpbb.com>
-#
-# For the full copyright and license information, please view the LICENSE
-# file that was distributed with this source code.
-#
-
-USERNAME='phpseclib'
-HOSTNAME='phpseclib.bantux.org'
-HOSTRSAF='09:40:96:14:6a:cd:67:46:17:e5:b4:39:24:24:6e:9d'
-LDIRNAME='code_coverage'
-RDIRNAME='code_coverage'
-ID_RSA='travis/code_coverage_id_rsa'
-
-# Install expect if necessary
-if ! which expect > /dev/null
-then
-	sudo apt-get update -qq
-	sudo apt-get install -qq expect
-fi
-
-# Workaround for rsync not creating target directories with depth > 1
-mv "$LDIRNAME" "x$LDIRNAME"
-RROOT="$RDIRNAME/$TRAVIS_BRANCH/$TRAVIS_BUILD_NUMBER"
-mkdir -p "$RROOT"
-mv "x$LDIRNAME" "$RROOT/PHP-$TRAVIS_PHP_VERSION/"
-
-# Update latest symlink
-ln -s "$TRAVIS_BUILD_NUMBER" "$RDIRNAME/$TRAVIS_BRANCH/latest"
-
-# Stop complaints about world-readable key file.
-chmod 600 "$ID_RSA"
-
-export RSYNC_RSH="ssh -4 -i $ID_RSA -o ConnectTimeout=5"
-RSYNC_OPT="--recursive --times --links --progress"
-
-expect << EOF
-	spawn rsync $RSYNC_OPT "$RDIRNAME/" "$USERNAME@$HOSTNAME:$RDIRNAME/"
-
-	expect "RSA key fingerprint is $HOSTRSAF."
-	send "yes\n"
-
-	expect "Enter passphrase for key '$ID_RSA':"
-	send "$CODE_COVERAGE_PASSPHRASE\n"
-
-	expect eof
-EOF
diff --git a/civicrm/vendor/phpseclib/phpseclib/travis/upload-code-coverage-scrutinizer.sh b/civicrm/vendor/phpseclib/phpseclib/travis/upload-code-coverage-scrutinizer.sh
deleted file mode 100755
index efcff08c88d0e972fc9b13909c410d5bdd7df73a..0000000000000000000000000000000000000000
--- a/civicrm/vendor/phpseclib/phpseclib/travis/upload-code-coverage-scrutinizer.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-#
-# This file is part of the phpseclib project.
-#
-# (c) Andreas Fischer <bantu@phpbb.com>
-#
-# For the full copyright and license information, please view the LICENSE
-# file that was distributed with this source code.
-#
-set -e
-
-wget https://scrutinizer-ci.com/ocular.phar
-php ocular.phar code-coverage:upload --format=php-clover code_coverage/clover.xml