commit 7707c01358af75321c257226b26a7c379b45aaf4
Author: Assos Assos <assos+forge@centrale-marseille.fr>
Date:   Thu Jul 16 20:29:01 2015 +0200

    Update Feeds JSONPath Parser 7.x-1.0-beta2 -> 7.x-1.0

diff --git a/drupal7/sites/all/modules/feeds_jsonpath_parser/FeedsJSONPathParser.inc b/drupal7/sites/all/modules/feeds_jsonpath_parser/FeedsJSONPathParser.inc
index ea9c1e72..47f12d10 100644
--- a/drupal7/sites/all/modules/feeds_jsonpath_parser/FeedsJSONPathParser.inc
+++ b/drupal7/sites/all/modules/feeds_jsonpath_parser/FeedsJSONPathParser.inc
@@ -1,23 +1,34 @@
 <?php
-// $Id: FeedsJSONPathParser.inc,v 1.1.2.4.2.4 2011/02/05 19:28:01 twistor Exp $
 
 /**
  * @file
- *
- * Provides the Class for Feeds JSONPath Parser.
+ * Contains FeedsJSONPathParser.
  */
 
 /**
- * Base class for the HTML and XML parsers.
+ * Parses JSON using JSONPath.
  */
 class FeedsJSONPathParser extends FeedsParser {
 
   /**
-   * Implementation of FeedsParser::parse().
+   * A regular expression that finds four byte UTF-8 chars.
+   *
+   * @var string
+   */
+  protected static $fourByteRegex = '/(?:\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})/s';
+
+  /**
+   * The source fields to debug.
+   *
+   * @var array
+   */
+  protected $debug = array();
+
+  /**
+   * Implements FeedsParser::parse().
    */
   public function parse(FeedsSource $source, FeedsFetcherResult $fetcher_result) {
-    $mappings = $source->importer->processor->config['mappings'];
-    $mappings = $this->filterMappings($mappings);
+    $mappings = $this->getOwnMappings();
     $source_config = $source->getConfigFor($this);
     // Allow config inheritance.
     if (empty($source_config)) {
@@ -40,54 +51,74 @@ class FeedsJSONPathParser extends FeedsParser {
       $array = json_decode($raw, TRUE);
     }
 
-    if (is_array($array)) {
-      require_once 'jsonpath-0.8.1.php';
-
-      $all_items = $this->jsonPath($array, $source_config['context']);
-      $this->debug($all_items, 'context');
-      unset($array);
-
-      foreach ($all_items as $item) {
-        $parsed_item = $variables = array();
-        foreach ($source_config['sources'] as $source => $query) {
-          $parsed = $this->parseSourceElement($item, $query, $source);
-          // Avoid null values.
-          if (isset($parsed)) {
-            // Variable sunstitution can't handle arrays.
-            if (!is_array($parsed)) {
-              $variables['{' . $mappings[$source] . '}'] = $parsed;
-            }
-            else {
-              $variables['{' . $mappings[$source] . '}'] = '';
-            }
-            $parsed_item[$source] = $parsed;
-          }
+    if (!is_array($array)) {
+      throw new Exception(t('There was an error decoding the JSON document.'));
+    }
+    require_once feeds_jsonpath_parser_library_path();
+
+    $all_items = $this->jsonPath($array, $source_config['context']);
+    unset($array);
+
+    // Batch.
+    $state = $source->state(FEEDS_PARSE);
+    if (!$state->total) {
+      $state->total = count($all_items);
+    }
+
+    $start = (int) $state->pointer;
+    $state->pointer = $start + $source->importer->getLimit();
+    $all_items = array_slice($all_items, $start, $source->importer->getLimit());
+
+    // Set progress state.
+    $state->progress($state->total, $state->pointer);
+
+    // Debug output.
+    $this->debug($all_items, 'context');
+
+    foreach ($all_items as $item) {
+      // Invoke a hook to check whether the item should be skipped.
+      if ($this->invokeHook($item, $source) === TRUE) {
+        continue;
+      }
+
+      $parsed_item = $variables = array();
+      foreach ($source_config['sources'] as $source_key => $query) {
+        // Variable substitution.
+        $query = strtr($query, $variables);
+        $parsed = $this->parseSourceElement($item, $query, $source_key);
+
+        $variables['{' . $mappings[$source_key] . '}'] = is_array($parsed) ? reset($parsed) : $parsed;
+
+        // Avoid null values.
+        if (isset($parsed)) {
+          $parsed_item[$source_key] = $parsed;
         }
+      }
+      if (!empty($parsed_item)) {
         $result->items[] = $parsed_item;
       }
     }
-    else {
-      throw new Exception(t('There was an error decoding the JSON document.'));
-    }
     return $result;
   }
 
   /**
-   * Utilizes the jsonPath function from jsonpath-0.8.1.php
+   * Utilizes the jsonPath function from jsonpath-0.8.1.php.
    *
    * jsonPath returns false if the expression returns zero results and that will
    * mess up our for loops, so return an empty array instead.
    *
-   * @todo
-   *   Firgure out error handling.
-   * @param $array
-   *   The input array to parse
-   * @$expression
+   * @param array $array
+   *   The input array to parse.
+   * @param string $expression
    *   The JSONPath expression.
+   *
    * @return array
-   *   Returns an array that is the output of jsonPath
+   *   Returns an array that is the output of jsonPath.
+   *
+   * @todo
+   *   Firgure out error handling.
    */
-  private function jsonPath($array, $expression) {
+  protected function jsonPath($array, $expression) {
     $result = jsonPath($array, $expression);
     return ($result === FALSE) ? array() : $result;
   }
@@ -95,10 +126,13 @@ class FeedsJSONPathParser extends FeedsParser {
   /**
    * Parses one item from the context array.
    *
-   * @param $item
-   *   A PHP array.
-   * @param $query
+   * @param array $item
+   *   An array containing one item from the context.
+   * @param string $query
    *   A JSONPath query.
+   * @param string $source
+   *   The source element that corresponds to the query.
+   *
    * @return array
    *   An array containing the results of the query.
    */
@@ -108,18 +142,22 @@ class FeedsJSONPathParser extends FeedsParser {
     }
     $results = $this->jsonPath($item, $query);
     $this->debug($results, $source);
-    unset($item);
-
-    /**
-     * If there is one result, return it directly.  If there are no results,
-     * return. Otherwise return the results.
-     */
-    if (count($results) === 1) {
-      return $results[0];
-    }
-    if (count($results) === 0) {
+
+    $count = count($results);
+    if ($count === 0) {
       return;
     }
+
+    foreach ($results as $delta => $value) {
+      if (is_string($value) && $value !== '') {
+        $results[$delta] = !empty($this->config['convert_four_byte']) ? $this->convertFourBytes($value) : $this->stripFourBytes($value);
+      }
+    }
+
+    if ($count === 1) {
+      return reset($results);
+    }
+
     return $results;
   }
 
@@ -132,6 +170,13 @@ class FeedsJSONPathParser extends FeedsParser {
     if (empty($source_config)) {
       $source_config = $this->config;
     }
+
+    if (isset($source_config['allow_override']) &&
+        !$source_config['allow_override'] &&
+        empty($source_config['config'])) {
+      return;
+    }
+
     // Add extensions that might get importerd.
     $fetcher = feeds_importer($this->id)->fetcher;
     if (isset($fetcher->config['allowed_extensions'])) {
@@ -145,7 +190,7 @@ class FeedsJSONPathParser extends FeedsParser {
     foreach ($mappings_ as $mapping) {
       if (strpos($mapping['source'], 'jsonpath_parser:') === 0) {
         $mappings[$mapping['source']] = $mapping['target'];
-        if ($mapping['unique']) {
+        if (!empty($mapping['unique'])) {
           $uniques[] = $mapping['target'];
         }
       }
@@ -158,7 +203,16 @@ class FeedsJSONPathParser extends FeedsParser {
       '#tree' => TRUE,
     );
     if (empty($mappings)) {
-      $form['jsonpath']['error_message']['#markup'] = t('FeedsJSONPathParser: No mappings were defined.');
+      // Detect if Feeds menu structure has changed. This will take a while to
+      // be released, but since I run dev it needs to work.
+      $feeds_menu = feeds_ui_menu();
+      if (isset($feeds_menu['admin/structure/feeds/list'])) {
+        $feeds_base = 'admin/structure/feeds/edit/';
+      }
+      else {
+        $feeds_base = 'admin/structure/feeds/';
+      }
+      $form['jsonpath']['error_message']['#markup'] = '<div class="help">' . t('No JSONPath mappings are defined. Define mappings !link.', array('!link' => l(t('here'), $feeds_base . $this->id . '/mapping'))) . '</div><br />';
       return $form;
     }
     $form['jsonpath']['context'] = array(
@@ -194,7 +248,11 @@ class FeedsJSONPathParser extends FeedsParser {
         '#size' => 80,
       );
       if (!empty($variables)) {
-        $form['jsonpath']['sources'][$source]['#description'] .= '<br>' . t('The variables '. implode(', ', $variables). ' are availliable for replacement.');
+        $variable_text = format_plural(count($variables),
+          t('The variable %v is available for replacement.', array('%v' => implode(', ', $variables))),
+          t('The variables %v are available for replacement.', array('%v' => implode(', ', $variables)))
+        );
+        $form['jsonpath']['sources'][$source]['#description'] .= '<br />' . $variable_text;
       }
       $variables[] = '{' . $target . '}';
     }
@@ -217,27 +275,49 @@ class FeedsJSONPathParser extends FeedsParser {
    * Override parent::configForm().
    */
   public function configForm(&$form_state) {
-    $form = $this->sourceForm($this->config);
+    $config = $this->getConfig();
+    $config['config'] = TRUE;
+    $form = $this->sourceForm($config);
     $form['jsonpath']['context']['#required'] = FALSE;
     $form['jsonpath']['#collapsed'] = FALSE;
+    $form['jsonpath']['allow_override'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Allow source configuration override'),
+      '#description' => t('This setting allows feed nodes to specify their own JSONPath values for the context and sources.'),
+      '#default_value' => $config['allow_override'],
+    );
+    $form['jsonpath']['convert_four_byte'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Convert four byte characters'),
+      '#description' => t('Coverts four byte UTF-8 characters to their HTML entity. By default, four byte characters will be stripped.'),
+      '#default_value' => !empty($config['convert_four_byte']),
+    );
+
     return $form;
   }
 
   /**
-  * Override parent::getMappingSources().
-  */
+   * Override parent::getMappingSources().
+   */
   public function getMappingSources() {
     $mappings = $this->filterMappings(feeds_importer($this->id)->processor->config['mappings']);
     $next = 0;
     if (!empty($mappings)) {
-      $last_mapping = end(array_keys($mappings));
-      $next = explode(':', $last_mapping);
-      $next = $next[1] + 1;
+      $keys = array_keys($mappings);
+
+      $nums = array();
+      foreach ($keys as $key) {
+        list(, $num) = explode(':', $key);
+        $nums[] = $num;
+      }
+
+      $max = max($nums);
+      $next = ++$max;
     }
     return array(
       'jsonpath_parser:' . $next => array(
         'name' => t('JSONPath Expression'),
-        'description' => t('Allows you to configure n JSONPath expression that will populate this field.'),
+        'description' => t('Allows you to configure a JSONPath expression that will populate this field.'),
       ),
     ) + parent::getMappingSources();
   }
@@ -254,6 +334,8 @@ class FeedsJSONPathParser extends FeedsParser {
       'context' => '',
       'sources' => array(),
       'debug' => array(),
+      'allow_override' => FALSE,
+      'convert_four_byte' => FALSE,
     );
   }
 
@@ -263,14 +345,18 @@ class FeedsJSONPathParser extends FeedsParser {
    * If the values of this source are the same as the base config we set them to
    * blank to that the values will be inherited from the importer defaults.
    *
-   * @param &$values
+   * @param array $values
    *   The values from the form to validate, passed by reference.
    */
   public function sourceFormValidate(&$values) {
+    $config = $this->getConfig();
     $values = $values['jsonpath'];
-    asort($values);
-    asort($this->config);
-    if ($values === $this->config) {
+    $allow_override = $config['allow_override'];
+    unset($config['allow_override']);
+    unset($config['convert_four_byte']);
+    ksort($values);
+    ksort($config);
+    if ($values === $config || !$allow_override) {
       $values = array();
       return;
     }
@@ -284,16 +370,36 @@ class FeedsJSONPathParser extends FeedsParser {
     if (isset($values['jsonpath'])) {
       $values = $values['jsonpath'];
     }
-    $values['context'] = trim($values['context']);
-    foreach ($values['sources'] as &$source) {
-      $source = trim($source);
+
+    $values['context'] = isset($values['context']) ? trim($values['context']) : '';
+    if (!empty($values['sources'])) {
+      foreach ($values['sources'] as &$source) {
+        $source = trim($source);
+      }
     }
   }
 
+  /**
+   * Gets the mappings that belong to this parser.
+   *
+   * @return array
+   *   An array of mappings keyed source => target.
+   */
+  protected function getOwnMappings() {
+    $importer_config = feeds_importer($this->id)->getConfig();
+    return $this->filterMappings($importer_config['processor']['config']['mappings']);
+  }
+
   /**
    * Filters mappings, returning the ones that belong to us.
+   *
+   * @param array $mappings
+   *   A mapping array from a processor.
+   *
+   * @return array
+   *   An array of mappings keyed source => target.
    */
-  private function filterMappings($mappings) {
+  protected function filterMappings($mappings) {
     $our_mappings = array();
     foreach ($mappings as $mapping) {
       if (strpos($mapping['source'], 'jsonpath_parser:') === 0) {
@@ -303,7 +409,7 @@ class FeedsJSONPathParser extends FeedsParser {
     return $our_mappings;
   }
 
-  private function debug($item, $source) {
+  protected function debug($item, $source) {
     if (in_array($source, $this->debug)) {
       $o = '<ul>';
       foreach ($item as $i) {
@@ -313,4 +419,71 @@ class FeedsJSONPathParser extends FeedsParser {
       drupal_set_message($source . ':' . $o);
     }
   }
+
+  /**
+   * Calls our filter hook.
+   *
+   * @param array &$item
+   *   The item to alter.
+   * @param FeedsSource $source
+   *   The feed source.
+   * @return true|null
+   *   Returns true if the item should be skipped.
+   */
+  protected function invokeHook(array &$item, FeedsSource $source) {
+    foreach (module_implements('feeds_jsonpath_parser_filter') as $module) {
+      $function = $module . '_feeds_jsonpath_parser_filter';
+      if ($function($item, $source) === TRUE) {
+        return TRUE;
+      }
+    }
+  }
+
+  /**
+   * Strips four byte characters from a string.
+   *
+   * @param string $string
+   *   The input string.
+   *
+   * @return string
+   *   The string with four byte characters removed.
+   */
+  public static function stripFourBytes($string) {
+    return preg_replace(self::$fourByteRegex, '', $string);
+  }
+
+  /**
+   * Replaces four byte characters with their HTML unicode codepoint.
+   *
+   * @param string $string
+   *   The input string.
+   *
+   * @return string
+   *   The string with four byte characters converted.
+   */
+  public static function convertFourBytes($string) {
+    return preg_replace_callback(self::$fourByteRegex, array('FeedsJSONPathParser', 'doFourByteReplace'), $string);
+  }
+
+  /**
+   * Callback for FeedsJSONPathParser::convertFourBytes().
+   *
+   * @param array $matches
+   *   The regular expression matches.
+   *
+   * @return string
+   *   A four byte unicode character converted to its HTML representation.
+   */
+  public static function doFourByteReplace(array $matches) {
+    $char = $matches[0];
+
+    // Calculate the codepoint of the character.
+    $codepoint = ord($char[0]) - 0xF0 << 18;
+    $codepoint += ord($char[1]) - 0x80 << 12;
+    $codepoint += ord($char[2]) - 0x80 << 6;
+    $codepoint += ord($char[3]) - 0x80;
+
+    return '&#' . $codepoint . ';';
+  }
+
 }
diff --git a/drupal7/sites/all/modules/feeds_jsonpath_parser/LICENSE.txt b/drupal7/sites/all/modules/feeds_jsonpath_parser/LICENSE.txt
index 2c095c8d..d159169d 100644
--- a/drupal7/sites/all/modules/feeds_jsonpath_parser/LICENSE.txt
+++ b/drupal7/sites/all/modules/feeds_jsonpath_parser/LICENSE.txt
@@ -1,274 +1,339 @@
-GNU GENERAL PUBLIC LICENSE
-
-              Version 2, June 1991
-
-Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,
-Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute
-verbatim copies of this license document, but changing it is not allowed.
-
-                  Preamble
-
-The licenses for most software are designed to take away your freedom to
-share and change it. By contrast, the GNU General Public License is
-intended to guarantee your freedom to share and change free software--to
-make sure the software is free for all its users. This General Public License
-applies to most of the Free Software Foundation's software and to any other
-program whose authors commit to using it. (Some other Free Software
-Foundation software is covered by the GNU Library General Public License
-instead.) You can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the
-freedom to distribute copies of free software (and charge for this service if
-you wish), that you receive source code or can get it if you want it, that you
-can change the software or use pieces of it in new free programs; and that
-you know you can do these things.
-
-To protect your rights, we need to make restrictions that forbid anyone to
-deny you these rights or to ask you to surrender the rights. These restrictions
-translate to certain responsibilities for you if you distribute copies of the
-software, or if you modify it.
-
-For example, if you distribute copies of such a program, whether gratis or for
-a fee, you must give the recipients all the rights that you have. You must make
-sure that they, too, receive or can get the source code. And you must show
-them these terms so they know their rights.
-
-We protect your rights with two steps: (1) copyright the software, and (2)
-offer you this license which gives you legal permission to copy, distribute
-and/or modify the software.
-
-Also, for each author's protection and ours, we want to make certain that
-everyone understands that there is no warranty for this free software. If the
-software is modified by someone else and passed on, we want its recipients
-to know that what they have is not the original, so that any problems
-introduced by others will not reflect on the original authors' reputations.
-
-Finally, any free program is threatened constantly by software patents. We
-wish to avoid the danger that redistributors of a free program will individually
-obtain patent licenses, in effect making the program proprietary. To prevent
-this, we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
-           GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
-               MODIFICATION
-
-0. This License applies to any program or other work which contains a notice
-placed by the copyright holder saying it may be distributed under the terms
-of this General Public License. The "Program", below, refers to any such
-program or work, and a "work based on the Program" means either the
-Program or any derivative work under copyright law: that is to say, a work
-containing the Program or a portion of it, either verbatim or with
-modifications and/or translated into another language. (Hereinafter, translation
-is included without limitation in the term "modification".) Each licensee is
-addressed as "you".
-
-Activities other than copying, distribution and modification are not covered
-by this License; they are outside its scope. The act of running the Program is
-not restricted, and the output from the Program is covered only if its contents
-constitute a work based on the Program (independent of having been made
-by running the Program). Whether that is true depends on what the Program
-does.
-
-1. You may copy and distribute verbatim copies of the Program's source
-code as you receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice and
-disclaimer of warranty; keep intact all the notices that refer to this License
-and to the absence of any warranty; and give any other recipients of the
-Program a copy of this License along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and you
-may at your option offer warranty protection in exchange for a fee.
-
-2. You may modify your copy or copies of the Program or any portion of it,
-thus forming a work based on the Program, and copy and distribute such
-modifications or work under the terms of Section 1 above, provided that you
-also meet all of these conditions:
-
-a) You must cause the modified files to carry prominent notices stating that
-you changed the files and the date of any change.
-
-b) You must cause any work that you distribute or publish, that in whole or in
-part contains or is derived from the Program or any part thereof, to be
-licensed as a whole at no charge to all third parties under the terms of this
-License.
-
-c) If the modified program normally reads commands interactively when run,
-you must cause it, when started running for such interactive use in the most
-ordinary way, to print or display an announcement including an appropriate
-copyright notice and a notice that there is no warranty (or else, saying that
-you provide a warranty) and that users may redistribute the program under
-these conditions, and telling the user how to view a copy of this License.
-(Exception: if the Program itself is interactive but does not normally print such
-an announcement, your work based on the Program is not required to print
-an announcement.)
-
-These requirements apply to the modified work as a whole. If identifiable
-sections of that work are not derived from the Program, and can be
-reasonably considered independent and separate works in themselves, then
-this License, and its terms, do not apply to those sections when you distribute
-them as separate works. But when you distribute the same sections as part
-of a whole which is a work based on the Program, the distribution of the
-whole must be on the terms of this License, whose permissions for other
-licensees extend to the entire whole, and thus to each and every part
-regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest your rights to
-work written entirely by you; rather, the intent is to exercise the right to
-control the distribution of derivative or collective works based on the
-Program.
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
 
 In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of a
-storage or distribution medium does not bring the other work under the scope
-of this License.
-
-3. You may copy and distribute the Program (or a work based on it, under
-Section 2) in object code or executable form under the terms of Sections 1
-and 2 above provided that you also do one of the following:
-
-a) Accompany it with the complete corresponding machine-readable source
-code, which must be distributed under the terms of Sections 1 and 2 above
-on a medium customarily used for software interchange; or,
-
-b) Accompany it with a written offer, valid for at least three years, to give
-any third party, for a charge no more than your cost of physically performing
-source distribution, a complete machine-readable copy of the corresponding
-source code, to be distributed under the terms of Sections 1 and 2 above on
-a medium customarily used for software interchange; or,
-
-c) Accompany it with the information you received as to the offer to distribute
-corresponding source code. (This alternative is allowed only for
-noncommercial distribution and only if you received the program in object
-code or executable form with such an offer, in accord with Subsection b
-above.)
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
 
 The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source code
-means all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation and
-installation of the executable. However, as a special exception, the source
-code distributed need not include anything that is normally distributed (in
-either source or binary form) with the major components (compiler, kernel,
-and so on) of the operating system on which the executable runs, unless that
-component itself accompanies the executable.
-
-If distribution of executable or object code is made by offering access to
-copy from a designated place, then offering equivalent access to copy the
-source code from the same place counts as distribution of the source code,
-even though third parties are not compelled to copy the source along with the
-object code.
-
-4. You may not copy, modify, sublicense, or distribute the Program except as
-expressly provided under this License. Any attempt otherwise to copy,
-modify, sublicense or distribute the Program is void, and will automatically
-terminate your rights under this License. However, parties who have received
-copies, or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-5. You are not required to accept this License, since you have not signed it.
-However, nothing else grants you permission to modify or distribute the
-Program or its derivative works. These actions are prohibited by law if you
-do not accept this License. Therefore, by modifying or distributing the
-Program (or any work based on the Program), you indicate your acceptance
-of this License to do so, and all its terms and conditions for copying,
-distributing or modifying the Program or works based on it.
-
-6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the original
-licensor to copy, distribute or modify the Program subject to these terms and
-conditions. You may not impose any further restrictions on the recipients'
-exercise of the rights granted herein. You are not responsible for enforcing
-compliance by third parties to this License.
-
-7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues), conditions
-are imposed on you (whether by court order, agreement or otherwise) that
-contradict the conditions of this License, they do not excuse you from the
-conditions of this License. If you cannot distribute so as to satisfy
-simultaneously your obligations under this License and any other pertinent
-obligations, then as a consequence you may not distribute the Program at all.
-For example, if a patent license would not permit royalty-free redistribution
-of the Program by all those who receive copies directly or indirectly through
-you, then the only way you could satisfy both it and this License would be to
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
 refrain entirely from distribution of the Program.
 
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply and
-the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any patents or
-other property right claims or to contest validity of any such claims; this
-section has the sole purpose of protecting the integrity of the free software
-distribution system, which is implemented by public license practices. Many
-people have made generous contributions to the wide range of software
-distributed through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing to
-distribute software through any other system and a licensee cannot impose
-that choice.
-
-This section is intended to make thoroughly clear what is believed to be a
-consequence of the rest of this License.
-
-8. If the distribution and/or use of the Program is restricted in certain
-countries either by patents or by copyrighted interfaces, the original copyright
-holder who places the Program under this License may add an explicit
-geographical distribution limitation excluding those countries, so that
-distribution is permitted only in or among countries not thus excluded. In such
-case, this License incorporates the limitation as if written in the body of this
-License.
-
-9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will be
-similar in spirit to the present version, but may differ in detail to address new
-problems or concerns.
-
-Each version is given a distinguishing version number. If the Program specifies
-a version number of this License which applies to it and "any later version",
-you have the option of following the terms and conditions either of that
-version or of any later version published by the Free Software Foundation. If
-the Program does not specify a version number of this License, you may
-choose any version ever published by the Free Software Foundation.
-
-10. If you wish to incorporate parts of the Program into other free programs
-whose distribution conditions are different, write to the author to ask for
-permission. For software which is copyrighted by the Free Software
-Foundation, write to the Free Software Foundation; we sometimes make
-exceptions for this. Our decision will be guided by the two goals of
-preserving the free status of all derivatives of our free software and of
-promoting the sharing and reuse of software generally.
-
-               NO WARRANTY
-
-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE,
-THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT
-PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
-STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
-WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
-PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
-NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
-AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR
-ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
-LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
-SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
-ARISING OUT OF THE USE OR INABILITY TO USE THE
-PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
-OR DATA BEING RENDERED INACCURATE OR LOSSES
-SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
-PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN
-IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.
-
-          END OF TERMS AND CONDITIONS
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.api.php b/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.api.php
new file mode 100644
index 00000000..94e5b856
--- /dev/null
+++ b/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.api.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Documentation of Feeds JSONPath parser hooks.
+ */
+
+ /**
+  * Allows filtering or modifying a feed item.
+  *
+  * @param array &$item
+  *   The feed item to modify.
+  *
+  * @return bool
+  *   Returns true if the item should be skipped.
+  */
+ function hook_feeds_jsonpath_parser_filter(array &$item, FeedsSource $source) {
+   // Check for the importer.
+   if ($source->id  != 'my_importer') {
+     return;
+   }
+   // 1) Alter the items array.
+   $item['title'] = 'A hard coded title';
+
+   // 2) Return TRUE which will cause this item to be skipped.
+   if ($item['title'] == 'An item I would like to skip.') {
+     return TRUE;
+   }
+ }
diff --git a/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.info b/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.info
index 7b8ed5c7..8e8bca9e 100644
--- a/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.info
+++ b/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.info
@@ -1,14 +1,14 @@
-; $Id: feeds_jsonpath_parser.info,v 1.1.4.2 2011/02/05 18:12:18 twistor Exp $
-name = Feeds JSONPath Parser
+name = JSONPath Parser
 description = Parse a JSON document using JSONPath.
 files[] = tests/feeds_jsonpath_parser.test
+files[] = FeedsJSONPathParser.inc
 package = Feeds
 dependencies[] = feeds
 core = 7.x
 
-; Information added by drupal.org packaging script on January 1, 1970 - 00:00
-version = "7.x-1.0-beta2"
+; Information added by Drupal.org packaging script on 2015-06-25
+version = "7.x-1.0"
 core = "7.x"
 project = "feeds_jsonpath_parser"
-datestamp = "1296934371"
+datestamp = "1435272784"
 
diff --git a/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.install b/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.install
index ebd10b6a..317189f0 100644
--- a/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.install
+++ b/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.install
@@ -1,5 +1,4 @@
 <?php
-// $Id: feeds_jsonpath_parser.install,v 1.1.2.1 2010/09/28 20:18:46 twistor Exp $
 
 /**
  * @file
@@ -7,27 +6,34 @@
  */
 
 /**
- * Implementation of hook_requirements().
+ * Implements hook_requirements().
  */
 function feeds_jsonpath_parser_requirements($phase) {
   $requirements = array();
 
-  if ($phase == 'install') {
-    $t = get_t();
-    $requirements['feeds_jsonpath_parser']['title'] = $t('Feeds JSONPath Parser');
-
-    if (file_exists(dirname(__FILE__) . '/jsonpath-0.8.1.php')) {
-      $requirements['feeds_jsonpath_parser']['severity'] = REQUIREMENT_OK;
-      $requirements['feeds_jsonpath_parser']['value'] = '0.8.1';
-    }
-    else {
-      $requirements['feeds_jsonpath_parser']['severity'] = REQUIREMENT_ERROR;
-      $requirements['feeds_jsonpath_parser']['value'] = $t('Not found');
-      $requirements['feeds_jsonpath_parser']['description'] = $t('The <a href="@jsonpath">JSONPath</a> plugin is missing. <a href="@download">Download</a> and place in your module directory.', array(
-        '@jsonpath' => 'http://goessner.net/articles/JsonPath/',
-	'@download' => 'http://jsonpath.googlecode.com/files/jsonpath-0.8.1.php',
-      ));
-    }
+  if ($phase !== 'runtime' && $phase !== 'install') {
+    return $requirements;
   }
+
+  drupal_load('module', 'feeds_jsonpath_parser');
+
+  $t = get_t();
+  $requirements['feeds_jsonpath_parser']['title'] = $t('JSONPath library');
+  $requirements['feeds_jsonpath_parser']['severity'] = REQUIREMENT_OK;
+  $requirements['feeds_jsonpath_parser']['value'] = $t('Installed');
+
+  if (!feeds_jsonpath_parser_library_path()) {
+    $requirements['feeds_jsonpath_parser']['severity'] = REQUIREMENT_ERROR;
+    $requirements['feeds_jsonpath_parser']['description'] = $t('The <a href="@jsonpath">JSONPath</a> plugin is missing. Download <a href="@download">this file</a> and place in sites/all/libraries/jsonpath.', array(
+      '@jsonpath' => 'http://goessner.net/articles/JsonPath/',
+      '@download' => 'http://jsonpath.googlecode.com/svn/trunk/src/php/jsonpath.php',
+    ));
+    $requirements['feeds_jsonpath_parser']['value'] = $t('Not installed');
+  }
+
+  if ($phase === 'install') {
+    unset($requirements['feeds_jsonpath_parser']['value']);
+  }
+
   return $requirements;
 }
diff --git a/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.module b/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.module
index dcb1eb1e..b9282b95 100644
--- a/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.module
+++ b/drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.module
@@ -1,5 +1,4 @@
 <?php
-// $Id: feeds_jsonpath_parser.module,v 1.1.4.1 2011/02/05 18:12:18 twistor Exp $
 
 /**
  * Implements hook_feeds_plugins().
@@ -28,3 +27,42 @@ function feeds_jsonpath_parser_feeds_plugins() {
 function feeds_jsonpath_parser_enable() {
   cache_clear_all('plugins:feeds:plugins', 'cache');
 }
+
+/**
+ * Returns the path of the JSONPath library.
+ *
+ * @return string|bool
+ *   The relative path of the JSONPath directory, or false if not found.
+ */
+function feeds_jsonpath_parser_library_path() {
+  $libraries_path = module_exists('libraries') ? libraries_get_path('jsonpath') : FALSE;
+  if ($libraries_path && is_dir($libraries_path)) {
+    $path = $libraries_path;
+  }
+  elseif (is_dir(DRUPAL_ROOT . '/sites/all/libraries/jsonpath')) {
+    $path = DRUPAL_ROOT . '/sites/all/libraries/jsonpath';
+  }
+  // This is defined when simpletest downloads the library for us.
+  elseif (variable_get('feeds_jsonpath_library_dir')) {
+    $path = variable_get('feeds_jsonpath_library_dir');
+  }
+  else {
+    $search = glob(dirname(__FILE__) . '/jsonpath*.php');
+    return is_array($search) ? reset($search) : FALSE;
+  }
+
+  if (!isset($path)) {
+    return FALSE;
+  }
+
+  // Newer forks of JSONPath are all modern and fancy with their autoloaders.
+  if (is_file($path . '/vendor/autoload.php')) {
+    return $path . '/vendor/autoload.php';
+  }
+  // Old school. Look for multiple versions.
+  foreach (glob($path . '/jsonpath*.php') as $file) {
+    return $file;
+  }
+
+  return FALSE;
+}
diff --git a/drupal7/sites/all/modules/feeds_jsonpath_parser/jsonpath-0.8.1.php b/drupal7/sites/all/modules/feeds_jsonpath_parser/jsonpath-0.8.1.php
deleted file mode 100644
index 0dbbaf48..00000000
--- a/drupal7/sites/all/modules/feeds_jsonpath_parser/jsonpath-0.8.1.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-/* JSONPath 0.8.1 - XPath for JSON
- *
- * Copyright (c) 2007 Stefan Goessner (goessner.net)
- * Licensed under the MIT (MIT-LICENSE.txt) licence.
- */
-
-// API function 
-function jsonPath($obj, $expr, $args=null) {
-   $jsonpath = new JsonPath();
-   $jsonpath->resultType = ($args ? $args['resultType'] : "VALUE");
-   $x = $jsonpath->normalize($expr);
-   $jsonpath->obj = $obj;
-   if ($expr && $obj && ($jsonpath->resultType == "VALUE" || $jsonpath->resultType == "PATH")) {
-      $jsonpath->trace(preg_replace("/^\\$;/", "", $x), $obj, "$");
-      if (count($jsonpath->result))
-         return $jsonpath->result;
-      else
-         return false;
-   }
-}
-
-// JsonPath class (internal use only)
-class JsonPath {
-   var $obj = null;
-   var $resultType = "Value";
-   var $result = array();
-   var $subx = array();
-
-   // normalize path expression
-   function normalize($x) {
-      $x = preg_replace_callback("/[\['](\??\(.*?\))[\]']/", array(&$this, "_callback_01"), $x);
-      $x = preg_replace(array("/'?\.'?|\['?/", "/;;;|;;/", "/;$|'?\]|'$/"),
-                        array(";", ";..;", ""),
-                        $x);
-      $x = preg_replace_callback("/#([0-9]+)/", array(&$this, "_callback_02"), $x);
-      $this->result = array();  // result array was temporarily used as a buffer ..
-      return $x;
-   }
-   function _callback_01($m) { return "[#".(array_push($this->result, $m[1])-1)."]"; }
-   function _callback_02($m) { return $this->result[$m[1]]; }
-
-   function asPath($path) {
-      $x = explode(";", $path);
-      $p = "$";
-      for ($i=1,$n=count($x); $i<$n; $i++)
-         $p .= preg_match("/^[0-9*]+$/", $x[$i]) ? ("[".$x[$i]."]") : ("['".$x[$i]."']");
-      return $p;
-   }
-   function store($p, $v) {
-      if ($p) array_push($this->result, ($this->resultType == "PATH" ? $this->asPath($p) : $v));
-      return !!$p;
-   }
-   function trace($expr, $val, $path) {
-      if ($expr) {
-         $x = explode(";", $expr);
-         $loc = array_shift($x);
-         $x = implode(";", $x);
-
-         if (is_array($val) && array_key_exists($loc, $val))
-            $this->trace($x, $val[$loc], $path.";".$loc);
-         else if ($loc == "*")
-            $this->walk($loc, $x, $val, $path, array(&$this, "_callback_03"));
-         else if ($loc === "..") {
-            $this->trace($x, $val, $path);
-            $this->walk($loc, $x, $val, $path, array(&$this, "_callback_04"));
-         }
-         else if (preg_match("/,/", $loc)) // [name1,name2,...]
-            for ($s=preg_split("/'?,'?/", $loc),$i=0,$n=count($s); $i<$n; $i++)
-                $this->trace($s[$i].";".$x, $val, $path);
-         else if (preg_match("/^\(.*?\)$/", $loc)) // [(expr)]
-            $this->trace($this->evalx($loc, $val, substr($path,strrpos($path,";")+1)).";".$x, $val, $path);
-         else if (preg_match("/^\?\(.*?\)$/", $loc)) // [?(expr)]
-            $this->walk($loc, $x, $val, $path, array(&$this, "_callback_05"));
-         else if (preg_match("/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/", $loc)) // [start:end:step]  phyton slice syntax
-            $this->slice($loc, $x, $val, $path);
-      }
-      else
-         $this->store($path, $val);
-   }
-   function _callback_03($m,$l,$x,$v,$p) { $this->trace($m.";".$x,$v,$p); }
-   function _callback_04($m,$l,$x,$v,$p) { if (is_array($v[$m])) $this->trace("..;".$x,$v[$m],$p.";".$m); }
-   function _callback_05($m,$l,$x,$v,$p) { if ($this->evalx(preg_replace("/^\?\((.*?)\)$/","$1",$l),$v[$m])) $this->trace($m.";".$x,$v,$p); }
-
-   function walk($loc, $expr, $val, $path, $f) {
-      foreach($val as $m => $v)
-         call_user_func($f, $m, $loc, $expr, $val, $path);
-   }
-   function slice($loc, $expr, $v, $path) {
-      $s = explode(":", preg_replace("/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/", "$1:$2:$3", $loc));
-      $len=count($v);
-      $start=(int)$s[0]?$s[0]:0; 
-      $end=(int)$s[1]?$s[1]:$len; 
-      $step=(int)$s[2]?$s[2]:1;
-      $start = ($start < 0) ? max(0,$start+$len) : min($len,$start);
-      $end   = ($end < 0)   ? max(0,$end+$len)   : min($len,$end);
-      for ($i=$start; $i<$end; $i+=$step)
-         $this->trace($i.";".$expr, $v, $path);
-   }
-   function evalx($x, $v, $vname) {
-      $name = "";
-      $expr = preg_replace(array("/\\$/","/@/"), array("\$this->obj","\$v"), $x);
-      $res = eval("\$name = $expr;");
-
-      if ($res === FALSE)
-         print("(jsonPath) SyntaxError: " . $expr);
-      else
-         return $name;
-   }
-}
-?>
\ No newline at end of file
diff --git a/drupal7/sites/all/modules/feeds_jsonpath_parser/tests/feeds_jsonpath_parser.test b/drupal7/sites/all/modules/feeds_jsonpath_parser/tests/feeds_jsonpath_parser.test
index 91113ad5..666c7e03 100644
--- a/drupal7/sites/all/modules/feeds_jsonpath_parser/tests/feeds_jsonpath_parser.test
+++ b/drupal7/sites/all/modules/feeds_jsonpath_parser/tests/feeds_jsonpath_parser.test
@@ -1,5 +1,4 @@
 <?php
-// $Id: feeds_jsonpath_parser.test,v 1.1.2.1 2011/02/05 18:12:18 twistor Exp $
 
 /**
  * @file
@@ -14,11 +13,11 @@ class FeedsJSONPathParserTestCase extends FeedsWebTestCase {
   /**
    * Describe this test.
    */
-  public function getInfo() {
+  public static function getInfo() {
     return array(
       'name' => t('JSONPath Parser'),
       'description' => t('Regression tests for Feeds JSONPath parser.'),
-      'group' => t('Feeds'),
+      'group' => t('Feeds JSONPath Parser'),
     );
   }
 
@@ -26,7 +25,56 @@ class FeedsJSONPathParserTestCase extends FeedsWebTestCase {
    * Set up test.
    */
   public function setUp() {
-    parent::setUp(array('feeds', 'feeds_ui', 'ctools', 'job_scheduler', 'feeds_jsonpath_parser'));
+    parent::setUp(array('feeds_jsonpath_parser'));
+    $this->downloadJsonPath();
+  }
+
+  /**
+   * Downloads JSONPath.
+   */
+  protected function downloadJsonPath() {
+    // We don't use a variable_set() here since we want this to be a unit test.
+    if (variable_get('feeds_jsonpath_library_dir')) {
+      return;
+    }
+    $url = 'https://jsonpath.googlecode.com/svn/trunk/src/php/jsonpath.php';
+    $filename = 'jsonpath.php';
+
+    // Avoid downloading the file dozens of times.
+    $library_dir = $this->originalFileDirectory . '/simpletest/feeds_jsonpath_parser';
+    $jsonpath_library_dir = DRUPAL_ROOT . '/' . $library_dir . '/jsonpath';
+
+    if (!file_exists(DRUPAL_ROOT . '/' . $library_dir)) {
+      drupal_mkdir(DRUPAL_ROOT . '/' . $library_dir);
+    }
+
+    if (!file_exists($jsonpath_library_dir)) {
+      drupal_mkdir($jsonpath_library_dir);
+    }
+
+    // Local file name.
+    $local_file = $jsonpath_library_dir . '/' . $filename;
+
+    // Begin single threaded code.
+    if (function_exists('sem_get')) {
+      $semaphore = sem_get(ftok(__FILE__, 1));
+      sem_acquire($semaphore);
+    }
+
+    // Download and extact the archive, but only in one thread.
+    if (!file_exists($local_file)) {
+      $local_file = system_retrieve_file($url, $local_file, FALSE, FILE_EXISTS_REPLACE);
+    }
+
+    if (function_exists('sem_get')) {
+      sem_release($semaphore);
+    }
+
+    // Verify that the file was successfully downloaded.
+    $this->assertTrue(file_exists($local_file), format_string('@file found.', array('@file' => $local_file)));
+
+    // Set the library directory.
+    variable_set('feeds_jsonpath_library_dir', $jsonpath_library_dir);
   }
 
   /**
@@ -55,20 +103,20 @@ class FeedsJSONPathParserTestCase extends FeedsWebTestCase {
       'jsonpath[context]' => '$.store.book[*]',
       'jsonpath[sources][jsonpath_parser:0]' => 'author',
       'jsonpath[sources][jsonpath_parser:1]' => 'price',
+      'jsonpath[allow_override]' => TRUE,
     );
-    $this->drupalPost('admin/structure/feeds/edit/jsonpath/settings/FeedsJSONPathParser', $edit, 'Save');
-    $this->assertText('Your changes have been saved.');
-    $this->assertRaw('$.store.book[*]');
-    $this->assertRaw('author');
-    $this->assertRaw('price');
+    $edit_url = 'admin/structure/feeds/jsonpath/settings/FeedsJSONPathParser';
+    $node_save_text = 'Basic page Testing JSONPath Parser has been updated.';
+
+    $this->postAndCheck($edit_url, $edit, 'Save', 'Your changes have been saved.');
 
     // Test import.
-    $path = $GLOBALS['base_url'] .'/'. drupal_get_path('module', 'feeds_jsonpath_parser') .'/tests/feeds_jsonpath_parser/';
-    $nid = $this->createFeedNode('jsonpath', $path . 'test.json', 'Testing JSONPath Parser');
+    $path = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds_jsonpath_parser') . '/tests/feeds_jsonpath_parser';
+    $nid = $this->createFeedNode('jsonpath', $path . '/test.json', 'Testing JSONPath Parser');
     $this->assertText('Created 4 nodes');
 
     // Import again, this verifies url field was mapped correctly.
-    $this->drupalPost('node/'. $nid .'/import', array(), 'Import');
+    $this->drupalPost('node/' . $nid . '/import', array(), 'Import');
     $this->assertText('There are no new nodes');
 
     // Assert accuracy of aggregated content. I find humor in using our own
@@ -85,16 +133,11 @@ class FeedsJSONPathParserTestCase extends FeedsWebTestCase {
       'feeds[FeedsJSONPathParser][jsonpath][sources][jsonpath_parser:0]' => 'bar',
       'feeds[FeedsJSONPathParser][jsonpath][sources][jsonpath_parser:1]' => 'baz',
     );
-    $this->drupalPost('node/'. $nid .'/edit', $edit, 'Save');
-    $this->drupalGet('node/'. $nid .'/edit');
-    // Why not use XPath to test JSONPath?
-    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-context"][1]/@value', '/foo');
-    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-sources-jsonpath-parser0"][1]/@value', 'bar');
-    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-sources-jsonpath-parser1"][1]/@value', 'baz');
-
-    // Assert the we don't create an empty node when XPath values don't return anything.
+    $this->postAndCheck('node/' . $nid . '/edit', $edit, 'Save', $node_save_text);
+
+    // Assert the we don't create an empty node when JSONPath values don't return anything.
     // That happened at one point.
-    $this->drupalPost('node/'. $nid .'/import', array(), 'Import');
+    $this->drupalPost('node/' . $nid . '/import', array(), 'Import');
     $this->assertText('There are no new nodes');
 
     // Put the values back so we can test inheritance if the form was changed
@@ -104,11 +147,7 @@ class FeedsJSONPathParserTestCase extends FeedsWebTestCase {
       'feeds[FeedsJSONPathParser][jsonpath][sources][jsonpath_parser:0]' => 'author',
       'feeds[FeedsJSONPathParser][jsonpath][sources][jsonpath_parser:1]' => 'price',
     );
-    $this->drupalPost('node/'. $nid .'/edit', $edit, 'Save');
-    $this->drupalGet('node/'. $nid .'/edit');
-    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-context"][1]/@value', '$.store.book[*]');
-    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-sources-jsonpath-parser0"][1]/@value', 'author');
-    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-sources-jsonpath-parser1"][1]/@value', 'price');
+    $this->postAndCheck('node/' . $nid . '/edit', $edit, 'Save', $node_save_text);
 
     // Change importer defaults.
     $edit = array(
@@ -116,16 +155,35 @@ class FeedsJSONPathParserTestCase extends FeedsWebTestCase {
       'jsonpath[sources][jsonpath_parser:0]' => 'booya',
       'jsonpath[sources][jsonpath_parser:1]' => 'boyz',
     );
-    $this->drupalPost('admin/structure/feeds/edit/jsonpath/settings/FeedsJSONPathParser', $edit, 'Save');
-    $this->assertText('Your changes have been saved.');
-    $this->assertRaw('//tr');
-    $this->assertRaw('booya');
-    $this->assertRaw('boyz');
+    $this->drupalPost($edit_url, $edit, 'Save');
+    $this->postAndCheck($edit_url, $edit, 'Save', 'Your changes have been saved.');
 
     // Make sure the changes propigated.
-    $this->drupalGet('node/'. $nid .'/edit');
-    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-context"][1]/@value', '//tr');
-    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-sources-jsonpath-parser0"][1]/@value', 'booya');
-    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-sources-jsonpath-parser1"][1]/@value', 'boyz');
+    $this->drupalGet('node/' . $nid . '/edit');
+    $this->assertFieldByName('feeds[FeedsJSONPathParser][jsonpath][context]', '//tr');
+    $this->assertFieldByName('feeds[FeedsJSONPathParser][jsonpath][sources][jsonpath_parser:0]', 'booya');
+    $this->assertFieldByName('feeds[FeedsJSONPathParser][jsonpath][sources][jsonpath_parser:1]', 'boyz');
+
+    // Turn off allow_override.
+    $edit = array(
+      'jsonpath[allow_override]' => FALSE,
+    );
+    $this->postAndCheck($edit_url, $edit, 'Save', 'Your changes have been saved.');
+    $this->drupalGet('node/' . $nid . '/edit');
+    $this->assertNoText('JSONPath Parser Settings');
+
+    // Test byte replacement.
+    $this->assertEqual('ࡇ abc ʦ &#135361;', FeedsJSONPathParser::convertFourBytes('ࡇ abc ʦ 𡃁'));
+    $this->assertEqual('ࡇ abc ʦ ', FeedsJSONPathParser::stripFourBytes('ࡇ abc ʦ 𡃁'));
   }
+
+  public function postAndCheck($url, $edit, $button, $saved_text) {
+    $this->drupalPost($url, $edit, $button);
+    $this->assertText($saved_text);
+    $this->drupalGet($url);
+    foreach ($edit as $key => $value) {
+      $this->assertFieldByName($key, $value);
+    }
+  }
+
 }
