From 4d14a81936bc26fa09c4908362707201841036d1 Mon Sep 17 00:00:00 2001
From: Chris Gross <gross.364@osu.edu>
Date: Mon, 12 Sep 2016 16:03:44 -0400
Subject: [PATCH] weekly build

---
 profiles/wcm_base/CHANGELOG.txt               |    7 +
 .../modules/contrib/diff/CHANGELOG.txt        |  166 ++
 .../modules/contrib/diff/DiffEngine.php       | 1349 +++++++++++++++++
 .../wcm_base/modules/contrib/diff/LICENSE.txt |  339 +++++
 .../modules/contrib/diff/css/diff.boxes.css   |  124 ++
 .../modules/contrib/diff/css/diff.default.css |   86 ++
 .../modules/contrib/diff/diff.admin.inc       |  158 ++
 .../modules/contrib/diff/diff.api.php         |  181 +++
 .../wcm_base/modules/contrib/diff/diff.css    |   86 ++
 .../modules/contrib/diff/diff.diff.inc        |  384 +++++
 .../wcm_base/modules/contrib/diff/diff.info   |   12 +
 .../modules/contrib/diff/diff.install         |  124 ++
 .../wcm_base/modules/contrib/diff/diff.module |  623 ++++++++
 .../modules/contrib/diff/diff.pages.inc       |  632 ++++++++
 .../modules/contrib/diff/diff.theme.inc       |  149 ++
 .../modules/contrib/diff/diff.tokens.inc      |   63 +
 .../modules/contrib/diff/includes/file.inc    |  111 ++
 .../modules/contrib/diff/includes/image.inc   |  112 ++
 .../modules/contrib/diff/includes/list.inc    |   71 +
 .../modules/contrib/diff/includes/node.inc    |  107 ++
 .../modules/contrib/diff/includes/number.inc  |   17 +
 .../contrib/diff/includes/taxonomy.inc        |  107 ++
 .../modules/contrib/diff/includes/text.inc    |  113 ++
 .../wcm_base/modules/contrib/diff/js/diff.js  |   58 +
 .../wcm_base/modules/contrib/diff/readme.txt  |  136 ++
 .../draggableviews/draggableviews.info        |    6 +-
 .../draggableviews/draggableviews.module      |   17 +
 .../draggableviews_book.info                  |    6 +-
 .../draggableviews_test.info                  |    6 +-
 .../ocio_wysiwyg.features.wysiwyg.inc         |   11 +-
 .../custom/ocio_wysiwyg/ocio_wysiwyg.module   |    9 +-
 .../custom/ocio_wysiwyg/plugins/icon-tabs.png |  Bin 344 -> 0 bytes
 .../ocio_wysiwyg/plugins/menuMods/plugin.js   |   18 +
 .../ocio_wysiwyg/plugins/tabs/plugin.js       |    1 +
 .../wcm_panels_settings.module                |   13 +
 .../wcm_workbench/wcm_workbench.features.inc  |    9 +
 .../custom/wcm_workbench/wcm_workbench.info   |    8 +
 .../custom/wcm_workbench/wcm_workbench.make   |    3 +
 .../custom/wcm_workbench/wcm_workbench.module |   36 +
 .../wcm_workbench/wcm_workbench.strongarm.inc |   49 +
 .../ocio-default/ocio-default.layout.css      |   25 -
 .../ocio-default.layout.no-query.css          |   25 -
 .../css/ocio-omega-base.no-query.css          |   75 +-
 .../css/ocio-omega-base.styles.css            |   75 +-
 .../ocio_omega_base/sass/base/_forms.scss     |   38 -
 .../sass/components/_webform.scss             |   72 +-
 46 files changed, 5631 insertions(+), 186 deletions(-)
 create mode 100644 profiles/wcm_base/modules/contrib/diff/CHANGELOG.txt
 create mode 100644 profiles/wcm_base/modules/contrib/diff/DiffEngine.php
 create mode 100644 profiles/wcm_base/modules/contrib/diff/LICENSE.txt
 create mode 100644 profiles/wcm_base/modules/contrib/diff/css/diff.boxes.css
 create mode 100644 profiles/wcm_base/modules/contrib/diff/css/diff.default.css
 create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.admin.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.api.php
 create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.css
 create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.diff.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.info
 create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.install
 create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.module
 create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.pages.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.theme.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.tokens.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/file.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/image.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/list.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/node.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/number.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/taxonomy.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/text.inc
 create mode 100644 profiles/wcm_base/modules/contrib/diff/js/diff.js
 create mode 100644 profiles/wcm_base/modules/contrib/diff/readme.txt
 delete mode 100644 profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/icon-tabs.png
 create mode 100644 profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/menuMods/plugin.js
 create mode 100644 profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.strongarm.inc

diff --git a/profiles/wcm_base/CHANGELOG.txt b/profiles/wcm_base/CHANGELOG.txt
index 621b9ada..3594ca60 100644
--- a/profiles/wcm_base/CHANGELOG.txt
+++ b/profiles/wcm_base/CHANGELOG.txt
@@ -1,3 +1,10 @@
+WCM Base 7.x-1.x, 2016-09-12
+----------------------------
+- WCM Workbench: Added diff module, including custom links in Workbench Block.
+- WCM Panels Settings: Clear page cache when saving panelized nodes in panels IPE.
+- OCIO WYSIWYG: Added custom plugin menuMod (removes fields in table cell dialog).
+- OCIO Omega Base: Improved webform styles.
+
 WCM Base 7.x-1.x, 2016-08-29
 ----------------------------
 - WCM Search:
diff --git a/profiles/wcm_base/modules/contrib/diff/CHANGELOG.txt b/profiles/wcm_base/modules/contrib/diff/CHANGELOG.txt
new file mode 100644
index 00000000..38696432
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/CHANGELOG.txt
@@ -0,0 +1,166 @@
+
+CHANGELOG for Diff 7.x-2.0+13-dev to 7.x-3.x
+============================================
+
+1) System variable names have been changed
+------------------------------------------
+
+Considerable changes have occurred.
+
+2) hook_diff() was removed
+--------------------------
+
+This has been replaced by hook_entity_diff() as of Diff 7.x-3.x.
+
+3) Field diffs are handled independently by Diff and the field module
+---------------------------------------------------------------------
+
+Field modules SHOULD NOT implement hook_entity_diff().
+
+This is complicated and costly in terms of performance.
+
+Two new field callbacks are defined to handle these.
+
+  a) MODULE_field_diff_view_prepare()
+
+  Optional: If you need to load data, use MODULE_field_diff_view_prepare().
+
+  b) MODULE_field_diff_view()
+
+  Recommended: You should implement this to generate the compared data.
+
+If there is no corresponding hook for a field, the field comparison will try
+to guess the value using $item['safe_value'] or $item['value'] properties.
+
+If you need to make this configurable, there are two additional hooks:
+
+  c) MODULE_field_diff_default_options($field_type)
+  
+  You should define any additioal settings here. This shares a global namespace
+  of the diff module, so you can overwrite core Diff settings here too.
+  
+  In saying that, take care not to accidentially do this.
+  
+  d) MODULE_field_diff_options_form($field_type, $settings)
+  
+  This is where you insert Form API elements to configure your option settings.
+
+4) Field diffs are now configurable
+-----------------------------------
+
+Each field type defined by core have configurable settings to control the
+rendering of the comparison.
+
+  a) Global configuration
+
+  An administration page has been added to handle field type default settings.
+  
+  This is the preferred way to configure field settings are these are global to
+  all fields of this type.
+
+  b) View mode display options
+
+  The display "Diff comparison" is used to control the fields that are displayed 
+  when comparing different revisions.
+
+  The following is a walk-through on how you would configure the Basic page
+  (page) content types field configuration.
+
+  - Enable "Diff comparison" custom view mode
+
+    Navigate to admin/structure/types/manage/page/display and look at the
+    Custom Display Settings for this view mode. Check and save.
+
+  - Configure the display
+
+    After Saving this page, a new tab appears "Diff comparison", click this or
+    navigate directly to admin/structure/types/manage/page/display/diff_standard
+
+    - You can hide or show the fields that you want to display when doing 
+      comparisons.
+    - If the field has no inbuilt diff support, then the renderred field items
+      will be compared.
+
+5) Standard comparison preview / Inline diff view setting
+---------------------------------------------------------
+
+You can set the view modes used to compare the rendered node. This can be found
+in the Diff settings in the Content Type settings page.
+
+6) Optional CSS and new Boxes styles
+------------------------------------
+
+This takes the styles from WikiPedia to really spice up the diff page.
+
+7) Optional JScript extras
+--------------------------
+
+This spices up the revision checkboxes on the revisions page.
+
+8) Simple past revision token support
+-------------------------------------
+
+Use-case, email notifications when content has changes. If these support tokens,
+then you can embed Diffs into these emails.
+
+9) Extensive string review
+--------------------------
+See http://drupal.org/node/1785742
+
+
+10) Inline block settings changes
+---------------------------------
+The inline block settings are now in the block configuration page.
+
+11) And much more...
+--------------------
+
+The complete change log follows:
+
+Diff 7.x-2.x
+    o #888680 by Deciphered, Alan D.: Allow modules to interact via drupal_alter()
+    o #1280892 by Alan D., crea: Diff should track the variables that it defines
+    o #1304658 by Alan D., kari.kaariainen: Remove links and comments from the comparison preview
+    o #1122206 by binford2k, Alan D.: Notices thrown by DiffEngine::process_chunk()
+    o #1175064 by zilverdistel, Alan D.: Provide variables for leading and trailing context
+    o #1673864 by Alan D.: Allow users to bypass the admin theme when viewing comparisons
+    o #1673876 by Alan D.: Use Drupal autoloading for classes
+    o #1673856 by Alan D.: Use hook_form_BASE_FORM_ID_alter() rather than hook_form_alter()
+    o #1673856 by Alan D.: Normalise line endings
+    o #114308 by Alan D.: add jQuery for hiding radios that shouldn't show diffs
+    o #1688840 by Alan D.: Enable new JScript behaviour by default
+    o #372957 by erykmynn, JuliaKM, lsrzj, andrew_rs, alexpott, et al: HTML Strip for Diff, WYSIWYG Friendly
+      (This was refactored in the 7.x-3.x branch from the commited 7.x-2.x code)    
+    o #521212 by Alan D., blakehall: Make diff comparison page themable
+    o #1671484 by Alan D.: Show number of lines changed on revisions page
+    o #114699 by smokris, Alan D.: Diff module should support Token
+    o #372957 by c31ck: display either Hide or Show based on what clicking it will do at any time (HTML Strip for Diff)
+      This was altered for the 7.x-3.x branch.
+    o #1807510 & #1825202: Simplify Diff administration
+    o #1812162 by mitchell, Alan D.: 'Highlight changes' block appears on edit form
+
+    Node to Entity changes
+    ----------------------
+    These are roughly tracked in the meta issue #1365750 Generalize API and Integrate with core field types
+
+    o (no issue) by Alan D.: Use entity specific system variables.
+    o (no issue) by Alan D.: View mode code, new hooks, new API. Massive patch!
+
+    Resolves:
+    o #248778: Taxonomy diff
+    o #1550698: Diff of "select from list" fields shows change in key, not change in value
+    o #1458814: File (and image) field support
+    o #1418760: Optional setting to honour the display settings
+    o #1347316: Selectable view mode for inline diffs and "Current revision" display view mode
+    o #1458906: Improve performances (of existing 7.x-2.x field rendering)
+    o #1424162: Diff in Taxonomy term description
+    o #1211282: Image diff support
+
+The following patches will be posted in the corresponding project queues once
+the 7.x-3.x branch is released:
+    o #1595702 by Alan D., mbilbille: Support of field collection module
+    o #1350604 by Alan D., johaziel: Datetime diff
+    o (no issue) by Alan D.: Email field Diff support
+    o (no issue) by Alan D.: Countries Diff support
+    o (no issue) by Alan D.: Name field Diff support
+    o (no issue) by Alan D.: Link field Diff support
diff --git a/profiles/wcm_base/modules/contrib/diff/DiffEngine.php b/profiles/wcm_base/modules/contrib/diff/DiffEngine.php
new file mode 100644
index 00000000..12366107
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/DiffEngine.php
@@ -0,0 +1,1349 @@
+<?php
+
+/**
+ * @file
+ * A PHP diff engine for phpwiki. (Taken from phpwiki-1.3.3)
+ *
+ * Copyright (C) 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org>
+ * You may copy this code freely under the conditions of the GPL.
+ */
+
+define('USE_ASSERTS', FALSE);
+
+/**
+ * @todo document
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class _DiffOp {
+  var $type;
+  var $orig;
+  var $closing;
+
+  function reverse() {
+    trigger_error('pure virtual', E_USER_ERROR);
+  }
+
+  function norig() {
+    return $this->orig ? sizeof($this->orig) : 0;
+  }
+
+  function nclosing() {
+    return $this->closing ? sizeof($this->closing) : 0;
+  }
+}
+
+/**
+ * @todo document
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class _DiffOp_Copy extends _DiffOp {
+  var $type = 'copy';
+
+  function _DiffOp_Copy($orig, $closing = FALSE) {
+    if (!is_array($closing)) {
+      $closing = $orig;
+    }
+    $this->orig = $orig;
+    $this->closing = $closing;
+  }
+
+  function reverse() {
+    return new _DiffOp_Copy($this->closing, $this->orig);
+  }
+}
+
+/**
+ * @todo document
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class _DiffOp_Delete extends _DiffOp {
+  var $type = 'delete';
+
+  function _DiffOp_Delete($lines) {
+    $this->orig = $lines;
+    $this->closing = FALSE;
+  }
+
+  function reverse() {
+    return new _DiffOp_Add($this->orig);
+  }
+}
+
+/**
+ * @todo document
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class _DiffOp_Add extends _DiffOp {
+  var $type = 'add';
+
+  function _DiffOp_Add($lines) {
+    $this->closing = $lines;
+    $this->orig = FALSE;
+  }
+
+  function reverse() {
+    return new _DiffOp_Delete($this->closing);
+  }
+}
+
+/**
+ * @todo document
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class _DiffOp_Change extends _DiffOp {
+  var $type = 'change';
+
+  function _DiffOp_Change($orig, $closing) {
+    $this->orig = $orig;
+    $this->closing = $closing;
+  }
+
+  function reverse() {
+    return new _DiffOp_Change($this->closing, $this->orig);
+  }
+}
+
+
+/**
+ * Class used internally by Diff to actually compute the diffs.
+ *
+ * The algorithm used here is mostly lifted from the perl module
+ * Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
+ *   http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip
+ *
+ * More ideas are taken from:
+ *   http://www.ics.uci.edu/~eppstein/161/960229.html
+ *
+ * Some ideas are (and a bit of code) are from from analyze.c, from GNU
+ * diffutils-2.7, which can be found at:
+ *   ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz
+ *
+ * closingly, some ideas (subdivision by NCHUNKS > 2, and some optimizations)
+ * are my own.
+ *
+ * Line length limits for robustness added by Tim Starling, 2005-08-31
+ *
+ * @author Geoffrey T. Dairiki, Tim Starling
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class _DiffEngine {
+  function MAX_XREF_LENGTH() {
+    return 10000;
+  }
+
+  function diff($from_lines, $to_lines) {
+
+    $n_from = sizeof($from_lines);
+    $n_to = sizeof($to_lines);
+
+    $this->xchanged = $this->ychanged = array();
+    $this->xv = $this->yv = array();
+    $this->xind = $this->yind = array();
+    unset($this->seq);
+    unset($this->in_seq);
+    unset($this->lcs);
+
+    // Skip leading common lines.
+    for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) {
+      if ($from_lines[$skip] !== $to_lines[$skip]) {
+        break;
+      }
+      $this->xchanged[$skip] = $this->ychanged[$skip] = FALSE;
+    }
+    // Skip trailing common lines.
+    $xi = $n_from;
+    $yi = $n_to;
+    for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) {
+      if ($from_lines[$xi] !== $to_lines[$yi]) {
+        break;
+      }
+      $this->xchanged[$xi] = $this->ychanged[$yi] = FALSE;
+    }
+
+    // Ignore lines which do not exist in both files.
+    for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
+      $xhash[$this->_line_hash($from_lines[$xi])] = 1;
+    }
+
+    for ($yi = $skip; $yi < $n_to - $endskip; $yi++) {
+      $line = $to_lines[$yi];
+      if ($this->ychanged[$yi] = empty($xhash[$this->_line_hash($line)])) {
+        continue;
+      }
+      $yhash[$this->_line_hash($line)] = 1;
+      $this->yv[] = $line;
+      $this->yind[] = $yi;
+    }
+    for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
+      $line = $from_lines[$xi];
+      if ($this->xchanged[$xi] = empty($yhash[$this->_line_hash($line)])) {
+        continue;
+      }
+      $this->xv[] = $line;
+      $this->xind[] = $xi;
+    }
+
+    // Find the LCS.
+    $this->_compareseq(0, sizeof($this->xv), 0, sizeof($this->yv));
+
+    // Merge edits when possible
+    $this->_shift_boundaries($from_lines, $this->xchanged, $this->ychanged);
+    $this->_shift_boundaries($to_lines, $this->ychanged, $this->xchanged);
+
+    // Compute the edit operations.
+    $edits = array();
+    $xi = $yi = 0;
+    while ($xi < $n_from || $yi < $n_to) {
+      USE_ASSERTS && assert($yi < $n_to || $this->xchanged[$xi]);
+      USE_ASSERTS && assert($xi < $n_from || $this->ychanged[$yi]);
+
+      // Skip matching "snake".
+      $copy = array();
+      while ( $xi < $n_from && $yi < $n_to && !$this->xchanged[$xi] && !$this->ychanged[$yi]) {
+        $copy[] = $from_lines[$xi++];
+        ++$yi;
+      }
+      if ($copy) {
+        $edits[] = new _DiffOp_Copy($copy);
+      }
+      // Find deletes & adds.
+      $delete = array();
+      while ($xi < $n_from && $this->xchanged[$xi]) {
+        $delete[] = $from_lines[$xi++];
+      }
+      $add = array();
+      while ($yi < $n_to && $this->ychanged[$yi]) {
+        $add[] = $to_lines[$yi++];
+      }
+      if ($delete && $add) {
+        $edits[] = new _DiffOp_Change($delete, $add);
+      }
+      elseif ($delete) {
+        $edits[] = new _DiffOp_Delete($delete);
+      }
+      elseif ($add) {
+        $edits[] = new _DiffOp_Add($add);
+      }
+    }
+    return $edits;
+  }
+
+  /**
+   * Returns the whole line if it's small enough, or the MD5 hash otherwise.
+   */
+  function _line_hash($line) {
+    if (drupal_strlen($line) > $this->MAX_XREF_LENGTH()) {
+      return md5($line);
+    }
+    else {
+      return $line;
+    }
+  }
+
+
+  /**
+   * Divide the Largest Common Subsequence (LCS) of the sequences
+   * [XOFF, XLIM) and [YOFF, YLIM) into NCHUNKS approximately equally
+   * sized segments.
+   *
+   * Returns (LCS, PTS).  LCS is the length of the LCS. PTS is an
+   * array of NCHUNKS+1 (X, Y) indexes giving the diving points between
+   * sub sequences.  The first sub-sequence is contained in [X0, X1),
+   * [Y0, Y1), the second in [X1, X2), [Y1, Y2) and so on.  Note
+   * that (X0, Y0) == (XOFF, YOFF) and
+   * (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM).
+   *
+   * This function assumes that the first lines of the specified portions
+   * of the two files do not match, and likewise that the last lines do not
+   * match.  The caller must trim matching lines from the beginning and end
+   * of the portions it is going to specify.
+   */
+  function _diag($xoff, $xlim, $yoff, $ylim, $nchunks) {
+    $flip = FALSE;
+
+    if ($xlim - $xoff > $ylim - $yoff) {
+      // Things seems faster (I'm not sure I understand why)
+      // when the shortest sequence in X.
+      $flip = TRUE;
+      list($xoff, $xlim, $yoff, $ylim) = array($yoff, $ylim, $xoff, $xlim);
+    }
+
+    if ($flip) {
+      for ($i = $ylim - 1; $i >= $yoff; $i--) {
+        $ymatches[$this->xv[$i]][] = $i;
+      }
+    }
+    else {
+      for ($i = $ylim - 1; $i >= $yoff; $i--) {
+        $ymatches[$this->yv[$i]][] = $i;
+      }
+    }
+    $this->lcs = 0;
+    $this->seq[0]= $yoff - 1;
+    $this->in_seq = array();
+    $ymids[0] = array();
+
+    $numer = $xlim - $xoff + $nchunks - 1;
+    $x = $xoff;
+    for ($chunk = 0; $chunk < $nchunks; $chunk++) {
+      if ($chunk > 0) {
+        for ($i = 0; $i <= $this->lcs; $i++) {
+          $ymids[$i][$chunk-1] = $this->seq[$i];
+        }
+      }
+
+      $x1 = $xoff + (int)(($numer + ($xlim-$xoff)*$chunk) / $nchunks);
+      for ( ; $x < $x1; $x++) {
+        $line = $flip ? $this->yv[$x] : $this->xv[$x];
+        if (empty($ymatches[$line])) {
+          continue;
+        }
+        $matches = $ymatches[$line];
+        reset($matches);
+        while (list ($junk, $y) = each($matches)) {
+          if (empty($this->in_seq[$y])) {
+            $k = $this->_lcs_pos($y);
+            USE_ASSERTS && assert($k > 0);
+            $ymids[$k] = $ymids[$k-1];
+            break;
+          }
+        }
+        while (list ($junk, $y) = each($matches)) {
+          if ($y > $this->seq[$k-1]) {
+            USE_ASSERTS && assert($y < $this->seq[$k]);
+            // Optimization: this is a common case:
+            // next match is just replacing previous match.
+            $this->in_seq[$this->seq[$k]] = FALSE;
+            $this->seq[$k] = $y;
+            $this->in_seq[$y] = 1;
+          }
+          elseif (empty($this->in_seq[$y])) {
+            $k = $this->_lcs_pos($y);
+            USE_ASSERTS && assert($k > 0);
+            $ymids[$k] = $ymids[$k-1];
+          }
+        }
+      }
+    }
+
+    $seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff);
+    $ymid = $ymids[$this->lcs];
+    for ($n = 0; $n < $nchunks - 1; $n++) {
+      $x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks);
+      $y1 = $ymid[$n] + 1;
+      $seps[] = $flip ? array($y1, $x1) : array($x1, $y1);
+    }
+    $seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim);
+
+    return array($this->lcs, $seps);
+  }
+
+  function _lcs_pos($ypos) {
+
+    $end = $this->lcs;
+    if ($end == 0 || $ypos > $this->seq[$end]) {
+      $this->seq[++$this->lcs] = $ypos;
+      $this->in_seq[$ypos] = 1;
+      return $this->lcs;
+    }
+
+    $beg = 1;
+    while ($beg < $end) {
+      $mid = (int)(($beg + $end) / 2);
+      if ($ypos > $this->seq[$mid]) {
+        $beg = $mid + 1;
+      }
+      else {
+        $end = $mid;
+      }
+    }
+
+    USE_ASSERTS && assert($ypos != $this->seq[$end]);
+
+    $this->in_seq[$this->seq[$end]] = FALSE;
+    $this->seq[$end] = $ypos;
+    $this->in_seq[$ypos] = 1;
+    return $end;
+  }
+
+  /**
+   * Find LCS of two sequences.
+   *
+   * The results are recorded in the vectors $this->{x,y}changed[], by
+   * storing a 1 in the element for each line that is an insertion
+   * or deletion (ie. is not in the LCS).
+   *
+   * The subsequence of file 0 is [XOFF, XLIM) and likewise for file 1.
+   *
+   * Note that XLIM, YLIM are exclusive bounds.
+   * All line numbers are origin-0 and discarded lines are not counted.
+   */
+  function _compareseq($xoff, $xlim, $yoff, $ylim) {
+
+    // Slide down the bottom initial diagonal.
+    while ($xoff < $xlim && $yoff < $ylim && $this->xv[$xoff] == $this->yv[$yoff]) {
+      ++$xoff;
+      ++$yoff;
+    }
+
+    // Slide up the top initial diagonal.
+    while ($xlim > $xoff && $ylim > $yoff && $this->xv[$xlim - 1] == $this->yv[$ylim - 1]) {
+      --$xlim;
+      --$ylim;
+    }
+
+    if ($xoff == $xlim || $yoff == $ylim) {
+      $lcs = 0;
+    }
+    else {
+      // This is ad hoc but seems to work well.
+      //$nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
+      //$nchunks = max(2, min(8, (int)$nchunks));
+      $nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1;
+      list($lcs, $seps)
+      = $this->_diag($xoff, $xlim, $yoff, $ylim, $nchunks);
+    }
+
+    if ($lcs == 0) {
+      // X and Y sequences have no common subsequence:
+      // mark all changed.
+      while ($yoff < $ylim) {
+        $this->ychanged[$this->yind[$yoff++]] = 1;
+      }
+      while ($xoff < $xlim) {
+        $this->xchanged[$this->xind[$xoff++]] = 1;
+      }
+    }
+    else {
+      // Use the partitions to split this problem into subproblems.
+      reset($seps);
+      $pt1 = $seps[0];
+      while ($pt2 = next($seps)) {
+        $this->_compareseq ($pt1[0], $pt2[0], $pt1[1], $pt2[1]);
+        $pt1 = $pt2;
+      }
+    }
+  }
+
+  /**
+   * Adjust inserts/deletes of identical lines to join changes
+   * as much as possible.
+   *
+   * We do something when a run of changed lines include a
+   * line at one end and has an excluded, identical line at the other.
+   * We are free to choose which identical line is included.
+   * `compareseq' usually chooses the one at the beginning,
+   * but usually it is cleaner to consider the following identical line
+   * to be the "change".
+   *
+   * This is extracted verbatim from analyze.c (GNU diffutils-2.7).
+   */
+  function _shift_boundaries($lines, &$changed, $other_changed) {
+    $i = 0;
+    $j = 0;
+
+    USE_ASSERTS && assert('sizeof($lines) == sizeof($changed)');
+    $len = sizeof($lines);
+    $other_len = sizeof($other_changed);
+
+    while (1) {
+      /*
+       * Scan forwards to find beginning of another run of changes.
+       * Also keep track of the corresponding point in the other file.
+       *
+       * Throughout this code, $i and $j are adjusted together so that
+       * the first $i elements of $changed and the first $j elements
+       * of $other_changed both contain the same number of zeros
+       * (unchanged lines).
+       * Furthermore, $j is always kept so that $j == $other_len or
+       * $other_changed[$j] == FALSE.
+       */
+      while ($j < $other_len && $other_changed[$j]) {
+        $j++;
+      }
+      while ($i < $len && ! $changed[$i]) {
+        USE_ASSERTS && assert('$j < $other_len && ! $other_changed[$j]');
+        $i++;
+        $j++;
+        while ($j < $other_len && $other_changed[$j]) {
+          $j++;
+        }
+      }
+
+      if ($i == $len) {
+        break;
+      }
+      $start = $i;
+
+      // Find the end of this run of changes.
+      while (++$i < $len && $changed[$i]) {
+        continue;
+      }
+
+      do {
+        /*
+         * Record the length of this run of changes, so that
+         * we can later determine whether the run has grown.
+         */
+        $runlength = $i - $start;
+
+        /*
+         * Move the changed region back, so long as the
+         * previous unchanged line matches the last changed one.
+         * This merges with previous changed regions.
+         */
+        while ($start > 0 && $lines[$start - 1] == $lines[$i - 1]) {
+          $changed[--$start] = 1;
+          $changed[--$i] = FALSE;
+          while ($start > 0 && $changed[$start - 1]) {
+            $start--;
+          }
+          USE_ASSERTS && assert('$j > 0');
+          while ($other_changed[--$j]) {
+            continue;
+          }
+          USE_ASSERTS && assert('$j >= 0 && !$other_changed[$j]');
+        }
+
+        /*
+         * Set CORRESPONDING to the end of the changed run, at the last
+         * point where it corresponds to a changed run in the other file.
+         * CORRESPONDING == LEN means no such point has been found.
+         */
+        $corresponding = $j < $other_len ? $i : $len;
+
+        /*
+         * Move the changed region forward, so long as the
+         * first changed line matches the following unchanged one.
+         * This merges with following changed regions.
+         * Do this second, so that if there are no merges,
+         * the changed region is moved forward as far as possible.
+         */
+        while ($i < $len && $lines[$start] == $lines[$i]) {
+          $changed[$start++] = FALSE;
+          $changed[$i++] = 1;
+          while ($i < $len && $changed[$i]) {
+            $i++;
+          }
+          USE_ASSERTS && assert('$j < $other_len && ! $other_changed[$j]');
+          $j++;
+          if ($j < $other_len && $other_changed[$j]) {
+            $corresponding = $i;
+            while ($j < $other_len && $other_changed[$j]) {
+              $j++;
+            }
+          }
+        }
+      } while ($runlength != $i - $start);
+
+      /*
+       * If possible, move the fully-merged run of changes
+       * back to a corresponding run in the other file.
+       */
+      while ($corresponding < $i) {
+        $changed[--$start] = 1;
+        $changed[--$i] = 0;
+        USE_ASSERTS && assert('$j > 0');
+        while ($other_changed[--$j]) {
+          continue;
+        }
+        USE_ASSERTS && assert('$j >= 0 && !$other_changed[$j]');
+      }
+    }
+  }
+}
+
+/**
+ * Class representing a 'diff' between two sequences of strings.
+ * @todo document
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class Diff {
+  var $edits;
+
+  /**
+   * Constructor.
+   * Computes diff between sequences of strings.
+   *
+   * @param $from_lines array An array of strings.
+   *      (Typically these are lines from a file.)
+   * @param $to_lines array An array of strings.
+   */
+  function Diff($from_lines, $to_lines) {
+    $eng = new _DiffEngine;
+    $this->edits = $eng->diff($from_lines, $to_lines);
+    //$this->_check($from_lines, $to_lines);
+  }
+
+  /**
+   * Compute reversed Diff.
+   *
+   * SYNOPSIS:
+   *
+   *  $diff = new Diff($lines1, $lines2);
+   *  $rev = $diff->reverse();
+   * @return object A Diff object representing the inverse of the
+   *          original diff.
+   */
+  function reverse() {
+    $rev = $this;
+    $rev->edits = array();
+    foreach ($this->edits as $edit) {
+      $rev->edits[] = $edit->reverse();
+    }
+    return $rev;
+  }
+
+  /**
+   * Check for empty diff.
+   *
+   * @return bool True iff two sequences were identical.
+   */
+  function isEmpty() {
+    foreach ($this->edits as $edit) {
+      if ($edit->type != 'copy') {
+        return FALSE;
+      }
+    }
+    return TRUE;
+  }
+
+  /**
+   * Compute the length of the Longest Common Subsequence (LCS).
+   *
+   * This is mostly for diagnostic purposed.
+   *
+   * @return int The length of the LCS.
+   */
+  function lcs() {
+    $lcs = 0;
+    foreach ($this->edits as $edit) {
+      if ($edit->type == 'copy') {
+        $lcs += sizeof($edit->orig);
+      }
+    }
+    return $lcs;
+  }
+
+  /**
+   * Get the original set of lines.
+   *
+   * This reconstructs the $from_lines parameter passed to the
+   * constructor.
+   *
+   * @return array The original sequence of strings.
+   */
+  function orig() {
+    $lines = array();
+
+    foreach ($this->edits as $edit) {
+      if ($edit->orig) {
+        array_splice($lines, sizeof($lines), 0, $edit->orig);
+      }
+    }
+    return $lines;
+  }
+
+  /**
+   * Get the closing set of lines.
+   *
+   * This reconstructs the $to_lines parameter passed to the
+   * constructor.
+   *
+   * @return array The sequence of strings.
+   */
+  function closing() {
+    $lines = array();
+
+    foreach ($this->edits as $edit) {
+      if ($edit->closing) {
+        array_splice($lines, sizeof($lines), 0, $edit->closing);
+      }
+    }
+    return $lines;
+  }
+
+  /**
+   * Check a Diff for validity.
+   *
+   * This is here only for debugging purposes.
+   */
+  function _check($from_lines, $to_lines) {
+    if (serialize($from_lines) != serialize($this->orig())) {
+      trigger_error("Reconstructed original doesn't match", E_USER_ERROR);
+    }
+    if (serialize($to_lines) != serialize($this->closing())) {
+      trigger_error("Reconstructed closing doesn't match", E_USER_ERROR);
+    }
+
+    $rev = $this->reverse();
+    if (serialize($to_lines) != serialize($rev->orig())) {
+      trigger_error("Reversed original doesn't match", E_USER_ERROR);
+    }
+    if (serialize($from_lines) != serialize($rev->closing())) {
+      trigger_error("Reversed closing doesn't match", E_USER_ERROR);
+    }
+
+
+    $prevtype = 'none';
+    foreach ($this->edits as $edit) {
+      if ( $prevtype == $edit->type ) {
+        trigger_error("Edit sequence is non-optimal", E_USER_ERROR);
+      }
+      $prevtype = $edit->type;
+    }
+
+    $lcs = $this->lcs();
+    trigger_error('Diff okay: LCS = ' . $lcs, E_USER_NOTICE);
+  }
+}
+
+/**
+ * FIXME: bad name.
+ * @todo document
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class MappedDiff extends Diff {
+  /**
+   * Constructor.
+   *
+   * Computes diff between sequences of strings.
+   *
+   * This can be used to compute things like
+   * case-insensitve diffs, or diffs which ignore
+   * changes in white-space.
+   *
+   * @param $from_lines array An array of strings.
+   *  (Typically these are lines from a file.)
+   *
+   * @param $to_lines array An array of strings.
+   *
+   * @param $mapped_from_lines array This array should
+   *  have the same size number of elements as $from_lines.
+   *  The elements in $mapped_from_lines and
+   *  $mapped_to_lines are what is actually compared
+   *  when computing the diff.
+   *
+   * @param $mapped_to_lines array This array should
+   *  have the same number of elements as $to_lines.
+   */
+  function MappedDiff($from_lines, $to_lines, $mapped_from_lines, $mapped_to_lines) {
+
+    assert(sizeof($from_lines) == sizeof($mapped_from_lines));
+    assert(sizeof($to_lines) == sizeof($mapped_to_lines));
+
+    $this->Diff($mapped_from_lines, $mapped_to_lines);
+
+    $xi = $yi = 0;
+    for ($i = 0; $i < sizeof($this->edits); $i++) {
+      $orig = &$this->edits[$i]->orig;
+      if (is_array($orig)) {
+        $orig = array_slice($from_lines, $xi, sizeof($orig));
+        $xi += sizeof($orig);
+      }
+
+      $closing = &$this->edits[$i]->closing;
+      if (is_array($closing)) {
+        $closing = array_slice($to_lines, $yi, sizeof($closing));
+        $yi += sizeof($closing);
+      }
+    }
+  }
+}
+
+/**
+ * A class to format Diffs
+ *
+ * This class formats the diff in classic diff format.
+ * It is intended that this class be customized via inheritance,
+ * to obtain fancier outputs.
+ * @todo document
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class DiffFormatter {
+  /**
+   * Should a block header be shown?
+   */
+  var $show_header = TRUE;
+
+  /**
+   * Number of leading context "lines" to preserve.
+   *
+   * This should be left at zero for this class, but subclasses
+   * may want to set this to other values.
+   */
+  var $leading_context_lines = 0;
+
+  /**
+   * Number of trailing context "lines" to preserve.
+   *
+   * This should be left at zero for this class, but subclasses
+   * may want to set this to other values.
+   */
+  var $trailing_context_lines = 0;
+
+  /**
+   * Format a diff.
+   *
+   * @param $diff object A Diff object.
+   * @return string The formatted output.
+   */
+  function format($diff) {
+    $xi = $yi = 1;
+    $block = FALSE;
+    $context = array();
+
+    $nlead = $this->leading_context_lines;
+    $ntrail = $this->trailing_context_lines;
+
+    $this->_start_diff();
+
+    foreach ($diff->edits as $edit) {
+      if ($edit->type == 'copy') {
+        if (is_array($block)) {
+          if (sizeof($edit->orig) <= $nlead + $ntrail) {
+            $block[] = $edit;
+          }
+          else {
+            if ($ntrail) {
+              $context = array_slice($edit->orig, 0, $ntrail);
+              $block[] = new _DiffOp_Copy($context);
+            }
+            $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
+            $block = FALSE;
+          }
+        }
+        $context = $edit->orig;
+      }
+      else {
+        if (! is_array($block)) {
+          $context = array_slice($context, sizeof($context) - $nlead);
+          $x0 = $xi - sizeof($context);
+          $y0 = $yi - sizeof($context);
+          $block = array();
+          if ($context) {
+            $block[] = new _DiffOp_Copy($context);
+          }
+        }
+        $block[] = $edit;
+      }
+
+      if ($edit->orig) {
+        $xi += sizeof($edit->orig);
+      }
+      if ($edit->closing) {
+        $yi += sizeof($edit->closing);
+      }
+    }
+
+    if (is_array($block)) {
+      $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
+    }
+    $end = $this->_end_diff();
+
+    if (!empty($xi)) {
+      $this->line_stats['counter']['x'] += $xi;
+    }
+    if (!empty($yi)) {
+      $this->line_stats['counter']['y'] += $yi;
+    }
+
+    return $end;
+  }
+
+  function _block($xbeg, $xlen, $ybeg, $ylen, &$edits) {
+    $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen));
+    foreach ($edits as $edit) {
+      if ($edit->type == 'copy') {
+        $this->_context($edit->orig);
+      }
+      elseif ($edit->type == 'add') {
+        $this->_added($edit->closing);
+      }
+      elseif ($edit->type == 'delete') {
+        $this->_deleted($edit->orig);
+      }
+      elseif ($edit->type == 'change') {
+        $this->_changed($edit->orig, $edit->closing);
+      }
+      else {
+        trigger_error('Unknown edit type', E_USER_ERROR);
+      }
+    }
+    $this->_end_block();
+  }
+
+  function _start_diff() {
+    ob_start();
+  }
+
+  function _end_diff() {
+    $val = ob_get_contents();
+    ob_end_clean();
+    return $val;
+  }
+
+  function _block_header($xbeg, $xlen, $ybeg, $ylen) {
+    if ($xlen > 1) {
+      $xbeg .= "," . ($xbeg + $xlen - 1);
+    }
+    if ($ylen > 1) {
+      $ybeg .= "," . ($ybeg + $ylen - 1);
+    }
+
+    return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
+  }
+
+  function _start_block($header) {
+    if ($this->show_header) {
+      echo $header . "\n";
+    }
+  }
+
+  function _end_block() {
+  }
+
+  function _lines($lines, $prefix = ' ') {
+    foreach ($lines as $line) {
+      echo "$prefix $line\n";
+    }
+  }
+
+  function _context($lines) {
+    $this->_lines($lines);
+  }
+
+  function _added($lines) {
+    $this->_lines($lines, '>');
+  }
+  function _deleted($lines) {
+    $this->_lines($lines, '<');
+  }
+
+  function _changed($orig, $closing) {
+    $this->_deleted($orig);
+    echo "---\n";
+    $this->_added($closing);
+  }
+}
+
+
+/**
+ *  Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3
+ *
+ */
+
+define('NBSP', '&#160;');      // iso-8859-x non-breaking space.
+
+/**
+ * @todo document
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class _HWLDF_WordAccumulator {
+  function _HWLDF_WordAccumulator() {
+    $this->_lines = array();
+    $this->_line = '';
+    $this->_group = '';
+    $this->_tag = '';
+  }
+
+  function _flushGroup($new_tag) {
+    if ($this->_group !== '') {
+      if ($this->_tag == 'mark') {
+        $this->_line .= '<span class="diffchange">' . check_plain($this->_group) . '</span>';
+      }
+      else {
+        $this->_line .= check_plain($this->_group);
+      }
+    }
+    $this->_group = '';
+    $this->_tag = $new_tag;
+  }
+
+  function _flushLine($new_tag) {
+    $this->_flushGroup($new_tag);
+    if ($this->_line != '') {
+      array_push($this->_lines, $this->_line);
+    }
+    else {
+      // make empty lines visible by inserting an NBSP
+      array_push($this->_lines, NBSP);
+    }
+    $this->_line = '';
+  }
+
+  function addWords($words, $tag = '') {
+    if ($tag != $this->_tag) {
+      $this->_flushGroup($tag);
+    }
+    foreach ($words as $word) {
+      // new-line should only come as first char of word.
+      if ($word == '') {
+        continue;
+      }
+      if ($word[0] == "\n") {
+        $this->_flushLine($tag);
+        $word = drupal_substr($word, 1);
+      }
+      assert(!strstr($word, "\n"));
+      $this->_group .= $word;
+    }
+  }
+
+  function getLines() {
+    $this->_flushLine('~done');
+    return $this->_lines;
+  }
+}
+
+/**
+ * @todo document
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class WordLevelDiff extends MappedDiff {
+  function MAX_LINE_LENGTH() {
+    return 10000;
+  }
+
+  function WordLevelDiff($orig_lines, $closing_lines) {
+    list($orig_words, $orig_stripped) = $this->_split($orig_lines);
+    list($closing_words, $closing_stripped) = $this->_split($closing_lines);
+
+    $this->MappedDiff($orig_words, $closing_words, $orig_stripped, $closing_stripped);
+  }
+
+  function _split($lines) {
+    $words = array();
+    $stripped = array();
+    $first = TRUE;
+    foreach ($lines as $line) {
+      // If the line is too long, just pretend the entire line is one big word
+      // This prevents resource exhaustion problems
+      if ( $first ) {
+        $first = FALSE;
+      }
+      else {
+        $words[] = "\n";
+        $stripped[] = "\n";
+      }
+      if ( drupal_strlen( $line ) > $this->MAX_LINE_LENGTH() ) {
+        $words[] = $line;
+        $stripped[] = $line;
+      }
+      else {
+        if (preg_match_all('/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xs', $line, $m)) {
+          $words = array_merge($words, $m[0]);
+          $stripped = array_merge($stripped, $m[1]);
+        }
+      }
+    }
+    return array($words, $stripped);
+  }
+
+  function orig() {
+    $orig = new _HWLDF_WordAccumulator;
+
+    foreach ($this->edits as $edit) {
+      if ($edit->type == 'copy') {
+        $orig->addWords($edit->orig);
+      }
+      elseif ($edit->orig) {
+        $orig->addWords($edit->orig, 'mark');
+      }
+    }
+    $lines = $orig->getLines();
+    return $lines;
+  }
+
+  function closing() {
+    $closing = new _HWLDF_WordAccumulator;
+
+    foreach ($this->edits as $edit) {
+      if ($edit->type == 'copy') {
+        $closing->addWords($edit->closing);
+      }
+      elseif ($edit->closing) {
+        $closing->addWords($edit->closing, 'mark');
+      }
+    }
+    $lines = $closing->getLines();
+    return $lines;
+  }
+}
+
+/**
+ * Diff formatter which uses Drupal theme functions.
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class DrupalDiffFormatter extends DiffFormatter {
+
+  var $rows;
+  var $line_stats = array(
+    'counter' => array('x' => 0, 'y' => 0),
+    'offset' => array('x' => 0, 'y' => 0),
+  );
+
+  function DrupalDiffFormatter() {
+    $this->leading_context_lines = variable_get('diff_context_lines_leading', 2);
+    $this->trailing_context_lines = variable_get('diff_context_lines_trailing', 2);
+  }
+
+  function _start_diff() {
+    $this->rows = array();
+  }
+
+  function _end_diff() {
+    return $this->rows;
+  }
+
+  function _block_header($xbeg, $xlen, $ybeg, $ylen) {
+    return array(
+      array(
+        'data' => theme('diff_header_line', array('lineno' => $xbeg + $this->line_stats['offset']['x'])),
+        'colspan' => 2,
+      ),
+      array(
+        'data' => theme('diff_header_line', array('lineno' => $ybeg + $this->line_stats['offset']['y'])),
+        'colspan' => 2,
+      )
+    );
+  }
+
+  function _start_block($header) {
+    if ($this->show_header) {
+      $this->rows[] = $header;
+    }
+  }
+
+  function _end_block() {
+  }
+
+  function _lines($lines, $prefix=' ', $color='white') {
+  }
+
+  /**
+   * Note: you should HTML-escape parameter before calling this.
+   */
+  function addedLine($line) {
+    return array(
+      array(
+        'data' => '+',
+        'class' => 'diff-marker',
+      ),
+      array(
+        'data' => theme('diff_content_line', array('line' => $line)),
+        'class' => 'diff-context diff-addedline',
+      )
+    );
+  }
+
+  /**
+   * Note: you should HTML-escape parameter before calling this.
+   */
+  function deletedLine($line) {
+    return array(
+      array(
+        'data' => '-',
+        'class' => 'diff-marker',
+      ),
+      array(
+        'data' => theme('diff_content_line', array('line' => $line)),
+        'class' => 'diff-context diff-deletedline',
+      )
+    );
+  }
+
+  /**
+   * Note: you should HTML-escape parameter before calling this.
+   */
+  function contextLine($line) {
+    return array(
+      '&nbsp;',
+      array(
+        'data' => theme('diff_content_line', array('line' => $line)),
+        'class' => 'diff-context',
+      )
+    );
+  }
+
+  function emptyLine() {
+    return array(
+      '&nbsp;',
+      theme('diff_empty_line', array('line' => '&nbsp;')),
+    );
+  }
+
+  function _added($lines) {
+    foreach ($lines as $line) {
+      $this->rows[] = array_merge($this->emptyLine(), $this->addedLine(check_plain($line)));
+    }
+  }
+
+  function _deleted($lines) {
+    foreach ($lines as $line) {
+      $this->rows[] = array_merge($this->deletedLine(check_plain($line)), $this->emptyLine());
+    }
+  }
+
+  function _context($lines) {
+    foreach ($lines as $line) {
+      $this->rows[] = array_merge($this->contextLine(check_plain($line)), $this->contextLine(check_plain($line)));
+    }
+  }
+
+  function _changed($orig, $closing) {
+    $diff = new WordLevelDiff($orig, $closing);
+    $del = $diff->orig();
+    $add = $diff->closing();
+
+    // Notice that WordLevelDiff returns HTML-escaped output.
+    // Hence, we will be calling addedLine/deletedLine without HTML-escaping.
+
+    while ($line = array_shift($del)) {
+      $aline = array_shift( $add );
+      $this->rows[] = array_merge($this->deletedLine($line), isset($aline) ? $this->addedLine($aline) : $this->emptyLine());
+    }
+    foreach ($add as $line) {  // If any leftovers
+      $this->rows[] = array_merge($this->emptyLine(), $this->addedLine($line));
+    }
+  }
+}
+
+/**
+ * Drupal inline Diff formatter.
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class DrupalDiffInline {
+  var $a;
+  var $b;
+
+  /**
+   * Constructor.
+   */
+  function __construct($a, $b) {
+    $this->a = $a;
+    $this->b = $b;
+  }
+
+  /**
+   * Render differences inline using HTML markup.
+   */
+  function render() {
+    $a = preg_split('/(<[^>]+?>| )/', $this->a, -1, PREG_SPLIT_DELIM_CAPTURE);
+    $b = preg_split('/(<[^>]+?>| )/', $this->b, -1, PREG_SPLIT_DELIM_CAPTURE);
+    $diff = new Diff($a, $b);
+    $diff->edits = $this->process_edits($diff->edits);
+
+    // Assemble highlighted output
+    $output = '';
+    foreach ($diff->edits as $chunk) {
+      switch ($chunk->type) {
+        case 'copy':
+          $output .= implode('', $chunk->closing);
+          break;
+        case 'delete':
+          foreach ($chunk->orig as $i => $piece) {
+            if (strpos($piece, '<') === 0 && drupal_substr($piece, drupal_strlen($piece) - 1) === '>') {
+              $output .= $piece;
+            }
+            else {
+              $output .= theme('diff_inline_chunk', array('text' => $piece, 'type' => $chunk->type));
+            }
+          }
+          break;
+        default:
+          $chunk->closing = $this->process_chunk($chunk->closing);
+          foreach ($chunk->closing as $i => $piece) {
+            if ($piece === ' ' || (strpos($piece, '<') === 0 && drupal_substr($piece, drupal_strlen($piece) - 1) === '>' && drupal_strtolower(drupal_substr($piece, 1, 3)) != 'img')) {
+              $output .= $piece;
+            }
+            else {
+              $output .= theme('diff_inline_chunk', array('text' => $piece, 'type' => $chunk->type));
+            }
+          }
+          break;
+      }
+    }
+    return $output;
+  }
+
+  /**
+   * Merge chunk segments between tag delimiters.
+   */
+  function process_chunk($chunk) {
+    $processed = array();
+    $j = 0;
+    foreach ($chunk as $i => $piece) {
+      $next = isset($chunk[$i+1]) ? $chunk[$i+1] : NULL;
+      if (!isset($processed[$j])) {
+        $processed[$j] = '';
+      }
+      if (strpos($piece, '<') === 0 && drupal_substr($piece, drupal_strlen($piece) - 1) === '>') {
+        $processed[$j] = $piece;
+        $j++;
+      }
+      elseif (isset($next) && strpos($next, '<') === 0 && drupal_substr($next, drupal_strlen($next) - 1) === '>') {
+        $processed[$j] .= $piece;
+        $j++;
+      }
+      else {
+        $processed[$j] .= $piece;
+      }
+    }
+    return $processed;
+  }
+
+  /**
+   * Merge copy and equivalent edits into intelligible chunks.
+   */
+  function process_edits($edits) {
+    $processed = array();
+    $current = array_shift($edits);
+
+    // Make two passes -- first merge space delimiter copies back into their originals.
+    while ($chunk = array_shift($edits)) {
+      if ($chunk->type == 'copy' && $chunk->orig === array(' ')) {
+        $current->orig = array_merge((array) $current->orig, (array) $chunk->orig);
+        $current->closing = array_merge((array) $current->closing, (array) $chunk->closing);
+      }
+      else {
+        $processed[] = $current;
+        $current = $chunk;
+      }
+    }
+    $processed[] = $current;
+
+    // Initial setup
+    $edits = $processed;
+    $processed = array();
+    $current = array_shift($edits);
+
+    // Second, merge equivalent chunks into each other.
+    while ($chunk = array_shift($edits)) {
+      if ($current->type == $chunk->type) {
+        $current->orig = array_merge((array) $current->orig, (array) $chunk->orig);
+        $current->closing = array_merge((array) $current->closing, (array) $chunk->closing);
+      }
+      else {
+        $processed[] = $current;
+        $current = $chunk;
+      }
+    }
+    $processed[] = $current;
+
+    return $processed;
+  }
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/LICENSE.txt b/profiles/wcm_base/modules/contrib/diff/LICENSE.txt
new file mode 100644
index 00000000..d159169d
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/LICENSE.txt
@@ -0,0 +1,339 @@
+                    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.)
+
+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
+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
+
+            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/profiles/wcm_base/modules/contrib/diff/css/diff.boxes.css b/profiles/wcm_base/modules/contrib/diff/css/diff.boxes.css
new file mode 100644
index 00000000..ee1b3116
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/css/diff.boxes.css
@@ -0,0 +1,124 @@
+
+html.js .diff-js-hidden { display: none; }
+
+/* Reset as many core themes as possible */
+table.diff {
+  font-size: 0.923em;
+  margin: 0 0 10px;
+  border: 0 none;
+  width: 98%;
+  border-spacing: 5px;
+  table-layout: fixed ;
+  border-collapse: separate;
+}
+table.diff tr td:last-child {
+  border-right: inherit;
+}
+table.diff td,
+table.diff th {
+  vertical-align: middle;
+  border: 0 none;
+  color: #000;
+  text-transform: none;
+  background: none;
+  border-spacing: 4px;
+  padding: 4px 8px;
+}
+table.diff tr, table.diff tr.even {
+  background: none;
+}
+table.diff tr th, table.diff tr th a, table.diff tr th a:hover {
+  color: inherit;
+  font-weight: bold;
+}
+table.diff tr.even,
+table.diff tr.odd {
+  border-width: 0;
+  border-style: none;
+  background: transparent;
+}
+table.diff th a { display: inline; }
+
+/* Main theming */
+table.diff, td.diff-number {
+  background-color: white
+}
+
+table.diff td.diff-lineno {
+  font-weight: bold
+}
+
+table.diff td.diff-addedline, table.diff td.diff-deletedline, table.diff td.diff-context {
+  font-size: 88%;
+  vertical-align: top;
+  white-space: -moz-pre-wrap;
+  white-space: pre-wrap
+}
+
+table.diff td.diff-addedline, table.diff td.diff-deletedline {
+  border-style: solid;
+  border-width: 1px 1px 1px 4px;
+  border-radius: 0.33em
+}
+
+table.diff td.diff-context {
+  background: #f3f3f3;
+  color: #333333;
+  border-style: solid;
+  border-width: 1px 1px 1px 4px;
+  border-color: #e6e6e6;
+  border-radius: 0.33em;
+}
+table.diff td.diff-addedline {
+  border-color: #a3d3ff;
+  background: #ffffff;
+  border: 1px 1px 1px 3px;
+}
+
+table.diff td.diff-deletedline {
+  border-color: #ffe49c
+}
+
+.diffchange {
+  font-weight: bold;
+  text-decoration: none
+}
+
+table.diff td.diff-addedline .diffchange, table.diff td.diff-deletedline .diffchange {
+  border-radius: 0.33em;
+  padding: 0.25em 0
+}
+
+table.diff td.diff-addedline .diffchange {
+  background: #d8ecff
+}
+
+table.diff td.diff-deletedline .diffchange {
+  background: #feeec8
+}
+
+table.diff table.diff td {
+  padding: 0.33em 0.66em
+}
+
+table.diff td.diff-marker {
+  width: 2%;
+  text-align: right;
+  font-weight: bold;
+  font-size: 1.25em  
+}
+
+table.diff col.diff-content {
+  width: 48%
+}
+
+table.diff table.diff td div {
+  word-wrap: break-word;
+  overflow: auto
+}
+td.diff-prevlink {
+  text-align: left;
+}
+td.diff-nextlink {
+  text-align: right;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/css/diff.default.css b/profiles/wcm_base/modules/contrib/diff/css/diff.default.css
new file mode 100644
index 00000000..a7ab7ffd
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/css/diff.default.css
@@ -0,0 +1,86 @@
+
+html.js .diff-js-hidden { display: none; }
+
+/**
+ * Inline diff metadata
+ */
+.diff-inline-metadata {
+  padding:4px;
+  border:1px solid #ddd;
+  background:#fff;
+  margin:0px 0px 10px;
+}
+
+.diff-inline-legend { font-size:11px; }
+
+.diff-inline-legend span,
+.diff-inline-legend label { margin-right:5px; }
+
+/**
+ * Inline diff markup
+ */
+span.diff-deleted { color:#ccc; }
+span.diff-deleted img { border: solid 2px #ccc; }
+span.diff-changed { background:#ffb; }
+span.diff-changed img { border:solid 2px #ffb; }
+span.diff-added { background:#cfc; }
+span.diff-added img { border: solid 2px #cfc; }
+
+/**
+ * Traditional split diff theming
+ */
+table.diff {
+  border-spacing: 4px;
+  margin-bottom: 20px;
+  table-layout: fixed;
+  width: 100%;
+}
+table.diff tr.even, table.diff tr.odd {
+  background-color: inherit;
+  border: none;
+}
+td.diff-prevlink {
+  text-align: left;
+}
+td.diff-nextlink {
+  text-align: right;
+}
+td.diff-section-title, div.diff-section-title {
+  background-color: #f0f0ff;
+  font-size: 0.83em;
+  font-weight: bold;
+  padding: 0.1em 1em;
+}
+td.diff-context {
+  background-color: #fafafa;
+}
+td.diff-deletedline {
+  background-color: #ffa;
+  width: 50%;
+}
+td.diff-addedline {
+  background-color: #afa;
+  width: 50%;
+}
+span.diffchange {
+  color: #f00;
+  font-weight: bold;
+}
+
+table.diff col.diff-marker {
+  width: 1.4em;
+}
+table.diff col.diff-content {
+  width: 50%;
+}
+table.diff th {
+  padding-right: inherit;
+}
+table.diff td div {
+  overflow: auto;
+  padding: 0.1ex 0.5em;
+  word-wrap: break-word;
+}
+table.diff td {
+  padding: 0.1ex 0.4em;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/diff.admin.inc b/profiles/wcm_base/modules/contrib/diff/diff.admin.inc
new file mode 100644
index 00000000..a9df19ed
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/diff.admin.inc
@@ -0,0 +1,158 @@
+<?php
+
+/**
+ * @file
+ * Administration page callbacks and forms.
+ */
+
+/**
+ * General configuration form for controlling the diff behaviour.
+ */
+function diff_admin_settings($form, $form_state) {
+  $form['diff_theme'] = array(
+    '#type' => 'select',
+    '#title' => t('CSS options'),
+    '#default_value' => variable_get('diff_theme', 'default'),
+    '#options' => array(
+      'default' => t('Classic'),
+      'boxes' => t('Boxes'),
+    ),
+    '#empty_option' => t('- None -'),
+    '#description' => t('Alter the CSS used when displaying diff results.'),
+  );
+  $form['diff_default_state_node'] = array(
+    '#type' => 'select',
+    '#title' => t('Diff default state'),
+    '#default_value' => variable_get('diff_default_state_node', 'raw'),
+    '#options' => array(
+      'raw' => t('HTML view'),
+      'raw_plain' => t('Plain view'),
+    ),
+    '#empty_option' => t('- None -'),
+    '#description' => t('Default display to show when viewing a diff, html tags in diffed result or as plain text.'),
+  );
+  $form['diff_radio_behavior'] = array(
+    '#type' => 'select',
+    '#title' => t('Diff radio behavior'),
+    '#default_value' => variable_get('diff_radio_behavior', 'simple'),
+    '#options' => array(
+      'simple' => t('Simple exclusion'),
+      'linear' => t('Linear restrictions'),
+    ),
+    '#empty_option' => t('- None -'),
+    '#description' => t('<em>Simple exclusion</em> means that users will not be able to select the same revision, <em>Linear restrictions</em> means that users can only select older or newer revisions of the current selections.'),
+  );
+
+  $options = drupal_map_assoc(array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
+  $form['diff_context_lines_leading'] = array(
+    '#type' => 'select',
+    '#title' => t('Leading context lines'),
+    '#description' => t('This governs the number of unchanged leading context "lines" to preserve.'),
+    '#default_value' => variable_get('diff_context_lines_leading', 2),
+    '#options' => $options,
+  );
+  $form['diff_context_lines_trailing'] = array(
+    '#type' => 'select',
+    '#title' => t('Trailing context lines'),
+    '#description' => t('This governs the number of unchanged trailing context "lines" to preserve.'),
+    '#default_value' => variable_get('diff_context_lines_trailing', 2),
+    '#options' => $options,
+  );
+
+  return system_settings_form($form);
+}
+
+/**
+ * Global entity settings.
+ */
+function diff_admin_global_entity_settings($form, $form_state, $entity_type) {
+  $entity_info = entity_get_info($entity_type);
+  drupal_set_title(t('Diff settings for %entity_label entities', array('%entity_label' => $entity_info['label'])), PASS_THROUGH);
+  $form['diff_show_header_' . $entity_type] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show entity label header'),
+    '#default_value' => variable_get('diff_show_header_' . $entity_type, 1),
+  );
+  $form['diff_admin_path_' . $entity_type] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Treat diff pages as administrative'),
+    '#description' => t('Diff pages are treated as administrative pages by default, although it is up to each module to enforce this and to implement this optional setting.'),
+    '#default_value' => variable_get('diff_admin_path_' . $entity_type, 1),
+  );
+  return system_settings_form($form);
+}
+
+/**
+ * Menu callback - provides an overview of Diff support and global settings.
+ */
+function diff_admin_field_overview() {
+  $build['info'] = array(
+    '#markup' => '<p>' . t('This table provides a summary of the field type support found on the system. It is recommended that you use global settings whenever possible to configure field comparison settings.') . '</p>',
+  );
+
+  $header = array(t('Type'), t('Module'), t('Operations'));
+  $rows = array();
+
+  // Skip field types which have no widget types.
+  $field_types = field_info_field_types();
+  $widgets = array();
+  foreach (field_info_widget_types() as $name => $widget_type) {
+    foreach ($widget_type['field types'] as $widget_field_type) {
+      if (isset($field_types[$widget_field_type])) {
+        $widgets[$widget_field_type][$name] = $widget_type['label'];
+      }
+    }
+  }
+
+  foreach ($field_types as $field_name => $field_type) {
+    if (!empty($widgets[$field_name])) {
+      $row = array();
+      $row[] = t('@field_label (%field_type)', array(
+        '@field_label' => $field_type['label'],
+        '%field_type' => $field_name,
+      ));
+      $row[] = $field_type['module'];
+      $row[] = l(t('Global settings'), 'admin/config/content/diff/fields/' . $field_name);
+      $rows[] = $row;
+    }
+  }
+
+  $build['category_table'] = array(
+    '#theme' => 'table',
+    '#header' => $header,
+    '#rows' => $rows,
+    '#empty' => t('The system has no configurable fields.'),
+  );
+  return $build;
+}
+
+/**
+ * Menu form callback for the field settings.
+ */
+function diff_admin_global_field_settings($form, $form_state, $type) {
+  module_load_include('diff.inc', 'diff');
+
+  $field_types = field_info_field_types();
+  if (!isset($field_types[$type])) {
+    drupal_set_message(t('Invalid field type.'), 'error');
+    drupal_goto('admin/config/content/diff/fields');
+  }
+  $field_type = $field_types[$type];
+
+  // Set the title to give more context to this page.
+  drupal_set_title(t('Global settings for %label fields', array(
+    '%label' => $field_type['label'],
+  )), PASS_THROUGH);
+
+  $variable_name = "diff_{$field_type['module']}_field_{$type}_default_options";
+  $settings = variable_get($variable_name, array());
+  $settings = _diff_field_default_settings($field_type['module'], $type, $settings);
+  $func = $field_type['module'] . '_field_diff_options_form';
+  if (function_exists($func) && ($options_form = $func($type, $settings))) {
+    $form[$variable_name] = $options_form;
+  }
+  $form[$variable_name]['#tree'] = TRUE;
+
+  diff_global_settings_form($form[$variable_name], $form_state, $type, $settings);
+  return system_settings_form($form);
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/diff.api.php b/profiles/wcm_base/modules/contrib/diff/diff.api.php
new file mode 100644
index 00000000..507293a1
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/diff.api.php
@@ -0,0 +1,181 @@
+<?php
+
+/**
+ * @file
+ * Hooks provided by the diff module.
+ */
+
+/**
+ * @addtogroup hooks
+ * @{
+ */
+
+/**
+ * Allow modules to provide a comparison about entities.
+ *
+ * @param object $old_entity
+ *   The older entity revision.
+ * @param object $new_entity
+ *   The newer entity revision.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
+ *   - view_mode: The view mode to use. Defaults to FALSE.
+ *
+ * @return array
+ *   An associative array of values keyed by the entity property.
+ *
+ * @todo
+ *   Investiagate options and document these.
+ */
+function hook_entity_diff($old_entity, $new_entity, $context) {
+  if ($context['entity_type'] == 'node') {
+    $type = node_type_get_type($new_entity);
+    $result['title'] = array(
+      '#name' => $type->title_label,
+      '#old' => array($old_entity->title),
+      '#new' => array($new_entity->title),
+      '#weight' => -5,
+      '#settings' => array(
+        'show_header' => FALSE,
+      ),
+    );
+  }
+}
+
+/**
+ * Allow modules to alter a comparison about entities.
+ *
+ * @param array $entity_diffs
+ *   An array of entity differences.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
+ *   - old_entity: The older entity.
+ *   - new_entity: The newer entity.
+ *   - view_mode: The view mode to use. Defaults to FALSE.
+ *
+ * @see hook_entity_diff()
+ */
+function hook_entity_diff_alter($entity_diffs, $context) {
+}
+
+/**
+ * Callback to the module that defined the field to prepare items comparison.
+ *
+ * This allows the module to alter all items prior to rendering the comparative
+ * values. It is mainly used to bulk load entities to reduce overheads
+ * associated with loading entities individually.
+ *
+ * @param array $old_items
+ *   An array of field items from the older revision.
+ * @param array $new_items
+ *   An array of field items from the newer revision.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
+ *   - bundle: The bundle name.
+ *   - field: The field that the items belong to.
+ *   - instance: The instance that the items belong to.
+ *   - language: The language associated with $items.
+ *   - old_entity: The older entity.
+ *   - new_entity: The newer entity.
+ *
+ * @see MODULE_field_diff_view()
+ */
+function MODULE_field_diff_view_prepare(&$old_items, &$new_items, $context) {
+  $fids = array();
+  foreach (array_merge_recursive($old_items, $new_items) as $info) {
+    $fids[$info['fid']] = $info['fid'];
+  }
+  // A single load is much faster than individual loads.
+  $files = file_load_multiple($fids);
+
+  // For ease of processing, store a reference of the entity on the item array.
+  foreach ($old_items as $delta => $info) {
+    $old_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL;
+  }
+  foreach ($new_items as $delta => $info) {
+    $new_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL;
+  }
+}
+
+/**
+ * Callback to the module that defined the field to generate items comparisons.
+ *
+ * @param array $items
+ *   An array of field items from the entity.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity: The entity being compared.
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
+ *   - bundle: The bundle name.
+ *   - field: The field that the items belong to.
+ *   - instance: The instance that the items belong to.
+ *   - language: The language associated with $items.
+ *   - old_entity: The older entity.
+ *   - new_entity: The newer entity.
+ *
+ * @see MODULE_field_diff_view_prepare()
+ */
+function MODULE_field_diff_view($items, $context) {
+  $diff_items = array();
+  foreach ($items as $delta => $item) {
+    if (isset($item['file'])) {
+      $diff_items[$delta] = $item['file']->filename . ' [fid: ' . $item['fid'] . ']';
+    }
+  }
+
+  return $diff_items;
+}
+
+/**
+ * Allow other modules to interact with MODULE_field_diff_view_prepare().
+ *
+ * @param array $old_items
+ *   An array of field items from the older revision.
+ * @param array $new_items
+ *   An array of field items from the newer revision.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
+ *   - bundle: The bundle name.
+ *   - field: The field that the items belong to.
+ *   - instance: The instance that the items belong to.
+ *   - language: The language associated with $items.
+ *   - old_entity: The older entity.
+ *   - new_entity: The newer entity.
+ *
+ * @see MODULE_field_diff_view_prepare()
+ */
+function hook_field_diff_view_prepare_alter($old_items, $new_items, $context) {
+
+}
+
+/**
+ * Allow other modules to interact with MODULE_field_diff_view().
+ *
+ * @param array $values
+ *   An array of field items from the entity ready for comparison.
+ * @param array $items
+ *   An array of field items from the entity.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity: The entity being compared.
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
+ *   - bundle: The bundle name.
+ *   - field: The field that the items belong to.
+ *   - instance: The instance that the items belong to.
+ *   - language: The language associated with $items.
+ *   - old_entity: The older entity.
+ *   - new_entity: The newer entity.
+ *
+ * @see MODULE_field_diff_view()
+ */
+function hook_field_diff_view_alter($values, $items, $context) {
+
+}
+
+/**
+ * @} End of "addtogroup hooks".
+ */
diff --git a/profiles/wcm_base/modules/contrib/diff/diff.css b/profiles/wcm_base/modules/contrib/diff/diff.css
new file mode 100644
index 00000000..a09147c1
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/diff.css
@@ -0,0 +1,86 @@
+
+html.js .diff-js-hidden { display:none; }
+
+/**
+ * Inline diff metadata
+ */
+.diff-inline-metadata {
+  padding:4px;
+  border:1px solid #ddd;
+  background:#fff;
+  margin:0px 0px 10px;
+  }
+
+.diff-inline-legend { font-size:11px; }
+
+.diff-inline-legend span,
+.diff-inline-legend label { margin-right:5px; }
+
+/**
+ * Inline diff markup
+ */
+span.diff-deleted { color:#ccc; }
+span.diff-deleted img { border: solid 2px #ccc; }
+span.diff-changed { background:#ffb; }
+span.diff-changed img { border:solid 2px #ffb; }
+span.diff-added { background:#cfc; }
+span.diff-added img { border: solid 2px #cfc; }
+
+/**
+ * Traditional split diff theming
+ */
+table.diff {
+  border-spacing: 4px;
+  margin-bottom: 20px;
+  table-layout: fixed;
+  width: 100%;
+}
+table.diff tr.even, table.diff tr.odd {
+  background-color: inherit;
+  border: none;
+}
+td.diff-prevlink {
+  text-align: left;
+}
+td.diff-nextlink {
+  text-align: right;
+}
+td.diff-section-title, div.diff-section-title {
+  background-color: #f0f0ff;
+  font-size: 0.83em;
+  font-weight: bold;
+  padding: 0.1em 1em;
+}
+td.diff-deletedline {
+  background-color: #ffa;
+  width: 50%;
+}
+td.diff-addedline {
+  background-color: #afa;
+  width: 50%;
+}
+td.diff-context {
+  background-color: #fafafa;
+}
+span.diffchange {
+  color: #f00;
+  font-weight: bold;
+}
+
+table.diff col.diff-marker {
+  width: 1.4em;
+}
+table.diff col.diff-content {
+  width: 50%;
+}
+table.diff th {
+  padding-right: inherit;
+}
+table.diff td div {
+  overflow: auto;
+  padding: 0.1ex 0.5em;
+  word-wrap: break-word;
+}
+table.diff td {
+  padding: 0.1ex 0.4em;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/diff.diff.inc b/profiles/wcm_base/modules/contrib/diff/diff.diff.inc
new file mode 100644
index 00000000..63c01b44
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/diff.diff.inc
@@ -0,0 +1,384 @@
+<?php
+
+/**
+ * @file
+ * Includes the hooks defined by diff_hook_info().
+ */
+
+/**
+ * Implements hook_entity_diff().
+ *
+ * Helper function to invoke the depreciated hook_diff() for node entities.
+ *
+ * This manually invokes hook_diff() to avoid a function name clash with the
+ * PHP 5 (>= 5.3.0) date_diff() function or the Dates modules implementation.
+ *
+ * @param object $old_entity
+ *   The older node revision.
+ * @param object $new_entity
+ *   The newer node revision.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
+ *   - old_entity: The older entity.
+ *   - new_entity: The newer entity.
+ *   - view_mode: The view mode to use. Defaults to FALSE.
+ */
+function diff_entity_diff($old_entity, $new_entity, $context) {
+  $return = array();
+
+  $entity_type = $context['entity_type'];
+  $info = entity_get_info($entity_type);
+  if (!empty($info['fieldable'])) {
+    $return = diff_entity_fields_diff($old_entity, $new_entity, $context);
+  }
+
+  return $return;
+}
+
+/**
+ * Internal callback to handle fieldable entities.
+ *
+ * Field comparison is handled for core modules, but is expandable to any other
+ * fields if the module defines MODULE_field_diff_view().
+ *
+ * @param object $old_entity
+ *   The older entity entity revision.
+ * @param object $new_entity
+ *   The newer entity entity revision.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
+ *   - old_entity: The older entity.
+ *   - new_entity: The newer entity.
+ *   - view_mode: The view mode to use. Defaults to FALSE.
+ *
+ * @return array
+ *   An associative array of values keyed by the field name and delta value.
+ */
+function diff_entity_fields_diff($old_entity, $new_entity, $context) {
+  $result = array();
+
+  $entity_type = $context['entity_type'];
+  $view_mode = $context['view_mode'];
+
+  $field_context = $context;
+
+  $actual_mode = FALSE;
+  list(,, $bundle_name) = entity_extract_ids($entity_type, $new_entity);
+  $instances = field_info_instances($entity_type, $bundle_name);
+
+  // Some fields piggy back the display settings, so we need to fake these by
+  // ensuring that the field mode is always set.
+  if (empty($view_mode)) {
+    $actual_mode = 'diff_standard';
+    $field_context['custom_settings'] = FALSE;
+  }
+  $view_mode_settings = field_view_mode_settings($entity_type, $bundle_name);
+  $actual_mode = (!empty($view_mode_settings[$view_mode]['custom_settings'])) ? $view_mode : 'default';
+  if (!isset($field_context['custom_settings'])) {
+    $field_context['custom_settings'] = $actual_mode && $actual_mode == $view_mode;
+  }
+
+  $field_context['old_entity'] = $old_entity;
+  $field_context['new_entity'] = $new_entity;
+  $field_context['bundle_name'] = $bundle_name;
+
+  foreach ($instances as $instance) {
+    // Any view mode is supported in relation to hiding fields, but only if
+    // selected (todo see if this is a valid option).
+    if ($actual_mode && $instance['display'][$actual_mode]['type'] == 'hidden') {
+      continue;
+    }
+    $field_name = $instance['field_name'];
+    $field = field_info_field($field_name);
+    $field_context['field'] = $field;
+    $field_context['instance'] = $instance;
+    $field_context['display'] = $instance['display'][$actual_mode];
+
+    // We provide a loose check on the field access.
+    if (field_access('view', $field, $entity_type) || field_access('edit', $field, $entity_type)) {
+      $langcode = field_language($entity_type, $new_entity, $field_name);
+
+      $field_context['language'] = $langcode;
+      $field_context['field'] = $field;
+      $field_context['instance'] = $instance;
+
+      $old_items = array();
+      if (!empty($old_entity->{$field_name}[$langcode])) {
+        $old_items = $old_entity->{$field_name}[$langcode];
+      }
+
+      $new_items = array();
+      if (!empty($new_entity->{$field_name}[$langcode])) {
+        $new_items = $new_entity->{$field_name}[$langcode];
+      }
+
+      // Load files containing the field callbacks.
+      _diff_autoload($field);
+
+      $field_context['settings'] = diff_get_field_settings($field_context);
+
+      // Reference fields can optionally prepare objects in bulk to reduce
+      // overheads related to multiple database calls. If a field considers
+      // that the delta values is meaningless, they can order and rearrange
+      // to provide cleaner results.
+      $func = $field['module'] . '_field_diff_view_prepare';
+      if (function_exists($func)) {
+        $func($old_items, $new_items, $field_context);
+      }
+      // Allow other modules to act safely on behalf of the core field module.
+      drupal_alter('field_diff_view_prepare', $old_items, $new_items, $field_context);
+
+      // These functions compiles the items into comparable arrays of strings.
+      $func = $field['module'] . '_field_diff_view';
+      if (!function_exists($func)) {
+        $func = 'diff_field_diff_view';
+      }
+
+      // These callbacks should be independent of revision.
+      $old_context = $field_context;
+      $old_context['entity'] = $old_entity;
+      $old_values = $func($old_items, $old_context);
+      $new_context = $field_context;
+      $new_context['entity'] = $new_entity;
+      $new_values = $func($new_items, $new_context);
+
+      // Allow other modules to act safely on behalf of the core field module.
+      drupal_alter('field_diff_view', $old_values, $old_items, $old_context);
+      drupal_alter('field_diff_view', $new_values, $new_items, $new_context);
+
+      $max = max(array(count($old_values), count($new_values)));
+      if ($max) {
+        $result[$field_name] = array(
+          '#name' => $instance['label'],
+          '#old' => array(),
+          '#new' => array(),
+          '#settings' => $field_context['settings'],
+        );
+        for ($delta = 0; $delta < $max; $delta++) {
+          if (isset($old_values[$delta])) {
+            $result[$field_name]['#old'][] = is_array($old_values[$delta]) ? implode("\n", $old_values[$delta]) : $old_values[$delta];
+          }
+          if (isset($new_values[$delta])) {
+            $result[$field_name]['#new'][] = is_array($new_values[$delta]) ? implode("\n", $new_values[$delta]) : $new_values[$delta];
+          }
+        }
+        $result[$field_name]['#old'] = implode("\n", $result[$field_name]['#old']);
+        $result[$field_name]['#new'] = implode("\n", $result[$field_name]['#new']);
+
+        if ($actual_mode) {
+          $result[$field_name]['#weight'] = $instance['display'][$actual_mode]['weight'];
+        }
+
+      }
+    }
+  }
+  return $result;
+}
+
+/**
+ * A generic handler for parsing field values.
+ *
+ * This callback can only handle the most basic of fields that populates the
+ * safe_value during field load or use the value column for data storage.
+ *
+ * @param array $items
+ *   An array of field items.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity: The entity that the items belong to.
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
+ *   - bundle: The bundle name.
+ *   - field: The field that the items belong to.
+ *   - instance: The instance that the items belong to.
+ *   - language: The language associated with $items.
+ *   - old_entity: The older entity.
+ *   - new_entity: The newer entity.
+ *
+ * @return array
+ *   An array of strings representing the value, keyed by delta index.
+ */
+function diff_field_diff_view($items, $context) {
+  $diff_items = array();
+   $entity = clone $context['entity'];
+   $langcode = field_language($context['entity_type'], $entity, $context['field']['field_name']);
+   $view_mode = empty($context['view_mode']) ? 'diff_standard' : $context['view_mode'];
+   $element = field_view_field($context['entity_type'], $entity, $context['field']['field_name'], $view_mode, $langcode);
+
+   foreach (element_children($element) as $delta) {
+     $diff_items[$delta] = drupal_render($element[$delta]);
+   }
+  return $diff_items;
+}
+
+/**
+ * Helper function to get the settings for a given field or formatter.
+ *
+ * @param array $context
+ *   This will get the settings for a field.
+ *   - field (required): The field that the items belong to.
+ *   - entity: The entity that we are looking up.
+ *   - instance: The instance that the items belong to.
+ *   - view_mode: The view mode to use. Defaults to FALSE.
+ *
+ * @return array
+ *   The settings for this field type.
+ */
+function diff_get_field_settings($field_context) {
+  $field = $field_context['field'];
+
+  // Update saved settings from the global settings for this field type.
+  $settings = variable_get("diff_{$field['module']}_field_{$field['type']}_default_options", array());
+
+  $settings = _diff_field_default_settings($field['module'], $field['type'], $settings);
+
+  // Allow modules to alter the field settings based on the current context.
+  drupal_alter('diff_field_settings', $settings, $field_context);
+
+  return $settings;
+}
+
+/**
+ * Helper function to initiate any global form elements.
+ */
+function diff_global_settings_form(&$subform, $form_state, $type, $settings) {
+  $subform['show_header'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show field title'),
+    '#default_value' => $settings['show_header'],
+    '#weight' => -5,
+  );
+  $subform['markdown'] = array(
+    '#type' => 'select',
+    '#title' => t('Markdown callback'),
+    '#default_value' => $settings['markdown'],
+    '#options' => array(
+      'drupal_html_to_text' => t('Drupal HTML to Text'),
+      'filter_xss' => t('Filter XSS (some tags)'),
+      'diff_filter_xss' => t('Filter XSS (all tags)'),
+    ),
+    '#description' => t('These provide ways to clean markup tags to make comparisons easier to read.'),
+    '#empty_option' => t('- Do not process -'),
+  );
+  $subform['line_counter'] = array(
+    '#type' => 'radios',
+    '#title' => t('Line counter'),
+    '#default_value' => $settings['line_counter'],
+    '#description' => t('This outputs the (approximate) line numbers as a heading before every change.'),
+    '#options' => array(
+      '' => t('None. Counter ignore and not incremented.'),
+      'hidden' => t('Count lines but do not show line headers.'),
+      'line' => t('Count and show lines, restarting counter at 0.'),
+      'line_continuous' => t('Count and show lines, incrementing counter from last item.'),
+    ),
+  );
+
+  /*
+This would be cool, but to do anything else than inline with the text appears
+to be very hard, requiring a refactoring of both the modules API but also the
+DiffFormatter and Diff classes. Diff 8.x-4.x maybe.
+
+  $subform['show_delta'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show delta values'),
+    '#default_value' => $settings['show_delta'],
+  );
+  $subform['delta_format'] = array(
+    '#type' => 'radios',
+    '#title' => t('Delta insertion method'),
+    '#default_value' => $settings['delta_format'],
+    '#options' => array(
+      'inline' => t('Prefix to item'),
+      'row' => t('Individual row'),
+    ),
+    '#states' => array(
+      'invisible' => array(
+        "input[id$='show-delta']" => array('checked' => FALSE),
+      ),
+    ),
+  );
+  */
+}
+
+/**
+ * Helper function to populate the settings array.
+ */
+function _diff_field_default_settings($module, $field_type, $settings = array()) {
+  // Load files containing the field callbacks.
+  _diff_autoload($module);
+
+  // Populate any missing values from CALLBACK_field_diff_default_options().
+  $func = $module . '_field_diff_default_options';
+  if (function_exists($func)) {
+    $settings += $func($field_type);
+  }
+
+  // Check for Diff support. If it doesn't exist, the default markdown should
+  // escape the field display, otherwise a raw format should be used.
+  $func = $module . '_field_diff_view';
+
+  // Global settings.
+  $settings += array(
+    'markdown' => function_exists($func) ? '' : 'drupal_html_to_text',
+    'line_counter' => '',
+    'show_header' => 1,
+    // Can we? This seems too hard to track in the DiffFormatter as all we
+    // have is a string or an array of strings.
+    //'show_delta' => 0,
+    //'delta_format' => 'row',
+  );
+  return $settings;
+}
+
+/**
+ * Private helper function to load field includes.
+ *
+ * @param array|string $field_or_module
+ *   The field definition array or the module that implements the field.
+ */
+function _diff_autoload($field_or_module) {
+  $includes = &drupal_static(__FUNCTION__, FALSE);
+  if (!$includes) {
+    $includes = array(
+      'file' => module_exists('file'),
+      'image' => module_exists('image'),
+      'list' => module_exists('list'),
+      'taxonomy' => module_exists('taxonomy'),
+      'text' => module_exists('text'),
+      'number' => module_exists('number'),
+    );
+  }
+
+  $module = is_string($field_or_module) ? $field_or_module : $field_or_module['module'];
+
+  // Since field hooks are not real hooks, we manually load the field modules
+  // MODULE.diff.inc. We handle the five core field defining modules.
+  if (!isset($includes[$module])) {
+    module_load_include('diff.inc', $module);
+    $includes[$module] = 0;
+  }
+  elseif (!empty($includes[$module])) {
+    module_load_include('inc', 'diff', 'includes/' . $module);
+    $includes[$module] = 0;
+  }
+}
+
+/**
+ * Helper function to parse out the state in the diff results.
+ */
+function diff_extract_state($diff, $state = 'raw') {
+  $states = array(
+    0 => NULL,
+    1 => NULL,
+  );
+  if (isset($diff['#states'][$state])) {
+    if (isset($diff['#states'][$state]['#old'])) {
+      $states[0] = $diff['#states'][$state]['#old'];
+    }
+    if (isset($diff['#states'][$state]['#new'])) {
+      $states[1] = $diff['#states'][$state]['#new'];
+    }
+  }
+  return $states;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/diff.info b/profiles/wcm_base/modules/contrib/diff/diff.info
new file mode 100644
index 00000000..5ae077e8
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/diff.info
@@ -0,0 +1,12 @@
+name = Diff
+description = Show differences between content revisions.
+core = 7.x
+
+files[] = DiffEngine.php
+
+; Information added by drupal.org packaging script on 2012-11-13
+version = "7.x-3.2"
+core = "7.x"
+project = "diff"
+datestamp = "1352784357"
+
diff --git a/profiles/wcm_base/modules/contrib/diff/diff.install b/profiles/wcm_base/modules/contrib/diff/diff.install
new file mode 100644
index 00000000..16f1d27c
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/diff.install
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * @file
+ * Provides uninstallation functions.
+ */
+
+/**
+ * Implements hook_uninstall().
+ */
+function diff_uninstall() {
+  // Bulk delete entity based variables.
+  $prefixes = array(
+    'diff_enable_revisions_page_',
+    'diff_show_',
+    'diff_view_mode_',
+    'diff_admin_path_',
+    'diff_default_state_',
+  );
+  foreach ($prefixes as $prefix) {
+    db_delete('variable')
+      ->condition('name', db_like($prefix) . '%', 'LIKE')
+      ->execute();
+  }
+
+  // Delete global variables.
+  variable_del('diff_context_lines_trailing');
+  variable_del('diff_context_lines_leading');
+  variable_del('diff_theme');
+  variable_del('diff_radio_behavior', '');
+
+  foreach (field_info_fields() as $field) {
+    variable_del("diff_{$field['module']}_field_{$field['type']}_default_options");
+  }
+}
+
+/**
+ * Updates the existing system variables to target the entity type and bundle.
+ */
+function diff_update_7300() {
+  $node_types = array_keys(node_type_get_types());
+  foreach ($node_types as $bundle) {
+    $type_variables = array(
+      'show_preview_changes',
+      'enable_revisions_page',
+      'show_diff_inline',
+    );
+    foreach ($type_variables as $prefix) {
+      $setting = variable_get($prefix . '_' . $bundle, NULL);
+      if (isset($setting)) {
+        variable_del($prefix . '_' . $bundle);
+        variable_set('diff_' . $prefix . '_node_' . $bundle, $setting);
+      }
+    }
+  }
+}
+
+/**
+ * Removed diff_update_7301().
+ */
+
+/**
+ * Removed diff_update_7302().
+ */
+
+/**
+ * Renames some internal settings names.
+ */
+function diff_update_7303() {
+  // Get current values
+  $radio = variable_get('diff_script_revisioning', 'simple');
+  $leading = variable_get('diff_leading_context_lines', 2);
+  $trailing = variable_get('diff_trailing_context_lines', 2);
+  // Create new variable names
+  variable_set('diff_radio_behavior', $radio);
+  variable_set('diff_context_lines_leading', $leading);
+  variable_set('diff_context_lines_trailing', $trailing);
+  // Delete old variables
+  variable_del('diff_script_revisioning');
+  variable_del('diff_leading_context_lines');
+  variable_del('diff_trailing_context_lines');
+}
+
+/**
+ * Removes unused variable settings and merges inline diff block settings.
+ */
+function diff_update_7304() {
+  // This is now always applied to text fields.
+  variable_del('diff_normalise_text');
+
+  // Merge the content type settings for the inline diff block into a single variable.
+  // diff_update_7300() - show_diff_inline_TYPE to diff_show_diff_inline_node_TYPE
+  $node_types = array_keys(node_type_get_types());
+  $enabled_types = array();
+  foreach ($node_types as $node_type) {
+    if (variable_get('diff_show_diff_inline_node_' . $node_type, FALSE)) {
+      $enabled_types[$node_type] = $node_type;
+    }
+    variable_del('diff_show_diff_inline_node_' . $node_type);
+  }
+  variable_set('diff_show_diff_inline_node_bundles', $enabled_types);
+
+  // Warn users that these settings are altered.
+  drupal_set_message(t('Diff <em>Inline differences</em> content type settings are now located within the <em>Inline differences</em> block settings.'));
+}
+
+/**
+ * Updates to normalize the new view mode settings.
+ */
+function diff_update_7305() {
+  // Rebuild the menus.
+  variable_set('menu_rebuild_needed', TRUE);
+
+  // Removed the enforced entity view mode.
+  db_delete('variable')
+      ->condition('name', db_like('diff_view_mode_standard_node_') . '%', 'LIKE')
+      ->execute();
+
+  // Removes the configurable view mode for the inline diff block, as this
+  // is fairly meaningless and confusing to users.
+  db_delete('variable')
+      ->condition('name', db_like('diff_view_mode_inline_') . '%', 'LIKE')
+      ->execute();
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/diff.module b/profiles/wcm_base/modules/contrib/diff/diff.module
new file mode 100644
index 00000000..f58e1d72
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/diff.module
@@ -0,0 +1,623 @@
+<?php
+
+/**
+ * @file
+ * Provides functionality to show a diff between two node revisions.
+ */
+
+/**
+ * Number of items on one page of the revision list.
+ */
+define('REVISION_LIST_SIZE', 50);
+
+/**
+ * Exposed sorting options.
+ *
+ * No sorting means sorting by delta value for fields.
+ */
+define('DIFF_SORT_NONE', '0');
+
+/**
+ * Exposed sorting options.
+ *
+ * This normally sorts by the rendered comparison.
+ */
+define('DIFF_SORT_VALUE', '1');
+
+/**
+ * Exposed sorting options.
+ *
+ * It is up to the field / entity to decide how to handle the sort.
+ */
+define('DIFF_SORT_CUSTOM', '-1');
+
+/**
+ * Implements hook_help().
+ */
+function diff_help($path, $arg) {
+  switch ($path) {
+    case 'admin/help#diff':
+      $output = '<p>' . t('The Diff module replaces the normal <em>Revisions</em> node tab. Diff enhances the listing of revisions with an option to view the differences between any two content revisions. Access to this feature is controlled with the <em>View revisions</em> permission. The feature can be disabled for an entire content type on the content type configuration page. Diff also provides an optional <em>View changes</em> button while editing a node.') . '</p>';
+      return $output;
+    case 'node/%/revisions/%/view':
+      // The translated strings should match node_help('node/%/revisions').
+      return '<p>' . t('Revisions allow you to track differences between multiple versions of your content, and revert back to older versions.') . '</p>';
+    case 'node/%/revisions/view/%/%':
+      return '<p>' . t('Comparing two revisions:') . '</p>';
+  }
+}
+
+/**
+ * The various states that are available.
+ */
+function diff_available_states($entity_type = NULL) {
+  $states = array(
+    'raw' => t('Standard'),
+    'raw_plain' => t('Marked down'),
+  );
+
+  return $states;
+}
+
+/**
+ * Implements hook_menu().
+ *
+ * @todo: Review this.
+ */
+function diff_menu() {
+  /*
+   * By using MENU_LOCAL_TASK (and 'tab_parent') we can get the various
+   * revision-views to show the View|Edit|Revision-tabs of the node on top,
+   * and have the Revisions-tab open. To avoid creating/showing any extra tabs
+   * or sub-tabs (tasks below top level) for the various paths (i.e. "Diff",
+   * "Show latest" and "Show a specific revision") that need a revision-id (vid)
+   * parameter, we make sure to set 'tab_parent' a bit odd. This solution may
+   * not be the prettiest one, but by avoiding having two _LOCAL_TASKs sharing
+   * a parent that can be accessed by its full path, it seems to work as
+   * desired. Breadcrumbs work decently, at least the node link is among the
+   * crumbs. For some reason any breadcrumbs "before/above" the node is only
+   * seen at 'node/%node/revisions/%/view'.
+   */
+
+  // Not used directly, but was created to get the other menu items to work.
+  $items['node/%node/revisions/list'] = array(
+    'title' => 'List revisions',
+    'page callback' => 'diff_diffs_overview',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'access callback' => 'diff_node_revision_access',
+    'access arguments' => array(1),
+    'file' => 'diff.pages.inc',
+  );
+  $items['node/%node/revisions/view'] = array(
+    'title' => 'Compare revisions',
+    'page callback' => 'diff_diffs_show',
+    'page arguments' => array(1, 4, 5, 6),
+    'type' => MENU_LOCAL_TASK,
+    'access callback' => 'diff_node_revision_access',
+    'access arguments' => array(1),
+    'tab_parent' => 'node/%/revisions/list',
+    'file' => 'diff.pages.inc',
+  );
+
+  $items['node/%node/revisions/view/latest'] = array(
+    'title' => 'Show latest difference',
+    'page callback' => 'diff_latest',
+    'page arguments' => array(1),
+    'type' => MENU_LOCAL_TASK,
+    'access callback' => 'diff_node_revision_access',
+    'access arguments' => array(1),
+    'tab_parent' => 'node/%/revisions/view',
+    'file' => 'diff.pages.inc',
+  );
+
+  // Administrative settings.
+  $items['admin/config/content/diff'] = array(
+    'title' => 'Diff',
+    'description' => 'Diff settings.',
+    'file' => 'diff.admin.inc',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('diff_admin_settings'),
+    'access arguments' => array('administer site configuration'),
+  );
+  $items['admin/config/content/diff/settings'] = array(
+    'title' => 'Settings',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -10,
+  );
+  $items['admin/config/content/diff/fields'] = array(
+    'title' => 'Fields',
+    'description' => 'Field support and settings overview.',
+    'file' => 'diff.admin.inc',
+    'page callback' => 'diff_admin_field_overview',
+    'access arguments' => array('administer site configuration'),
+    'type' => MENU_LOCAL_TASK,
+  );
+  $items['admin/config/content/diff/fields/%'] = array(
+    'title' => 'Global field settings',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('diff_admin_global_field_settings', 5),
+    'access arguments' => array('administer site configuration'),
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+    'file' => 'diff.admin.inc',
+  );
+
+  $items['admin/config/content/diff/entities'] = array(
+    'title' => 'Entities',
+    'description' => 'Entity settings.',
+    'file' => 'diff.admin.inc',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('diff_admin_global_entity_settings', 'node'),
+    'access arguments' => array('administer site configuration'),
+    'type' => MENU_LOCAL_TASK,
+  );
+
+  $items['admin/config/content/diff/entities/node'] = array(
+    'title' => 'Node',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -10,
+  );
+
+  return $items;
+}
+
+/**
+ * Implements hook_menu_alter().
+ */
+function diff_menu_alter(&$callbacks) {
+  // Overwrite the default 'Revisions' page.
+  $callbacks['node/%node/revisions']['page callback'] = 'diff_diffs_overview';
+  $callbacks['node/%node/revisions']['module'] = 'diff';
+  $callbacks['node/%node/revisions']['file'] = 'diff.pages.inc';
+
+  $callbacks['node/%node/revisions/%/view']['tab_parent'] = 'node/%/revisions/list';
+  $callbacks['node/%node/revisions/%/revert']['tab_parent'] = 'node/%/revisions/%/view';
+  $callbacks['node/%node/revisions/%/delete']['tab_parent'] = 'node/%/revisions/%/view';
+
+  $callbacks['node/%node/revisions']['access callback']
+      = $callbacks['node/%node/revisions/%/view']['access callback']
+      = $callbacks['node/%node/revisions/%/revert']['access callback']
+      = $callbacks['node/%node/revisions/%/delete']['access callback'] = 'diff_node_revision_access';
+}
+
+/**
+ * Implements hook_admin_paths_alter().
+ */
+function diff_admin_paths_alter(&$paths) {
+  // By default, treat all diff pages as administrative.
+  if (variable_get('diff_admin_path_node', 1)) {
+    $paths['node/*/revisions/view/*/*'] = TRUE;
+  }
+}
+
+/**
+ * Access callback for the node revisions page.
+ */
+function diff_node_revision_access($node, $op = 'view') {
+  $may_revision_this_type = variable_get('diff_enable_revisions_page_node_' . $node->type, TRUE) || user_access('administer nodes');
+  return $may_revision_this_type && _node_revision_access($node, $op);
+}
+
+/**
+ * Implements hook_hook_info().
+ */
+function diff_hook_info() {
+  $hooks['entity_diff'] = array(
+    'group' => 'diff',
+  );
+  $hooks['diff'] = array(
+    'group' => 'diff',
+  );
+  $hooks['field_diff_view_prepare_alter'] = array(
+    'group' => 'diff',
+  );
+  $hooks['field_diff_view_alter'] = array(
+    'group' => 'diff',
+  );
+
+  return $hooks;
+}
+
+/**
+ * Implements hook_entity_info_alter().
+ *
+ * Although the module only provides an UI for comparing nodes, it has an
+ * extendable API for any entity, so we supply two view modes for all entities.
+ * - diff_standard: This view mode is used to tell the module how to compare
+ *                  individual fields. This is used on the revisions page.
+ */
+function diff_entity_info_alter(&$entity_info) {
+  foreach (array_keys($entity_info) as $entity_type) {
+    if (!empty($entity_info[$entity_type]['view modes'])) {
+      $entity_info[$entity_type]['view modes'] += array(
+        'diff_standard' => array(
+          'label' => t('Revision comparison'),
+          'custom settings' => FALSE,
+        ),
+      );
+    }
+  }
+}
+
+/**
+ * Implements hook_block_info().
+ */
+function diff_block_info() {
+  return array(
+    'inline' => array(
+      'info' => t('Inline differences'),
+    ),
+  );
+}
+
+/**
+ * Implements hook_block_configure().
+ */
+function diff_block_configure($delta = '') {
+  $form = array();
+  switch ($delta) {
+    case 'inline':
+      $form['bundles'] = array(
+        '#type' => 'checkboxes',
+        '#title' => t('Enabled content types'),
+        '#default_value' => variable_get('diff_show_diff_inline_node_bundles', array()),
+        '#options' => node_type_get_names(),
+        '#description' => t('Show this block only on pages that display content of the given type(s).'),
+      );
+      break;
+  }
+  return $form;
+}
+
+/**
+ * Implements hook_block_save().
+ */
+function diff_block_save($delta = '', $edit = array()) {
+  switch ($delta) {
+    case 'inline':
+      variable_set('diff_show_diff_inline_node_bundles', $edit['bundles']);
+      break;
+  }
+}
+
+/**
+ * Implements hook_block_view().
+ */
+function diff_block_view($delta) {
+  if ($delta === 'inline' && user_access('view revisions') && ($node = menu_get_object()) && arg(2) !== 'edit') {
+    $enabled_types = variable_get('diff_show_diff_inline_node_bundles', array());
+    if (!empty($enabled_types[$node->type])) {
+      $block = array();
+      $revisions = node_revision_list($node);
+      if (count($revisions) > 1) {
+        $block['subject'] = t('Highlight changes');
+        $block['content'] = drupal_get_form('diff_inline_form', $node, $revisions);
+      }
+      return $block;
+    }
+  }
+}
+
+/**
+ * Implements hook_node_view_alter().
+ */
+function diff_node_view_alter(&$build) {
+  $node = $build['#node'];
+  if (user_access('view revisions') && in_array($node->type, variable_get('diff_show_diff_inline_node_bundles', array()))) {
+    // Ugly but cheap way to check that we are viewing a node's revision page.
+    if (arg(2) === 'revisions' && arg(3) === $node->vid) {
+      module_load_include('inc', 'diff', 'diff.pages');
+      $old_vid = _diff_get_previous_vid(node_revision_list($node), $node->vid);
+      $build = array('#markup' => diff_inline_show($node, $old_vid));
+    }
+    $build['#prefix'] = isset($build['#prefix']) ? "<div id='diff-inline-{$node->nid}'>" . $build['#prefix'] : "<div id='diff-inline-{$node->nid}'>";
+    $build['#suffix'] = isset($build['#suffix']) ? $build['#suffix'] . "</div>" : "</div>";
+  }
+}
+
+/**
+ * Implements hook_form_BASE_FORM_ID_alter().
+ */
+function diff_form_node_form_alter(&$form, $form_state) {
+  // Add a 'View changes' button on the node edit form.
+  $node = $form['#node'];
+  if (variable_get('diff_show_preview_changes_node_' . $node->type, TRUE) && !empty($node->nid)) {
+    $form['actions']['preview_changes'] = array(
+      '#type' => 'submit',
+      '#value' => t('View changes'),
+      '#weight' => 12,
+      '#submit' => array('diff_node_form_build_preview_changes'),
+    );
+  }
+}
+
+/**
+ * Implements hook_form_BASE_FORM_ID_alter().
+ */
+function diff_form_node_type_form_alter(&$form, $form_state) {
+  if (isset($form['type'])) {
+    $type = $form['#node_type'];
+    $form['diff'] = array(
+      '#title' => t('Compare revisions'),
+      '#type' => 'fieldset',
+      '#group' => 'additional_settings',
+      '#tree' => FALSE,
+    );
+    $form['diff']['diff_show_preview_changes_node'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show <em>View changes</em> button on node edit form'),
+      '#weight' => 10,
+      '#default_value' => variable_get('diff_show_preview_changes_node_' . $type->type, TRUE),
+    );
+    $form['diff']['diff_enable_revisions_page_node'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Enable the <em>Revisions</em> page for this content type'),
+      '#weight' => 11,
+      '#default_value' => variable_get('diff_enable_revisions_page_node_' . $type->type, TRUE),
+    );
+    $options = array();
+    $info = entity_get_info('node');
+    foreach ($info['view modes'] as $view_mode => $view_mode_info) {
+      $options[$view_mode] = $view_mode_info['label'];
+    }
+    $form['diff']['diff_view_mode_preview_node'] = array(
+      '#type' => 'select',
+      '#title' => t('Standard comparison preview'),
+      '#description' => t('Governs the <em>Current revision</em> view mode when doing standard comparisons.'),
+      '#options' => $options,
+      '#weight' => 13,
+      '#default_value' => variable_get('diff_view_mode_preview_node_' . $type->type, 'full'),
+      '#empty_value' => '',
+      '#empty_option' => t('- Do not display -'),
+    );
+  }
+}
+
+/**
+ * Implements hook_node_type_update().
+ *
+ * This tracks the diff settings in case the node content type is renamed.
+ */
+function diff_node_type_update($info) {
+  if (!empty($info->old_type) && $info->old_type != $info->type) {
+    $type_variables = array(
+      'diff_show_preview_changes_node',
+      'diff_enable_revisions_page_node',
+      'diff_view_mode_preview_node',
+    );
+    foreach ($type_variables as $prefix) {
+      $setting = variable_get($prefix . '_' . $info->old_type, NULL);
+      if (isset($setting)) {
+        variable_del($prefix . '_' . $info->old_type);
+        variable_set($prefix . '_' . $info->type, $setting);
+      }
+    }
+
+    // Block settings are combined in a single variable.
+    $inline_block_types = variable_get('diff_show_diff_inline_node_bundles', array());
+    if (isset($inline_block_types[$info->old_type])) {
+      if (!empty($inline_block_types[$info->old_type])) {
+        $inline_block_types[$info->type] = $info->type;
+      }
+      unset($inline_block_types[$info->old_type]);
+      variable_set('diff_show_diff_inline_node_bundles', $inline_block_types);
+    }
+  }
+}
+
+/**
+ * Implements hook_node_type_delete().
+ */
+function diff_node_type_delete($info) {
+  variable_del('diff_show_preview_changes_node_' . $info->type);
+  variable_del('diff_enable_revisions_page_node_' . $info->type);
+  variable_del('diff_view_mode_preview_node_' . $info->type);
+}
+
+/**
+ * Submit handler for the 'View changes' action.
+ *
+ * @see node_form_build_preview()
+ */
+function diff_node_form_build_preview_changes($form, &$form_state) {
+  module_load_include('inc', 'diff', 'diff.pages');
+  $old_node = clone node_load($form_state['values']['nid']);
+  $node = node_form_submit_build_node($form, $form_state);
+
+  // Create diff of old node and edited node.
+  $rows = _diff_body_rows($old_node, $node);
+
+  $header = _diff_default_header(t('Original'), t('Changes'));
+  $changes = theme('table__diff__preview', array(
+    'header' => $header,
+    'rows' => $rows,
+    'attributes' => array('class' => 'diff'),
+    'colgroups' => _diff_default_cols(),
+    'sticky' => FALSE,
+  ));
+
+  // Prepend diff to edit form.
+  $form_state['node_preview'] = $changes;
+  $form_state['rebuild'] = TRUE;
+}
+
+/**
+ * Implements hook_theme().
+ */
+function diff_theme() {
+  return array(
+    'diff_node_revisions' => array(
+      'render element' => 'form',
+      'file' => 'diff.theme.inc',
+    ),
+    'diff_header_line' => array(
+      'arguments' => array('lineno' => NULL),
+      'file' => 'diff.theme.inc',
+    ),
+    'diff_content_line' => array(
+      'arguments' => array('line' => NULL),
+      'file' => 'diff.theme.inc',
+    ),
+    'diff_empty_line' => array(
+      'arguments' => array('line' => NULL),
+      'file' => 'diff.theme.inc',
+    ),
+    'diff_inline_form' => array(
+      'render element' => 'form',
+      'file' => 'diff.theme.inc',
+    ),
+    'diff_inline_metadata' => array(
+      'arguments' => array('node' => NULL),
+      'file' => 'diff.theme.inc',
+    ),
+    'diff_inline_chunk' => array(
+      'arguments' => array('text' => '', 'type' => NULL),
+      'file' => 'diff.theme.inc',
+    ),
+  );
+}
+
+/**
+ * Render the table rows for theme('table').
+ *
+ * @param string $a
+ *   The source string to compare from.
+ * @param string $b
+ *   The target string to compare to.
+ * @param boolean $show_header
+ *   Display diff context headers. For example, "Line x".
+ * @param array $line_stats
+ *   This structure tracks line numbers across multiple calls to DiffFormatter.
+ *
+ * @return array
+ *   Array of rows usable with theme('table').
+ */
+function diff_get_rows($a, $b, $show_header = FALSE, &$line_stats = NULL) {
+  $a = is_array($a) ? $a : explode("\n", $a);
+  $b = is_array($b) ? $b : explode("\n", $b);
+
+  if (!isset($line_stats)) {
+    $line_stats = array(
+      'counter' => array('x' => 0, 'y' => 0),
+      'offset' => array('x' => 0, 'y' => 0),
+    );
+  }
+  $formatter = new DrupalDiffFormatter();
+  // Header is the line counter.
+  $formatter->show_header = $show_header;
+  $formatter->line_stats = &$line_stats;
+  $diff = new Diff($a, $b);
+  return $formatter->format($diff);
+}
+
+/**
+ * Render and markup a diff of two strings into HTML markup.
+ *
+ * @param string $a
+ *   The source string to compare from.
+ * @param string $b
+ *   The target string to compare to.
+ *
+ * @return string
+ *   String containing HTML markup.
+ */
+function diff_get_inline($a, $b) {
+  $diff = new DrupalDiffInline($a, $b);
+  return $diff->render();
+}
+
+/**
+ * Form builder: Inline diff controls.
+ */
+function diff_inline_form($form, $form_state, $node, $revisions) {
+  $form = array();
+  $form['node'] = array(
+    '#type' => 'value',
+    '#value' => $node,
+  );
+  $form['revision'] = array(
+    '#type' => 'select',
+    '#options' => array(0 => t('- No highlighting -')),
+    '#default_value' => (arg(2) === 'revisions' && arg(3) === $node->vid) ? $node->vid : 0,
+    '#ajax' => array(
+      'callback' => 'diff_inline_ajax',
+      'wrapper' => "node-{$node->nid}",
+      'method' => 'replace',
+    ),
+  );
+  foreach ($revisions as $revision) {
+    $form['revision']['#options'][$revision->vid] = t('@revision by @name', array(
+      '@revision' => format_date($revision->timestamp, 'short'),
+      '@name' => format_username($revision),
+    ));
+  }
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('View'),
+    '#submit' => array('diff_inline_form_submit'),
+    '#attributes' => array('class' => array('diff-js-hidden')),
+  );
+  return $form;
+}
+
+/**
+ * AHAH callback for rendering the inline diff of a node.
+ */
+function diff_inline_ajax($form, $form_state) {
+  module_load_include('inc', 'diff', 'diff.pages');
+  $node = $form['node']['#value'];
+  $vid = isset($form_state['values']['revision']) ? $form_state['values']['revision'] : 0;
+  return "<div id='node-{$node->nid}'>" . diff_inline_show($node, $vid) . "</div>";
+}
+
+/**
+ * Form submission handler for diff_inline_form() for JS-disabled clients.
+ */
+function diff_inline_form_submit(&$form, &$form_state) {
+  if (isset($form_state['values']['revision'], $form_state['values']['node'])) {
+    $node = $form_state['values']['node'];
+    $vid = $form_state['values']['revision'];
+    $form_state['redirect'] = "node/{$node->nid}/revisions/{$vid}/view";
+  }
+}
+
+/**
+ * A helper function to normalise system differences.
+ *
+ * This handles differences in:
+ * - line endings: Mac, Windows and UNIX all use different line endings.
+ */
+function diff_normalise_text($text) {
+  $text = str_replace(array("\r\n", "\r"), "\n", $text);
+  return $text;
+}
+
+/**
+ * A wrapper function for filter_xss() to exclude all tags.
+ */
+function diff_filter_xss($string) {
+  return filter_xss($string, array());
+}
+
+/**
+ * Helper function to load any CSS or JScript files required by a page or form.
+ */
+function diff_build_attachments($jscript = FALSE) {
+  $attachments = array();
+  $theme = variable_get('diff_theme', 'default');
+  if ($theme) {
+    $attachments['css'] = array(
+      drupal_get_path('module', 'diff') . "/css/diff.{$theme}.css",
+    );
+  }
+  $type = variable_get('diff_radio_behavior', 'simple');
+  if ($jscript && $type) {
+    $attachments['js'] = array(
+      drupal_get_path('module', 'diff') . "/js/diff.js",
+      array(
+        'data' => array('diffRevisionRadios' => $type),
+        'type' => 'setting',
+      ),
+    );
+  }
+  return $attachments;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/diff.pages.inc b/profiles/wcm_base/modules/contrib/diff/diff.pages.inc
new file mode 100644
index 00000000..1cd14419
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/diff.pages.inc
@@ -0,0 +1,632 @@
+<?php
+
+/**
+ * @file
+ * Menu callbacks for hook_menu().
+ */
+
+/**
+ * Menu callback - show latest diff for a given node.
+ */
+function diff_latest($node) {
+  $revisions = node_revision_list($node);
+  $new = array_shift($revisions);
+  $old = array_shift($revisions);
+  drupal_goto("node/{$node->nid}/revisions/view/{$old->vid}/{$new->vid}");
+}
+
+/**
+ * Menu callback - an overview table of older revisions.
+ *
+ * Generate an overview table of older revisions of a node and provide
+ * an input form to select two revisions for a comparison.
+ */
+function diff_diffs_overview($node) {
+  drupal_set_title(t('Revisions for %title', array('%title' => $node->title)), PASS_THROUGH);
+  return drupal_get_form('diff_node_revisions', $node);
+}
+
+/**
+ * Input form to select two revisions.
+ */
+function diff_node_revisions($form, $form_state, $node) {
+  $form['nid'] = array(
+    '#type' => 'hidden',
+    '#value' => $node->nid,
+  );
+
+  $revision_list = node_revision_list($node);
+
+  if (count($revision_list) > REVISION_LIST_SIZE) {
+    // If the list of revisions is longer than the number shown on one page
+    // split the array.
+    $page = isset($_GET['page']) ? $_GET['page'] : '0';
+    $revision_chunks = array_chunk(node_revision_list($node), REVISION_LIST_SIZE);
+    $revisions = $revision_chunks[$page];
+    // Set up global pager variables as would 'pager_query' do.
+    // These variables are then used in the theme('pager') call later.
+    global $pager_page_array, $pager_total, $pager_total_items;
+    $pager_total_items[0] = count($revision_list);
+    $pager_total[0] = ceil(count($revision_list) / REVISION_LIST_SIZE);
+    $pager_page_array[0] = max(0, min($page, ((int) $pager_total[0]) - 1));
+  }
+  else {
+    $revisions = $revision_list;
+  }
+
+  $revert_permission = FALSE;
+  if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) {
+    $revert_permission = TRUE;
+  }
+  $delete_permission = FALSE;
+  if ((user_access('delete revisions') || user_access('administer nodes')) && node_access('delete', $node)) {
+    $delete_permission = TRUE;
+  }
+
+  foreach ($revisions as $revision) {
+    $operations = array();
+    $revision_ids[$revision->vid] = '';
+
+    $revision_log = ($revision->log != '') ? '<p class="revision-log">' . filter_xss($revision->log) . '</p>' : '';
+    if ($revision->current_vid > 0) {
+      $form['info'][$revision->vid] = array(
+        '#markup' => t('!date by !username', array(
+          '!date' => l(format_date($revision->timestamp, 'small'), "node/$node->nid"),
+          '!username' => theme('username', array('account' => $revision)))) . $revision_log,
+      );
+    }
+    else {
+      $diff_date = l(format_date($revision->timestamp, 'small'), "node/$node->nid/revisions/$revision->vid/view");
+      $form['info'][$revision->vid] = array(
+        '#markup' => t('!date by !username', array(
+          '!date' => $diff_date,
+          '!username' => theme('username', array('account' => $revision)))
+        ) . $revision_log,
+      );
+      if ($revert_permission) {
+        $operations[] = array(
+          '#markup' => l(t('Revert'), "node/$node->nid/revisions/$revision->vid/revert"),
+        );
+      }
+      if ($delete_permission) {
+        $operations[] = array(
+          '#markup' => l(t('Delete'), "node/$node->nid/revisions/$revision->vid/delete"),
+        );
+      }
+      // Set a dummy, even if the user has no permission for the other
+      // operations, so that we can check if the operations array is
+      // empty to know if the row denotes the current revision.
+      $operations[] = array();
+    }
+    $form['operations'][$revision->vid] = $operations;
+
+  }
+  $new_vid = key($revision_ids);
+  next($revision_ids);
+  $old_vid = key($revision_ids);
+  $form['diff']['old'] = array(
+    '#type' => 'radios',
+    '#options' => $revision_ids,
+    '#default_value' => $old_vid,
+  );
+  $form['diff']['new'] = array(
+    '#type' => 'radios',
+    '#options' => $revision_ids,
+    '#default_value' => $new_vid,
+  );
+
+  $form['submit'] = array('#type' => 'submit', '#value' => t('Compare'));
+
+  if (count($revision_list) > REVISION_LIST_SIZE) {
+    $form['#suffix'] = theme('pager');
+  }
+  $form['#attached'] = diff_build_attachments(TRUE);
+  return $form;
+}
+
+/**
+ * Submit code for input form to select two revisions.
+ */
+function diff_node_revisions_submit($form, &$form_state) {
+  // The ids are ordered so the old revision is always on the left.
+  $old_vid = min($form_state['values']['old'], $form_state['values']['new']);
+  $new_vid = max($form_state['values']['old'], $form_state['values']['new']);
+  $form_state['redirect'] = 'node/' . $form_state['values']['nid'] . '/revisions/view/' . $old_vid . '/' . $new_vid;
+}
+
+/**
+ * Validation for input form to select two revisions.
+ */
+function diff_node_revisions_validate($form, &$form_state) {
+  $old_vid = $form_state['values']['old'];
+  $new_vid = $form_state['values']['new'];
+  if ($old_vid == $new_vid || !$old_vid || !$new_vid) {
+    form_set_error('diff', t('Select different revisions to compare.'));
+  }
+}
+
+/**
+ * Create a comparison for the node between versions 'old_vid' and 'new_vid'.
+ *
+ * @param object $node
+ *   Node on which to perform comparison
+ * @param integer $old_vid
+ *   Version ID of the old revision.
+ * @param integer $new_vid
+ *   Version ID of the new revision.
+ */
+function diff_diffs_show($node, $old_vid, $new_vid, $state = NULL) {
+  // Attaches the CSS.
+  $build['#attached'] = diff_build_attachments();
+
+  $default_state = variable_get('diff_default_state_node', 'raw');
+  if (empty($state)) {
+  	$state = $default_state;
+  }
+  $state = str_replace('-', '_', $state);
+  if (!array_key_exists($state, diff_available_states())) {
+    $state = $default_state;
+  }
+
+  // Same title as the 'Revisions' tab. Blocked by non-page requests.
+  if (node_is_page($node)) {
+    drupal_set_title(t('Revisions for %title', array('%title' => $node->title)), PASS_THROUGH);
+  }
+  $node_revisions = node_revision_list($node);
+
+  $old_node = node_load($node->nid, $old_vid);
+  $new_node = node_load($node->nid, $new_vid);
+
+  // Generate table header (date, username, log message).
+  $old_header = t('!date by !username', array(
+    '!date' => l(format_date($old_node->revision_timestamp), "node/$node->nid/revisions/$old_node->vid/view", array('absolute' => 1)),
+    '!username' => theme('username', array('account' => $node_revisions[$old_vid])),
+  ));
+  $new_header = t('!date by !username', array(
+    '!date' => l(format_date($new_node->revision_timestamp), "node/$node->nid/revisions/$new_node->vid/view", array('absolute' => 1)),
+    '!username' => theme('username', array('account' => $node_revisions[$new_vid])),
+  ));
+
+  $old_log = $old_node->log != '' ? '<p class="revision-log">' . filter_xss($old_node->log) . '</p>' : '';
+  $new_log = $new_node->log != '' ? '<p class="revision-log">' . filter_xss($new_node->log) . '</p>' : '';
+
+  // Generate previous diff/next diff links.
+  $nav_suffix = ($default_state != $state) ? '/' . str_replace('_', '-', $state) : '';
+  $next_vid = _diff_get_next_vid($node_revisions, $new_vid);
+  if ($next_vid) {
+    $next_link = l(t('Next difference >'), 'node/' . $node->nid . '/revisions/view/' . $new_vid . '/' . $next_vid . $nav_suffix, array('absolute' => 1));
+  }
+  else {
+    $next_link = '';
+  }
+  $prev_vid = _diff_get_previous_vid($node_revisions, $old_vid);
+  if ($prev_vid) {
+    $prev_link = l(t('< Previous difference'), 'node/' . $node->nid . '/revisions/view/' . $prev_vid . '/' . $old_vid . $nav_suffix, array('absolute' => 1));
+  }
+  else {
+    $prev_link = '';
+  }
+
+  $header = _diff_default_header($old_header, $new_header);
+  $rows = array();
+  if ($old_log || $new_log) {
+    $rows['logs'] = array(
+      array(
+        'data' => $old_log,
+        'colspan' => 2,
+      ),
+      array(
+        'data' => $new_log,
+        'colspan' => 2,
+      ),
+    );
+  }
+  $rows['navigation'] = array(
+    array(
+      'data' => $prev_link,
+      'class' => array('diff-prevlink'),
+      'colspan' => 2,
+    ),
+    array(
+      'data' => $next_link,
+      'class' => array('diff-nextlink'),
+      'colspan' => 2,
+    ),
+  );
+
+  $links = array();
+  foreach (diff_available_states('node') as $alternative_state => $label) {
+    if ($alternative_state == $state) {
+      // @todo: Should we show both or just alternatives?
+    }
+    $links[$alternative_state] = array(
+      'title' => $label,
+      'href' => "node/{$node->nid}/revisions/view/{$old_vid}/{$new_vid}" . ($alternative_state == $default_state ? '' : '/' . str_replace('_', '-', $alternative_state)),
+    );
+  }
+  if (count($links) > 1) {
+    $state_links = theme('links', array(
+      'links' => $links,
+      'attributes' => array('class' => array('links', 'inline')),
+    ));
+    $rows['states'] = array(
+      array(
+        'data' => $state_links,
+        'class' => 'diff-links',
+        'colspan' => 4,
+      ),
+    );
+  }
+  $rows = array_merge($rows, _diff_body_rows($old_node, $new_node, $state));
+
+  $build['diff_table'] = array(
+    '#theme' => 'table__diff__standard',
+    '#header' => $header,
+    '#rows' => $rows,
+    '#attributes' => array('class' => array('diff')),
+    '#colgroups' => _diff_default_cols(),
+    '#sticky' => FALSE,
+  );
+
+  // Allow users to hide or set the display mode of the preview.
+  if (node_is_page($node) && $view_mode = variable_get('diff_view_mode_preview_node_' . $new_node->type, 'full')) {
+    $header = '';
+    if ($node->vid == $new_vid) {
+      $header .= '<div class="diff-section-title">' . t('Current revision:') . '</div>';
+    }
+    else {
+      $header .= '<div class="diff-section-title">' . t('Revision of @new_date:', array('@new_date' => format_date($new_node->revision_timestamp))) . '</div>';
+    }
+    $build['diff_preview']['header']['#markup'] = $header;
+    // Don't include node links or comments when viewing the diff.
+    $build['diff_preview']['content'] = node_view($new_node, $view_mode);
+    if (isset($build['diff_preview']['content']['links'])) {
+      unset($build['diff_preview']['content']['links']);
+    }
+    if (isset($build['diff_preview']['content']['comments'])) {
+      unset($build['diff_preview']['content']['comments']);
+    }
+  }
+  return $build;
+}
+
+/**
+ * Creates an array of rows which represent the difference between nodes.
+ *
+ * @param object $old_node
+ *   Node for comparison which will be displayed on the left side.
+ * @param object $new_node
+ *   Node for comparison which will be displayed on the right side.
+ * @param boolean $state
+ *   The state to render for the diff.
+ */
+function _diff_body_rows($old_node, $new_node, $state = 'raw') {
+  // This is an unique index only, so no need for drupal_static().
+  static $table_row_counter = 0;
+
+  if ($theme = variable_get('diff_theme', 'default')) {
+    drupal_add_css(drupal_get_path('module', 'diff') . "/css/diff.{$theme}.css");
+  }
+  module_load_include('inc', 'diff', 'includes/node');
+
+  $rows = array();
+  $any_visible_change = FALSE;
+  $context = array(
+    'entity_type' => 'node',
+    'states' => array($state),
+    'view_mode' => 'diff_standard',
+  );
+
+  $node_diffs = diff_compare_entities($old_node, $new_node, $context);
+
+  // Track line numbers between multiple diffs.
+  $line_stats = array(
+    'counter' => array('x' => 0, 'y' => 0),
+    'offset' => array('x' => 0, 'y' => 0),
+  );
+
+  // Render diffs for each.
+  foreach ($node_diffs as $node_diff) {
+    $show_header = !empty($node_diff['#name']);
+    // These are field level settings.
+    if ($show_header && isset($node_diff['#settings']['show_header'])) {
+      $show_header = $show_header && $node_diff['#settings']['show_header'];
+    }
+
+    // Line counting and line header options.
+    if (empty($node_diff['#settings']['line_counter'])) {
+      $line_counter = FALSE;
+    }
+    else {
+      $line_counter = $node_diff['#settings']['line_counter'];
+    }
+    // Every call to 'line' resets the counters.
+    if ($line_counter) {
+      $line_stats['counter']['x'] = 0;
+      $line_stats['counter']['y'] = 0;
+      if ($line_counter == 'line' && 0) {
+        $line_stats['offset']['x'] = 0;
+        $line_stats['offset']['y'] = 0;
+      }
+      $line_stats_ref = $line_stats;
+    }
+    else {
+      $line_stats_ref = NULL;
+    }
+
+    list($old, $new) = diff_extract_state($node_diff, $state);
+    if ($node_diff_rows = diff_get_rows($old, $new, $line_counter && $line_counter != 'hidden', $line_stats_ref)) {
+      if ($line_counter && $line_counter != 'line') {
+        $line_stats['offset']['x'] += $line_stats_ref['counter']['x'];
+        $line_stats['offset']['y'] += $line_stats_ref['counter']['y'];
+      }
+      if ($show_header) {
+        $rows['diff-header-' . $table_row_counter++] = array(
+          array(
+            'data' => t('Changes to %name', array('%name' => $node_diff['#name'])),
+            'class' => 'diff-section-title',
+            'colspan' => 4,
+          ),
+        );
+      }
+      // To avoid passing counter to the Diff engine, index rows manually here
+      // to allow modules to interact with the table. i.e. no array_merge().
+      foreach ($node_diff_rows as $row) {
+        $rows['diff-row-' . $table_row_counter++] = $row;
+      }
+      $any_visible_change = TRUE;
+    }
+  }
+  if (!$any_visible_change) {
+    $rows['diff-empty-' . $table_row_counter++] = array(
+      array(
+        'data' => t('No visible changes'),
+        'class' => 'diff-section-title',
+        'colspan' => 4,
+      ),
+    );
+    // @todo: revise this.
+    // Needed to keep safari happy.
+    $rows['diff-empty-' . $table_row_counter++] = array(
+      array('data' => ''),
+      array('data' => ''),
+      array('data' => ''),
+      array('data' => ''),
+    );
+  }
+
+  return $rows;
+}
+
+/**
+ * Generic callback to compare two entities.
+ */
+function diff_compare_entities($left_entity, $right_entity, $context) {
+  $entity_type = $context['entity_type'];
+  list(, , $bundle) = entity_extract_ids($entity_type, $right_entity);
+  $context['bundle'] = $bundle;
+  $context['old_entity'] = $left_entity;
+  $context['new_entity'] = $right_entity;
+  $context += array(
+    'states' => array('raw'),
+    'view_mode' => FALSE,
+    'language' => LANGUAGE_NONE,
+  );
+
+  $diff = module_invoke_all('entity_diff', $left_entity, $right_entity, $context);
+
+  // Allow other modules to interact directly with the results.
+  drupal_alter('entity_diff', $diff, $context);
+
+  // We start off assuming all form elements are in the correct order.
+  $diff['#sorted'] = TRUE;
+
+  // Field rows. Recurse through all child elements.
+  $count = 0;
+  foreach (element_children($diff) as $key) {
+    if (!isset($diff[$key]['#states'])) {
+      $diff[$key]['#states'] = array();
+    }
+
+    // Ensure that the element follows the new #states format.
+    if (isset($diff[$key]['#old'])) {
+      $diff[$key]['#states']['raw']['#old'] = $diff[$key]['#old'];
+      unset($diff[$key]['#old']);
+    }
+    if (isset($diff[$key]['#new'])) {
+      $diff[$key]['#states']['raw']['#new'] = $diff[$key]['#new'];
+      unset($diff[$key]['#new']);
+    }
+
+    // If requested, we can convert the .
+    foreach (array('raw', 'rendered') as $state) {
+      if (in_array($state . '_plain', $context['states'])) {
+        diff_markdown_state($diff[$key], $state);
+      }
+    }
+
+    // Assign a decimal placeholder weight to preserve original array order.
+    if (!isset($diff[$key]['#weight'])) {
+      $diff[$key]['#weight'] = $count / 1000;
+    }
+    else {
+      // If one child element has a weight then we will need to sort later.
+      unset($diff['#sorted']);
+    }
+    $count++;
+  }
+
+  // One of the children has a #weight.
+  if (!isset($diff['#sorted'])) {
+    uasort($diff, 'element_sort');
+  }
+
+  // Process the array and get line counts per field.
+  array_walk($diff, 'diff_process_state_lines');
+
+  return $diff;
+}
+
+function diff_process_state_lines(&$diff, $key) {
+  foreach ($diff['#states'] as $state => $data) {
+    if (isset($data['#old'])) {
+      if (is_string($data['#old'])) {
+        $diff['#states'][$state]['#old'] = explode("\n", $data['#old']);
+      }
+      $diff['#states'][$state]['#count_old'] = count($diff['#states'][$state]['#old']);
+    }
+    else {
+      $diff['#states'][$state]['#count_old'] = 0;
+    }
+    if (isset($data['#new'])) {
+      if (is_string($data['#new'])) {
+        $diff['#states'][$state]['#new'] = explode("\n", $data['#new']);
+      }
+      $diff['#states'][$state]['#count_new'] = count($diff['#states'][$state]['#new']);
+    }
+    else {
+      $diff['#states'][$state]['#count_new'] = 0;
+    }
+  }
+}
+
+/**
+ * Helper function to render plain states from the corresponding raw state.
+ *
+ * @param array $diff
+ *   The Diff Engine output array.
+ * @param string $state
+ *   The state to markdown.
+ */
+function diff_markdown_state(&$diff, $state) {
+  list($plain_old, $plain_new) = diff_extract_state($diff, $state . '_plain');
+  list($old, $new) = diff_extract_state($diff, $state);
+  $markdown = FALSE;
+  if (isset($diff['#settings']) && !empty($diff['#settings']['markdown'])) {
+    if (function_exists($diff['#settings']['markdown'])) {
+      $markdown = $diff['#settings']['markdown'];
+    }
+  }
+
+  if (!isset($plain_old) && isset($old)) {
+    if (is_array($old)) {
+      $diff['#states'][$state . '_plain']['#old'] = $markdown ? array_map($markdown, $old) : $old;
+    }
+    else {
+      $diff['#states'][$state . '_plain']['#old'] = $markdown ? $markdown($old) : $old;
+    }
+  }
+  if (!isset($plain_new) && isset($new)) {
+    if (is_array($new)) {
+      $diff['#states'][$state . '_plain']['#new'] = $markdown ? array_map($markdown, $new) : $new;
+    }
+    else {
+      $diff['#states'][$state . '_plain']['#new'] = $markdown ? $markdown($new) : $new;
+    }
+  }
+}
+
+/**
+ * Get the entry in the revisions list after $vid.
+ *
+ * @param array $node_revisions
+ *   Array of node revision IDs in descending order.
+ * @param int $vid
+ *   Version ID to look for.
+ *
+ * @return boolean|integer
+ *   Returns FALSE if $vid is the last entry.
+ */
+function _diff_get_next_vid($node_revisions, $vid) {
+  $previous = NULL;
+  foreach ($node_revisions as $revision) {
+    if ($revision->vid == $vid) {
+      return ($previous ? $previous->vid : FALSE);
+    }
+    $previous = $revision;
+  }
+  return FALSE;
+}
+
+/**
+ * Get the entry in the revision list before $vid.
+ *
+ * @param array $node_revisions
+ *   Array of node revision IDs in descending order.
+ * @param integer $vid
+ *   Version ID to look for.
+ *
+ * @return boolean|integer
+ *   Returns FALSE if $vid is the first entry.
+ */
+function _diff_get_previous_vid($node_revisions, $vid) {
+  $previous = NULL;
+  foreach ($node_revisions as $revision) {
+    if ($previous && $previous->vid == $vid) {
+      return $revision->vid;
+    }
+    $previous = $revision;
+  }
+  return FALSE;
+}
+
+/**
+ * Helper function to create default 'cols' array for diff table.
+ */
+function _diff_default_cols() {
+  return array(
+    array(
+      array(
+        'class' => 'diff-marker',
+      ),
+      array(
+        'class' => 'diff-content',
+      ),
+      array(
+        'class' => 'diff-marker',
+      ),
+      array(
+        'class' => 'diff-content',
+      ),
+    ),
+  );
+}
+
+/**
+ * Helper function to create default 'header' array for diff table.
+ */
+function _diff_default_header($old_header = '', $new_header = '') {
+  return array(
+    array(
+      'data' => $old_header,
+      'colspan' => 2,
+    ),
+    array(
+      'data' => $new_header,
+      'colspan' => 2,
+    ),
+  );
+}
+
+/**
+ * Show the inline diff for a given node, vid.
+ *
+ * If vid = 0 or no previous vid exists for the given revision returns the
+ * normally rendered content of the specified revision.
+ */
+function diff_inline_show($node, $vid = 0, $metadata = TRUE) {
+  $new_node = $vid ? node_load($node->nid, $vid, TRUE) : clone $node;
+  node_build_content($new_node);
+  $new = drupal_render($new_node->content);
+
+  $old = $vid ? _diff_get_previous_vid(node_revision_list($node), $vid) : 0;
+  if ($old) {
+    $old_node = node_load($node->nid, $old, TRUE);
+    node_build_content($old_node);
+    $old = drupal_render($old_node->content);
+    $output = $metadata ? theme('diff_inline_metadata', array('node' => $new_node)) : '';
+    $output .= diff_get_inline($old, $new);
+    return $output;
+  }
+  return $new;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/diff.theme.inc b/profiles/wcm_base/modules/contrib/diff/diff.theme.inc
new file mode 100644
index 00000000..96d20b3a
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/diff.theme.inc
@@ -0,0 +1,149 @@
+<?php
+
+/**
+ * @file
+ * Themeable function callbacks for diff.module.
+ */
+
+/**
+ * Theme function to display the revisions formular.
+ */
+function theme_diff_node_revisions($vars) {
+  $form = $vars['form'];
+  $output = '';
+
+  // Overview table:
+  $header = array(
+    t('Revision'),
+    array('data' => drupal_render($form['submit']), 'colspan' => 2),
+    array('data' => t('Operations'), 'colspan' => 2),
+  );
+  if (isset($form['info']) && is_array($form['info'])) {
+    foreach (element_children($form['info']) as $key) {
+      $row = array();
+      if (isset($form['operations'][$key][0])) {
+        // Note: even if the commands for revert and delete are not permitted,
+        // the array is not empty since we set a dummy in this case.
+        $row[] = drupal_render($form['info'][$key]);
+        $row[] = drupal_render($form['diff']['old'][$key]);
+        $row[] = drupal_render($form['diff']['new'][$key]);
+        $row[] = drupal_render($form['operations'][$key][0]);
+        $row[] = drupal_render($form['operations'][$key][1]);
+        $rows[] = array(
+          'data' => $row,
+          'class' => array('diff-revision'),
+        );
+      }
+      else {
+        // The current revision (no commands to revert or delete).
+        $row[] = array(
+          'data' => drupal_render($form['info'][$key]),
+          'class' => array('revision-current'),
+        );
+        $row[] = array(
+          'data' => drupal_render($form['diff']['old'][$key]),
+          'class' => array('revision-current'),
+        );
+        $row[] = array(
+          'data' => drupal_render($form['diff']['new'][$key]),
+          'class' => array('revision-current'),
+        );
+        $row[] = array(
+          'data' => t('current revision'),
+          'class' => array('revision-current'),
+          'colspan' => '2',
+        );
+        $rows[] = array(
+          'data' => $row,
+          'class' => array('error diff-revision'),
+        );
+      }
+    }
+  }
+  $output .= theme('table__diff__revisions', array(
+    'header' => $header,
+    'rows' => $rows,
+    'sticky' => FALSE,
+    'attributes' => array('class' => 'diff-revisions'),
+  ));
+
+  $output .= drupal_render_children($form);
+  return $output;
+}
+
+/**
+ * Theme functions
+ */
+
+/**
+ * Theme function for a header line in the diff.
+ */
+function theme_diff_header_line($vars) {
+  return '<strong>' . t('Line @lineno', array('@lineno' => $vars['lineno'])) . '</strong>';
+}
+
+/**
+ * Theme function for a content line in the diff.
+ */
+function theme_diff_content_line($vars) {
+  return '<div>' . $vars['line'] . '</div>';
+}
+
+/**
+ * Theme function for an empty line in the diff.
+ */
+function theme_diff_empty_line($vars) {
+  return $vars['line'];
+}
+
+/**
+ * Theme function for inline diff form.
+ */
+function theme_diff_inline_form($vars) {
+  if ($theme = variable_get('diff_theme', 'default')) {
+    drupal_add_css(drupal_get_path('module', 'diff') . "/css/diff.{$theme}.css");
+  }
+  return drupal_render_children($vars['form']);
+}
+
+/**
+ * Display inline diff metadata.
+ */
+function theme_diff_inline_metadata($vars) {
+  if ($theme = variable_get('diff_theme', 'default')) {
+    drupal_add_css(drupal_get_path('module', 'diff') . "/css/diff.{$theme}.css");
+  }
+  $node = $vars['node'];
+
+  $output = "<div class='diff-inline-metadata clear-block'>";
+  $output .= "<div class='diff-inline-byline'>";
+  $output .= t('Updated by !name on @date', array(
+    '!name' => theme('username', array('account' => user_load($node->revision_uid))),
+    '@date' => format_date($node->revision_timestamp, 'small'),
+  ));
+  $output .= "</div>";
+  $output .= "<div class='diff-inline-legend clear-block'>";
+  $output .= "<label>" . t('Legend') . "</label>";
+  $output .= theme('diff_inline_chunk', array('text' => t('Added'), 'type' => 'add'));
+  $output .= theme('diff_inline_chunk', array('text' => t('Changed'), 'type' => 'change'));
+  $output .= theme('diff_inline_chunk', array('text' => t('Deleted'), 'type' => 'delete'));
+  $output .= "</div>";
+  $output .= "</div>";
+  return $output;
+}
+
+/**
+ * Theme a span of changed text in an inline diff display.
+ */
+function theme_diff_inline_chunk($vars) {
+  switch ($vars['type']) {
+    case 'add':
+      return "<span class='diff-added'>{$vars['text']}</span>";
+    case 'change':
+      return "<span class='diff-changed'>{$vars['text']}</span>";
+    case 'delete':
+      return "<span class='diff-deleted'>{$vars['text']}</span>";
+    default:
+      return $vars['text'];
+  }
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/diff.tokens.inc b/profiles/wcm_base/modules/contrib/diff/diff.tokens.inc
new file mode 100644
index 00000000..96dbd80a
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/diff.tokens.inc
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Builds placeholder replacement tokens for diff-related data.
+ */
+
+/**
+ * Implements hook_token_info().
+ */
+function diff_token_info() {
+  $node['diff'] = array(
+    'name' => t('Latest differences'),
+    'description' => t('The differences between the current revision and the previous revision of this node.'),
+  );
+  $node['diff-markdown'] = array(
+    'name' => t('Latest differences (marked down)'),
+    'description' => t('The differences between the current revision and the previous revision of this node, but with a marked-down form of each revision used for comparison.'),
+  );
+
+  return array(
+    'tokens' => array('node' => $node),
+  );
+}
+
+/**
+ * Implements hook_tokens().
+ */
+function diff_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $sanitize = !empty($options['sanitize']);
+
+  $replacements = array();
+
+  if ($type == 'node' && !empty($data['node'])) {
+    $node = $data['node'];
+    foreach ($tokens as $name => $original) {
+      switch ($name) {
+        // Basic diff standard comparison information.
+        case 'diff':
+        case 'diff-markdown':
+          $revisons = node_revision_list($node);
+          if (count($revisons) == 1) {
+            $replacements[$original] = t('(No previous revision available.)');
+          }
+          else {
+            module_load_include('inc', 'diff', 'diff.pages');
+            $old_vid = _diff_get_previous_vid($revisons, $node->vid);
+            $state = $name == 'diff' ? 'raw' : 'raw_plain';
+            $build = diff_diffs_show($node, $old_vid, $node->vid, $state);
+            unset($build['diff_table']['#rows']['states']);
+            unset($build['diff_table']['#rows']['navigation']);
+            unset($build['diff_preview']);
+
+            $output = drupal_render_children($build);
+            $replacements[$original] = $sanitize ? check_plain($output) : $output;
+          }
+          break;
+
+      }
+    }
+  }
+  return $replacements;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/includes/file.inc b/profiles/wcm_base/modules/contrib/diff/includes/file.inc
new file mode 100644
index 00000000..678ff466
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/includes/file.inc
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * @file
+ * Provide diff field functions for the file module.
+ */
+
+/**
+ * Diff field callback for preloading file entities.
+ */
+function file_field_diff_view_prepare(&$old_items, &$new_items, $context) {
+  $fids = array();
+  foreach (array_merge_recursive($old_items, $new_items) as $info) {
+    $fids[$info['fid']] = $info['fid'];
+  }
+  $files = file_load_multiple($fids);
+
+  foreach ($old_items as $delta => $info) {
+    $old_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL;
+  }
+  foreach ($new_items as $delta => $info) {
+    $new_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL;
+  }
+}
+
+/**
+ * Diff field callback for parsing file field comparative values.
+ */
+function file_field_diff_view($items, $context) {
+  $field = $context['field'];
+  $instance = $context['instance'];
+  $settings = $context['settings'];
+
+  $diff_items = array();
+  foreach ($items as $delta => $item) {
+    if (isset($item['file'])) {
+      $output = array();
+
+      // We populate as much as possible to allow the best flexability in any
+      // string overrides.
+      $t_args = array();
+      foreach ($item as $key => $value) {
+        if (is_scalar($value)) {
+          $t_args['!' . $key] = $value;
+        }
+      }
+      // Some states do not have the file properties in the item, so put these
+      // out of the main file object.
+      if (!empty($item['file'])) {
+        $file_values = (array) $item['file'];
+        foreach ($file_values as $key => $value) {
+          if (is_scalar($value) && !isset($t_args['!' . $key])) {
+            $t_args['!' . $key] = $value;
+          }
+        }
+      }
+
+      $output['file'] = t('File: !filename', $t_args);
+      if ($settings['compare_description_field'] && !empty($instance['settings']['description_field'])) {
+        if (!empty($item['description'])) {
+          $output['description'] = t('Description: !description', $t_args);
+        }
+      }
+      if ($settings['show_id']) {
+        $output['fid'] = t('File ID: !fid', $t_args);
+      }
+      if ($settings['compare_display_field'] && !empty($field['settings']['display_field'])) {
+        $output['display'] = $item['display'] ? t('Displayed') : t('Hidden');
+      }
+      $diff_items[$delta] = implode('; ', $output);
+    }
+  }
+
+  return $diff_items;
+}
+
+/**
+ * Provide default field comparison options.
+ */
+function file_field_diff_default_options($field_type) {
+  return array(
+    'show_id' => 0,
+    'compare_display_field' => 0,
+    'compare_description_field' => 0,
+  );
+}
+
+/**
+ * Provide a form for setting the field comparison options.
+ */
+function file_field_diff_options_form($field_type, $settings) {
+  $options_form = array();
+  $options_form['show_id'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show file ID'),
+    '#default_value' => $settings['show_id'],
+  );
+  $options_form['compare_description_field'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Compare description field'),
+    '#default_value' => $settings['compare_description_field'],
+    '#description' => t('This is only used if the "Enable <em>Description</em> field" is checked in the instance settings.'),
+  );
+  $options_form['compare_display_field'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Compare display state field'),
+    '#default_value' => $settings['compare_display_field'],
+    '#description' => t('This is only used if the "Enable <em>Display</em> field" is checked in the field settings.'),
+  );
+  return $options_form;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/includes/image.inc b/profiles/wcm_base/modules/contrib/diff/includes/image.inc
new file mode 100644
index 00000000..cb93616d
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/includes/image.inc
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * @file
+ * Provide diff field functions for the image module.
+ */
+
+/**
+ * Diff field callback for preloading the image file entities.
+ */
+function image_field_diff_view_prepare(&$old_items, &$new_items, $context) {
+  $fids = array();
+  foreach (array_merge_recursive($old_items, $new_items) as $info) {
+    $fids[$info['fid']] = $info['fid'];
+  }
+  $files = file_load_multiple($fids);
+
+  foreach ($old_items as $delta => $info) {
+    $old_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL;
+  }
+  foreach ($new_items as $delta => $info) {
+    $new_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL;
+  }
+}
+
+/**
+ * Diff field callback for parsing image field comparative values.
+ */
+function image_field_diff_view($items, $context) {
+  $instance = $context['instance'];
+  $settings = $context['settings'];
+
+  $diff_items = array();
+  foreach ($items as $delta => $item) {
+    if (isset($item['file'])) {
+      $output = array();
+
+      // We populate as much as possible to allow the best flexability in any
+      // string overrides.
+      $t_args = array();
+      foreach ($item as $key => $value) {
+        if (is_scalar($value)) {
+          $t_args['!' . $key] = $value;
+        }
+      }
+      // Some states do not have the file properties in the item, so put these
+      // out of the main file object.
+      if (!empty($item['file'])) {
+        $file_values = (array) $item['file'];
+        foreach ($file_values as $key => $value) {
+          if (is_scalar($value) && !isset($t_args['!' . $key])) {
+            $t_args['!' . $key] = $value;
+          }
+        }
+      }
+
+      $output[] = t('Image: !filename', $t_args);
+      if ($settings['compare_alt_field'] && !empty($instance['settings']['alt_field'])) {
+        if (!empty($item['alt'])) {
+          $output[] = t('Alt: !alt', $t_args);
+        }
+      }
+      if ($settings['compare_title_field'] && !empty($instance['settings']['title_field'])) {
+        if (!empty($item['title'])) {
+          $output[] = t('Title: !title', $t_args);
+        }
+      }
+      if ($settings['show_id']) {
+        $output[] = t('File ID: !fid', $t_args);
+      }
+      $diff_items[$delta] = implode('; ', $output);
+    }
+  }
+
+  return $diff_items;
+}
+
+/**
+ * Provide default field comparison options.
+ */
+function image_field_diff_default_options($field_type) {
+  return array(
+    'show_id' => 0,
+    'compare_alt_field' => 0,
+    'compare_title_field' => 0,
+  );
+}
+
+/**
+ * Provide a form for setting the field comparison options.
+ */
+function image_field_diff_options_form($field_type, $settings) {
+  $options_form = array();
+  $options_form['show_id'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show image ID'),
+    '#default_value' => $settings['show_id'],
+  );
+  $options_form['compare_alt_field'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Compare <em>Alt</em> field'),
+    '#default_value' => $settings['compare_alt_field'],
+    '#description' => t('This is only used if the "Enable <em>Alt</em> field" is checked in the instance settings.'),
+  );
+  $options_form['compare_title_field'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Compare <em>Title</em> field'),
+    '#default_value' => $settings['compare_title_field'],
+    '#description' => t('This is only used if the "Enable <em>Title</em> field" is checked in the instance settings.'),
+  );
+  return $options_form;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/includes/list.inc b/profiles/wcm_base/modules/contrib/diff/includes/list.inc
new file mode 100644
index 00000000..d1f62e33
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/includes/list.inc
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Provide diff field functions for the List module.
+ */
+
+/**
+ * Diff field callback for parsing list field comparative values.
+ */
+function list_field_diff_view($items, $context) {
+  $field = $context['field'];
+  $instance = $context['instance'];
+  $settings = $context['settings'];
+
+  $diff_items = array();
+  $allowed_values = list_allowed_values($field, $instance, $context['entity_type'], $context['entity']);
+  foreach ($items as $delta => $item) {
+    // Fairly complex condition to prevent duplicate "key (key)" type rendering.
+    if (isset($allowed_values[$item['value']]) &&
+        $allowed_values[$item['value']] != $item['value'] &&
+        strlen($allowed_values[$item['value']])) {
+      switch ($settings['compare']) {
+        case 'both':
+          $diff_items[$delta] = $allowed_values[$item['value']] . ' (' . $item['value'] . ')';
+          break;
+
+        case 'label':
+          $diff_items[$delta] = $allowed_values[$item['value']];
+          break;
+
+        default:
+          $diff_items[$delta] = $item['value'];
+          break;
+
+      }
+    }
+    else {
+      // If no match was found for the label, fall back to the key.
+      $diff_items[$delta] = $item['value'];
+    }
+  }
+  return $diff_items;
+}
+
+/**
+ * Provide default field comparison options.
+ */
+function list_field_diff_default_options($field_type) {
+  return array(
+    'compare' => 'label',
+  );
+}
+
+/**
+ * Provide a form for setting the field comparison options.
+ */
+function list_field_diff_options_form($field_type, $settings) {
+  $options_form = array();
+  $options_form['compare'] = array(
+    '#type' => 'radios',
+    '#title' => t('Comparison method'),
+    '#options' => array(
+      'label' => t('Label'),
+      'key' => t('Key'),
+      'both' => t('Label (key)'),
+    ),
+    '#default_value' => $settings['compare'],
+  );
+  return $options_form;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/includes/node.inc b/profiles/wcm_base/modules/contrib/diff/includes/node.inc
new file mode 100644
index 00000000..3f0bca33
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/includes/node.inc
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * @file
+ * Provide diff functions for the node module.
+ */
+
+/**
+ * Implements hook_entity_diff().
+ *
+ * This function compares core node properties. This is currently limited to:
+ *   - title: The title of the node.
+ *
+ * @param object $old_node
+ *   The older node revision.
+ * @param object $new_node
+ *   The newer node revision.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
+ *   - old_entity: The older entity.
+ *   - new_entity: The newer entity.
+ *   - view_mode: The view mode to use. Defaults to FALSE. If no view mode is
+ *                given, the recommended fallback view mode is 'default'.
+ *   - states: An array of view states. These could be one of:
+ *     - raw: The raw value of the diff, the classic 7.x-2.x view.
+ *     - rendered: The rendered HTML as determined by the view mode. Only
+ *                 return markup for this state if the value is normally shown
+ *                 by this view mode. The user will most likely be able to see
+ *                 the raw or raw_plain state, so this is optional.
+ *
+ *                 The rendering state is a work in progress.
+ *
+ *     Conditionally, you can get these states, but setting these will override
+ *     the user selectable markdown method.
+ *
+ *     - raw_plain: As raw, but text should be markdowned.
+ *     - rendered_plain: As rendered, but text should be markdowned.
+ *
+ * @return array
+ *   An associative array of values keyed by the entity property.
+ *
+ *   This is effectively an unnested Form API-like structure.
+ *
+ *   States are returned as follows:
+ *
+ *   $results['line'] = array(
+ *     '#name' => t('Line'),
+ *     '#states' => array(
+ *       'raw' => array(
+ *         '#old' => '<p class="line">This was the old line number [tag].</p>',
+ *         '#new' => '<p class="line">This is the new line [tag].</p>',
+ *       ),
+ *       'rendered' => array(
+ *         '#old' => '<p class="line">This was the old line number <span class="line-number">57</span>.</p>',
+ *         '#new' => '<p class="line">This is the new line <span class="line-number">57</span>.</p>',
+ *       ),
+ *     ),
+ *   );
+ *
+ *   For backwards compatability, no changes are required to support states,
+ *   but it is recommended to provide a better UI for end users.
+ *
+ *   For example, the following example is equivalent to returning the raw
+ *   state from the example above.
+ *
+ *   $results['line'] = array(
+ *     '#name' => t('Line'),
+ *     '#old' => '<p class="line">This was the old line number [tag].</p>',
+ *     '#new' => '<p class="line">This is the new line [tag].</p>',
+ *   );
+ */
+function node_entity_diff($old_node, $new_node, $context) {
+  $result = array();
+  if ($context['entity_type'] == 'node') {
+    $type = node_type_get_type($new_node);
+    $result['title'] = array(
+      '#name' => $type->title_label,
+      '#states' => array(),
+      '#weight' => -5,
+      '#settings' => array(
+        // Global setting - 'diff_show_header_' . $entity_type
+        'show_header' => variable_get('diff_show_header_node', 1),
+      ),
+    );
+    foreach ($context['states'] as $state) {
+      switch ($state) {
+        case 'rendered':
+          $result['title']['#states'][$state] = array(
+            '#old' => l($old_node->title, 'node/' . $old_node->title),
+            '#new' => l($new_node->title, 'node/' . $new_node->title),
+          );
+          break;
+
+        // We specify a default so that the title is allows compared.
+        case 'raw':
+        default:
+          $result['title']['#states'][$state] = array(
+            '#old' => array($old_node->title),
+            '#new' => array($new_node->title),
+          );
+          break;
+      }
+    }
+  }
+  return $result;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/includes/number.inc b/profiles/wcm_base/modules/contrib/diff/includes/number.inc
new file mode 100644
index 00000000..45e05133
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/includes/number.inc
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @file
+ * Provide diff field functions for the Number module.
+ */
+
+/**
+ * Diff field callback for parsing number field comparative values.
+ */
+function number_field_diff_view($items, $context) {
+  $diff_items = array();
+  foreach ($items as $delta => $item) {
+    $diff_items[$delta] = $item['value'];
+  }
+  return $diff_items;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/includes/taxonomy.inc b/profiles/wcm_base/modules/contrib/diff/includes/taxonomy.inc
new file mode 100644
index 00000000..5765c9c2
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/includes/taxonomy.inc
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * @file
+ * Implements pusdeo-hook hook_field_diff_view() for the Taxonomy module.
+ */
+
+/**
+ * Diff field callback for preloading term entities.
+ */
+function taxonomy_field_diff_view_prepare(&$old_items, &$new_items, $context) {
+  $tids = array();
+  foreach (array_merge_recursive($old_items, $new_items) as $info) {
+    $tids[$info['tid']] = $info['tid'];
+  }
+  $terms = taxonomy_term_load_multiple($tids);
+  foreach ($old_items as $delta => $info) {
+    $old_items[$delta]['term'] = isset($terms[$info['tid']]) ? $terms[$info['tid']] : NULL;
+  }
+  foreach ($new_items as $delta => $info) {
+    $new_items[$delta]['term'] = isset($terms[$info['tid']]) ? $terms[$info['tid']] : NULL;
+  }
+}
+
+/**
+ * Diff field callback for parsing term field comparative values.
+ */
+function taxonomy_field_diff_view($items, $context) {
+  $settings = $context['settings'];
+  $instance = $context['instance'];
+
+  $diff_items = array();
+  foreach ($items as $delta => $item) {
+    if (!empty($item['tid'])) {
+      if ($item['tid'] == 'autocreate') {
+        $diff_items[$delta] = t('!term_name (new)', array('!term_name' => $item['name']));
+      }
+      elseif (empty($item['term'])) {
+        $diff_items[$delta] = t('Missing term reference (!tid)', array('!tid' => $item['tid']));
+      }
+      else {
+        $output = array();
+        $output['name'] = $item['term']->name;
+        if ($settings['show_id']) {
+          $output['tid'] = t('Term ID: !tid', array('!tid' => $item['term']->tid));
+        }
+        $diff_items[$delta] = implode('; ', $output);
+      }
+    }
+  }
+  if (!empty($settings['sort']) && !empty($diff_items)) {
+    if ($settings['sort'] == DIFF_SORT_VALUE || $instance['widget']['type'] == 'taxonomy_autocomplete') {
+      usort($diff_items, 'uasort_taxonomy_field_diff_terms');
+    }
+  }
+  return $diff_items;
+}
+
+/**
+ * Helper function for sorting terms.
+ */
+function uasort_taxonomy_field_diff_terms($a, $b) {
+  // We need to use t() to test for string overrides.
+  $missing_text = t('Missing term reference');
+  $a_missing = strpos($a, $missing_text) === 0;
+  $b_missing = strpos($b, $missing_text) === 0;
+  if ($a_missing && $b_missing) {
+    return strnatcmp($a, $b);
+  }
+  elseif ($a_missing xor $b_missing) {
+    return $a_missing ? 100 : -100;
+  }
+  return strnatcmp($a, $b);
+}
+
+/**
+ * Provide default field comparison options.
+ */
+function taxonomy_field_diff_default_options($field_type) {
+  return array(
+    'show_id' => 0,
+    'sort' => DIFF_SORT_CUSTOM,
+  );
+}
+
+/**
+ * Provide a form for setting the field comparison options.
+ */
+function taxonomy_field_diff_options_form($field_type, $settings) {
+  $options_form = array();
+  $options_form['show_id'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show term ID'),
+    '#default_value' => $settings['show_id'],
+  );
+  $options_form['sort'] = array(
+    '#type' => 'radios',
+    '#title' => t('Sort'),
+    '#options' => array(
+      DIFF_SORT_NONE => t('No sort'),
+      DIFF_SORT_VALUE => t('Sort'),
+      DIFF_SORT_CUSTOM => t('Sort if free tagging field'),
+    ),
+    '#default_value' => $settings['sort'],
+  );
+  return $options_form;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/includes/text.inc b/profiles/wcm_base/modules/contrib/diff/includes/text.inc
new file mode 100644
index 00000000..b27e55ff
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/includes/text.inc
@@ -0,0 +1,113 @@
+<?php
+
+/**
+ * @file
+ * Provide diff field functions for the Text module.
+ */
+
+/**
+ * Diff field callback for parsing text field comparative values.
+ */
+function text_field_diff_view($items, $context) {
+  $field = $context['field'];
+  $instance = $context['instance'];
+  $settings = $context['settings'];
+
+  $diff_items = array();
+  foreach ($items as $delta => $item) {
+    $diff_items[$delta] = array();
+
+    // Compute the format for appending to the label.
+    $format_text = '';
+    if ($instance['settings']['text_processing'] && $settings['compare_format']) {
+      $format_id = empty($item['format']) ? filter_fallback_format() : $item['format'];
+      if ($format = filter_format_load($format_id)) {
+        $format_text = $format->name;
+      }
+      else {
+        $format_text = t('Missing format !format', array('!format' => $format_id));
+      }
+    }
+
+    // Compare the summary fields.
+    $summary = $field['type'] == 'text_with_summary' && $settings['compare_summary'];
+    if ($summary) {
+      // Allow users to optionally clean system specific characters.
+      if (empty($item['summary'])) {
+        $diff_items[$delta][] = t('Summary field is empty.');
+      }
+      else {
+        if ($format_text) {
+          $diff_items[$delta][] = t('Summary (!text_format):', array('!text_format' => $format_text));
+        }
+        else {
+          $diff_items[$delta][] = t('Summary:');
+        }
+        $diff_items[$delta][] = diff_normalise_text($item['summary']);
+      }
+    }
+
+    // Only show label if field has summary displayed.
+    if ($summary) {
+      if ($format_text) {
+        $diff_items[$delta][] = t('Content (!text_format):', array('!text_format' => $format_text));
+      }
+      else {
+        $diff_items[$delta][] = t('Content:');
+      }
+    }
+
+    // Allow users to optionally clean system specific characters.
+    $diff_items[$delta][] = diff_normalise_text($item['value']);
+
+    // If no summary, append the format selection to the bottom of the screen.
+    // This prevents adding the "Content (format)" label.
+    if ($format_text && !$summary) {
+      $diff_items[$delta][] = t('Text format: !text_format', array('!text_format' => $format_text));
+    }
+
+    $diff_items[$delta] = $diff_items[$delta];
+  }
+  return $diff_items;
+}
+
+/**
+ * Provide default field comparison options.
+ */
+function text_field_diff_default_options($field_type) {
+  // Overrides the global 'markdown' setting which does not escape HTML.
+  $settings = array(
+    'compare_format' => 0,
+    'markdown' => 'drupal_html_to_text',
+    'line_counter' => '',
+  );
+  if ($field_type == 'text_with_summary') {
+    $settings += array(
+      'compare_summary' => 0,
+    );
+  }
+
+  return $settings;
+}
+
+/**
+ * Provide a form for setting the field comparison options.
+ */
+function text_field_diff_options_form($field_type, $settings) {
+  $options_form = array();
+  $options_form['compare_format'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Compare format'),
+    '#default_value' => $settings['compare_format'],
+    '#description' => t('This is only used if the "Text processing" instance settings are set to <em>Filtered text (user selects text format)</em>.'),
+  );
+  if ($field_type == 'text_with_summary') {
+    $options_form['compare_summary'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Compare summary separately'),
+      '#default_value' => $settings['compare_summary'],
+      '#description' => t('This is only used if the "Summary input" option is checked in the instance settings.'),
+    );
+  }
+  return $options_form;
+}
diff --git a/profiles/wcm_base/modules/contrib/diff/js/diff.js b/profiles/wcm_base/modules/contrib/diff/js/diff.js
new file mode 100644
index 00000000..2c873e9f
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/js/diff.js
@@ -0,0 +1,58 @@
+(function ($) {
+
+Drupal.behaviors.diffRevisions = {
+  attach: function (context, settings) {
+    var $rows = $('table.diff-revisions tbody tr');
+    function updateDiffRadios() {
+      var newTd = false;
+      var oldTd = false;
+      if (!$rows.length) {
+        return true;
+      }
+      $rows.removeClass('selected').each(function() {
+        var $row = $(this);
+        $row.removeClass('selected');
+        var $inputs = $row.find('input[type="radio"]');
+        var $oldRadio = $inputs.filter('[name="old"]').eq(0);
+        var $newRadio = $inputs.filter('[name="new"]').eq(0);
+        if (!$oldRadio.length || !$newRadio.length) {
+          return true;
+        }
+        if ($oldRadio.attr('checked')) {
+          oldTd = true;
+          $row.addClass('selected');
+          $oldRadio.css('visibility', 'visible');
+          $newRadio.css('visibility', 'hidden');
+        } else if ($newRadio.attr('checked')) {
+          newTd = true;
+          $row.addClass('selected');
+          $oldRadio.css('visibility', 'hidden');
+          $newRadio.css('visibility', 'visible');
+        } else {
+          if (Drupal.settings.diffRevisionRadios == 'linear') {
+            if (newTd && oldTd) {
+              $oldRadio.css('visibility', 'visible');
+              $newRadio.css('visibility', 'hidden');
+            } else if (newTd) {
+              $newRadio.css('visibility', 'visible');
+              $oldRadio.css('visibility', 'visible');
+            } else {
+              $newRadio.css('visibility', 'visible');
+              $oldRadio.css('visibility', 'hidden');
+            }
+          } else {
+            $newRadio.css('visibility', 'visible');
+            $oldRadio.css('visibility', 'visible');
+          }
+        }
+      });
+      return true;
+    }
+    if (Drupal.settings.diffRevisionRadios) {
+      $rows.find('input[name="new"], input[name="old"]').click(updateDiffRadios);
+      updateDiffRadios();
+    }
+  }
+};
+
+})(jQuery);
diff --git a/profiles/wcm_base/modules/contrib/diff/readme.txt b/profiles/wcm_base/modules/contrib/diff/readme.txt
new file mode 100644
index 00000000..f82db821
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/diff/readme.txt
@@ -0,0 +1,136 @@
+Diff module - http://drupal.org/project/diff
+============================================
+
+Diff enhances usage of node revisions by adding the following features:
+
+- Diff between node revisions on the 'Revisions' tab to view all the changes
+  between any two revisions of a node.
+- Highlight changes inline while viewing a node to quickly see color-coded
+  additions, changes, and deletions.
+- Preview changes as a diff before updating a node.
+
+It is also an API to compare any entities although this functionality is not
+exposed by the core Diff module.
+
+REQUIREMENTS
+------------
+Drupal 7.x
+
+INSTALLATION
+------------
+1.  Place the Diff module into your modules directory.
+    This is normally the "sites/all/modules" directory.
+
+2.  Go to admin/build/modules. Enable the module.
+    The Diff modules is found in the Other section.
+
+Read more about installing modules at http://drupal.org/node/70151
+
+See the configuration section below.
+
+UPGRADING
+---------
+Any updates should be automatic. Just remember to run update.php!
+
+CONFIGURATION
+-------------
+
+Unlike the earlier version, the module now has a lot of configurable settings.
+
+Global settings can be found under Configuration > Content > Diff
+
+i.e. http://www.example.com/admin/config/content/diff
+
+Entity specific settings would be listed under the entities settings. This 
+module only handles Node revisioning functionality, and these are detailed 
+below.
+
+1) Node revisioning settings
+
+Diff needs to be configured to be used with specific node types on your site.
+To enable any of Diff's options on a content type's settings page.
+
+e.g. http://www.example.com/admin/structure/types/manage/page
+
+  a) Diff options
+
+  Under "Compare revisions", enable the settings that you want;
+  
+    i) "Show View changes button on node edit form" adds a new "Preview" like
+        submit button to node editing pages. This shows a diff preview.
+  
+    ii) "Enable the Revisions page for this content type" adds the revisioning
+         tab to content. This allows users to compare between various revisions
+         that they have access to.
+  
+    iii) "Standard comparison preview" option allows you to control how the most
+          current revision is show on the revision comparision page.
+       
+  b) Publishing options
+
+  It is strongly advised that you also enable the automatic creation of
+  revisions on any content types you want to use this with. If you do not do
+  this, chances are there will be limited revisioning information available to
+  compare. 
+
+  Under "Publishing options", enable "Create new revision".
+
+2) Field revisioning settings
+
+   Global settings per field type can be found here:
+
+   http://www.example.com/admin/config/content/diff/fields
+
+   "Show field title" toggles field title visibility on the comparison page.
+   
+   "Markdown callback" is the callback used to render the field when viewing the
+   page in the "Marked down" page view.
+   
+   "Line counter" is an optional. This shows the approximate line number where
+   the change occurred. This is an approximate counter only.
+   
+   Other fields add additional settings here.
+   
+3) Entity revisioning settings
+
+  Global configurable settings limited to node entities.
+
+  a) Show entity label header
+  
+  This provides a field like title for the entity label field.
+  
+  i.e. For nodes, this provides a header for the node's title. 
+  
+  b) Treat diff pages as administrative
+  
+  By default, the revisioning pages are administrative, i.e. they will use the
+  administration theme. You can block this by unchecking this option.
+  
+4) Global settings
+
+A small number of new features have been added to the 7.x-3.x branch, these
+include the ability to change the leading and trailing lines in the comparison,
+a new CSS theme for the diff pages, new JScript options for the revisioning
+selection form and options to help prevent cross operating systems in relation
+to line endings.
+
+http://www.example.com/admin/config/content/diff
+
+Technical
+---------
+- Diff compares the raw data, not the filtered output, making it easier to see
+changes to HTML entities, etc.
+- The diff engine itself is a GPL'ed php diff engine from phpwiki.
+
+API
+---
+See diff.api.php
+
+Maintainers
+-----------
+- realityloop (Brian Gilbert)
+- Alan D. (Alan Davison)
+- dww (Derek Wright)
+- moshe (Moshe Weitzman)
+- rötzi (Julian)
+- yhahn (Young Hahn)
diff --git a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.info b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.info
index ce149140..b7bc7109 100644
--- a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.info
+++ b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.info
@@ -19,9 +19,9 @@ dependencies[] = ctools
 dependencies[] = entity
 dependencies[] = views
 
-; Information added by Drupal.org packaging script on 2015-07-11
-version = "7.x-2.1+9-dev"
+; Information added by Drupal.org packaging script on 2016-09-07
+version = "7.x-2.1+10-dev"
 core = "7.x"
 project = "draggableviews"
-datestamp = "1436650744"
+datestamp = "1473261841"
 
diff --git a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.module b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.module
index 22aeeba3..a9fcab40 100644
--- a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.module
+++ b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.module
@@ -591,3 +591,20 @@ function _draggableviews_get_views_options($view = NULL) {
   }
   return $options;
 }
+
+/**
+ * Implements hook_node_delete().
+ */
+function draggableviews_node_delete($node) {
+  // Code to check if entry present in draggableviews_structure table.
+  $nid = $node->nid;
+  $query = db_select('draggableviews_structure', 'ds')
+      ->condition('entity_id', $nid)
+      ->fields('ds', array('view_name'));
+
+  $result = $query->execute()->rowCount();
+  // Code to remove entries from draggableviews_structure table.
+  if ($result > 0) {
+    db_delete('draggableviews_structure')->condition('entity_id', $nid)->execute();
+  }
+}
diff --git a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews_book/draggableviews_book.info b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews_book/draggableviews_book.info
index 473802a2..f7a97740 100644
--- a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews_book/draggableviews_book.info
+++ b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews_book/draggableviews_book.info
@@ -7,9 +7,9 @@ files[] = draggableviews_book_views_handler_argument.inc
 
 dependencies[] = draggableviews
 dependencies[] = book
-; Information added by Drupal.org packaging script on 2015-07-11
-version = "7.x-2.1+9-dev"
+; Information added by Drupal.org packaging script on 2016-09-07
+version = "7.x-2.1+10-dev"
 core = "7.x"
 project = "draggableviews"
-datestamp = "1436650744"
+datestamp = "1473261841"
 
diff --git a/profiles/wcm_base/modules/contrib/draggableviews/test/draggableviews_test/draggableviews_test.info b/profiles/wcm_base/modules/contrib/draggableviews/test/draggableviews_test/draggableviews_test.info
index caac68d6..4ecd4576 100644
--- a/profiles/wcm_base/modules/contrib/draggableviews/test/draggableviews_test/draggableviews_test.info
+++ b/profiles/wcm_base/modules/contrib/draggableviews/test/draggableviews_test/draggableviews_test.info
@@ -4,9 +4,9 @@ dependencies[] = draggableviews
 package = Views
 core = 7.x
 hidden = TRUE
-; Information added by Drupal.org packaging script on 2015-07-11
-version = "7.x-2.1+9-dev"
+; Information added by Drupal.org packaging script on 2016-09-07
+version = "7.x-2.1+10-dev"
 core = "7.x"
 project = "draggableviews"
-datestamp = "1436650744"
+datestamp = "1473261841"
 
diff --git a/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.features.wysiwyg.inc b/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.features.wysiwyg.inc
index f8d544b2..79902ef8 100644
--- a/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.features.wysiwyg.inc
+++ b/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.features.wysiwyg.inc
@@ -52,6 +52,9 @@ function ocio_wysiwyg_wysiwyg_default_profiles() {
         'accordion' => array(
           'accordion' => 1,
         ),
+        'menuMods' => array(
+          'tabs' => 1,
+        ),
         'tabs' => array(
           'tabs' => 1,
         ),
@@ -70,10 +73,10 @@ function ocio_wysiwyg_wysiwyg_default_profiles() {
       'acf_allowed_content' => '',
       'css_setting' => 'none',
       'css_path' => '',
-      'stylesSet' => 'Tagline=div.tagline
-Subhead=p.subhead
-Intro Text=p.intro-text
-Button=a.button
+      'stylesSet' => 'Tagline=div.tagline
+Subhead=p.subhead
+Intro Text=p.intro-text
+Button=a.button
 Pull Quote=blockquote.pull-quote',
       'block_formats' => 'p,h2,h3,h4',
       'advanced__active_tab' => 'edit-basic',
diff --git a/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.module b/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.module
index 6bc0ef2b..f6cb7d57 100644
--- a/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.module
+++ b/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.module
@@ -24,7 +24,7 @@ function ocio_wysiwyg_wysiwyg_editor_settings_alter(&$settings, $context) {
       $settings['contentsCss'][] = $module_path . '/replace/ui/themes/base/minified/jquery.ui.tabs.min.css';
     }
 
-    $settings['removeDialogTabs'] = 'table:advanced';
+    $settings['removeDialogTabs'] = 'tableProperties:advanced;';
 
     $settings['justifyClasses'] = array(
       'align-left',
@@ -63,6 +63,13 @@ function ocio_wysiwyg_wysiwyg_plugin($editor, $version) {
           ),
           'load' => TRUE,
         ),
+        'menuMods' => array(
+          'path' => drupal_get_path('module', 'ocio_wysiwyg') . '/plugins/menuMods',
+          'buttons' => array(
+            'menuMods' => t('MenuMods'),
+          ),
+          'load' => TRUE,
+        ),
       );
     break;
   }
diff --git a/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/icon-tabs.png b/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/icon-tabs.png
deleted file mode 100644
index 313444964140432f3389370180dd18b1118d819f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 344
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z
z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?d}4kf#9d}?s_1_
zS>O>_%)r1c1j3A$?$-SQ3hwcAaSX9Iy>#+MuEPdAF6WC_mG(a}4X#)Fcl)2OfeT;U
zsZtJEDe+lL*tgpxD*nuQ;LpnNXL;k3IgXzWUpA3VvP}2L=1p8)8q2@&n$(ghmwLDA
zoK_6;YCQA#j_A1!(QCJAuh2SHn3B!QkdP*?)6$SA@!*|<*Glik+4HQ+b(XpWUbVaJ
zTll<hrIw4!y8VoTC$?K#tcub;a#!EHpgd;&|GjQKA3r^mP)<lY@@=8t?K2#c$|v>f
f@BII%`N>~a1^N4~$2bfuL7wz<^>bP0l+XkKNMU=t

diff --git a/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/menuMods/plugin.js b/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/menuMods/plugin.js
new file mode 100644
index 00000000..3332a0c3
--- /dev/null
+++ b/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/menuMods/plugin.js
@@ -0,0 +1,18 @@
+(function($){
+  CKEDITOR.plugins.add('menuMods');
+
+  CKEDITOR.on('dialogDefinition', function(ev) {
+    if (ev.data.name == 'cellProperties') {
+      var infoTab = ev.data.definition.getContents('info');
+      infoTab.remove('width');
+      infoTab.remove('widthType');
+      infoTab.remove('height');
+      infoTab.remove('htmlHeightType');
+      infoTab.remove('borderColor');
+      infoTab.remove('bgColor');
+      infoTab.remove('borderColorChoose');
+      infoTab.remove('bgColorChoose');
+    }
+  });
+
+})(jQuery);
diff --git a/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/tabs/plugin.js b/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/tabs/plugin.js
index c812e83f..6d50ea40 100644
--- a/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/tabs/plugin.js
+++ b/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/tabs/plugin.js
@@ -43,4 +43,5 @@ CKEDITOR.plugins.add('tabs', {
     });
   }
 });
+
 })(jQuery);
diff --git a/profiles/wcm_base/modules/custom/wcm_panels_settings/wcm_panels_settings.module b/profiles/wcm_base/modules/custom/wcm_panels_settings/wcm_panels_settings.module
index 3f03e405..07d7e1b0 100644
--- a/profiles/wcm_base/modules/custom/wcm_panels_settings/wcm_panels_settings.module
+++ b/profiles/wcm_base/modules/custom/wcm_panels_settings/wcm_panels_settings.module
@@ -237,3 +237,16 @@ function wcm_panels_settings_linkchecker_node_links_alter(&$links, $node, $conte
 function wcm_panels_settings_form_panels_ipe_edit_control_form_alter(&$form, &$form_state) {
   $form['options']['revision']['#default_value'] = FALSE;
 }
+
+/*
+ * Implements hook_panels_display_save().
+ *
+ * Clear page cache when saving panelized node.
+ */
+function wcm_panels_settings_panels_display_save($display) {
+  if (isset($display->context['panelizer']) && $display->context['panelizer']->plugin == 'entity:node') {
+    $path = $display->context['panelizer']->data->path['source'];
+    $url = url($path, array('absolute' => TRUE));
+    cache_clear_all($url, 'cache_page');
+  }
+}
diff --git a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.features.inc b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.features.inc
index 90be2ac2..6291b13b 100644
--- a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.features.inc
+++ b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.features.inc
@@ -4,6 +4,15 @@
  * wcm_workbench.features.inc
  */
 
+/**
+ * Implements hook_ctools_plugin_api().
+ */
+function wcm_workbench_ctools_plugin_api($module = NULL, $api = NULL) {
+  if ($module == "strongarm" && $api == "strongarm") {
+    return array("version" => "1");
+  }
+}
+
 /**
  * Implements hook_views_api().
  */
diff --git a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.info b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.info
index 7ce79e0f..49d21364 100644
--- a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.info
+++ b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.info
@@ -5,11 +5,14 @@ package = WCM Configuration
 version = 7.x-1.0
 project = wcm_workbench
 dependencies[] = ctools
+dependencies[] = diff
 dependencies[] = features
+dependencies[] = strongarm
 dependencies[] = views
 dependencies[] = workbench
 dependencies[] = workbench_media
 dependencies[] = workbench_moderation
+features[ctools][] = strongarm:strongarm:1
 features[ctools][] = views:views_default:3.0
 features[features_api][] = api:2
 features[features_override_items][] = views_view.workbench_edited
@@ -33,6 +36,11 @@ features[features_overrides][] = views_view.workbench_recent_content.display|pag
 features[features_overrides][] = views_view.workbench_recent_content.display|page_1|display_options|menu|title
 features[features_overrides][] = views_view.workbench_recent_content.display|page_1|display_options|path
 features[features_overrides][] = views_view.workbench_recent_content.display|page_1|display_options|title
+features[variable][] = diff_context_lines_leading
+features[variable][] = diff_context_lines_trailing
+features[variable][] = diff_default_state_node
+features[variable][] = diff_radio_behavior
+features[variable][] = diff_theme
 features[views_view][] = files
 features[workbench_moderation_states][] = draft
 features[workbench_moderation_states][] = needs_review
diff --git a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.make b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.make
index f7fad68d..3e87074d 100644
--- a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.make
+++ b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.make
@@ -29,3 +29,6 @@ projects[workbench_moderation][patch][1492118] = http://drupal.org/files/issues/
 projects[workbench_moderation][patch][2485713] = http://drupal.org/files/issues/workbench-moderation-ajax-block-2485713-6.patch
 projects[workbench_moderation][patch][2462453] = http://drupal.org/files/issues/workbench_moderation-iib-var-2462453-1.patch
 projects[workbench_moderation][patch][2360973] = http://drupal.org/files/issues/workbench_moderation-install-warnings-2360973-3.patch
+
+projects[diff][version] = 3.2
+projects[diff][subdir] = contrib
diff --git a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.module b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.module
index 7082266a..a8611c2d 100644
--- a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.module
+++ b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.module
@@ -47,3 +47,39 @@ function wcm_workbench_form_node_revision_delete_confirm_alter(&$form, &$form_st
    $form['description']['#prefix'] = t('You are about to delete the revision of %title dated @time.', array('%title' => $form['#node_revision']->title, '@time' => format_date($form['#node_revision']->revision_timestamp)));
 }
 
+/*
+ * Implements hook_node_view().
+ *
+ * Add links to workbench block to view changes between revisions.
+ */
+function wcm_workbench_node_view($node, $view_mode) {
+  if ($view_mode = 'full') {
+    $links = array();
+
+    $url = 'node/'. $node->nid . '/moderation/diff/view/';
+
+    if(isset($node->workbench_moderation['published'])) {
+      $published = $node->workbench_moderation['published']->vid;
+      if ($node->vid != $published) {
+        $links[] = l('Published revision', $url . $published . '/' . $node->vid);
+      }
+    }
+
+    if(isset($node->workbench_moderation['current']) ) {
+      $current = $node->workbench_moderation['current']->vid;
+      if ($node->vid != $current) {
+        $links[] = l('Latest draft', $url .  $node->vid . '/' . $current);
+      }
+    }
+
+    if (!empty($links)) {
+      $messages = array(
+        'label' => t('Compare to'),
+        'message' => implode($links, ' | ')
+      );
+      workbench_moderation_messages('view', $node);
+      workbench_moderation_set_message(array($messages));
+    }
+  }
+}
+
diff --git a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.strongarm.inc b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.strongarm.inc
new file mode 100644
index 00000000..4e27b2ec
--- /dev/null
+++ b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.strongarm.inc
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @file
+ * wcm_workbench.strongarm.inc
+ */
+
+/**
+ * Implements hook_strongarm().
+ */
+function wcm_workbench_strongarm() {
+  $export = array();
+
+  $strongarm = new stdClass();
+  $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
+  $strongarm->api_version = 1;
+  $strongarm->name = 'diff_context_lines_leading';
+  $strongarm->value = '2';
+  $export['diff_context_lines_leading'] = $strongarm;
+
+  $strongarm = new stdClass();
+  $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
+  $strongarm->api_version = 1;
+  $strongarm->name = 'diff_context_lines_trailing';
+  $strongarm->value = '2';
+  $export['diff_context_lines_trailing'] = $strongarm;
+
+  $strongarm = new stdClass();
+  $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
+  $strongarm->api_version = 1;
+  $strongarm->name = 'diff_default_state_node';
+  $strongarm->value = 'raw_plain';
+  $export['diff_default_state_node'] = $strongarm;
+
+  $strongarm = new stdClass();
+  $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
+  $strongarm->api_version = 1;
+  $strongarm->name = 'diff_radio_behavior';
+  $strongarm->value = 'simple';
+  $export['diff_radio_behavior'] = $strongarm;
+
+  $strongarm = new stdClass();
+  $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
+  $strongarm->api_version = 1;
+  $strongarm->name = 'diff_theme';
+  $strongarm->value = 'default';
+  $export['diff_theme'] = $strongarm;
+
+  return $export;
+}
diff --git a/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.css b/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.css
index 69e69116..00d07f5d 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.css
+++ b/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.css
@@ -247,31 +247,6 @@ textarea {
   resize: none;
 }
 
-.webform-component label {
-  text-transform: uppercase;
-  font-weight: 600;
-  font-size: 14px;
-}
-.webform-component .description {
-  margin-bottom: 30px;
-}
-
-.webform-component-fieldset .webform-component label {
-  text-transform: uppercase;
-  font-weight: 400;
-  font-size: 13px;
-}
-
-.webform-component-fieldset,
-.webform-component-file,
-.webform-component-grid {
-  margin-bottom: 40px;
-}
-
-.webform-component-file #edit-submitted-file-upload {
-  max-width: 240px;
-}
-
 @media (max-width: 47.5em) {
   .l-main input, .l-main select, .l-main textarea {
     width: 100%;
diff --git a/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.no-query.css b/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.no-query.css
index 991767ac..5c5d799b 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.no-query.css
+++ b/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.no-query.css
@@ -247,31 +247,6 @@ textarea {
   resize: none;
 }
 
-.webform-component label {
-  text-transform: uppercase;
-  font-weight: 600;
-  font-size: 14px;
-}
-.webform-component .description {
-  margin-bottom: 30px;
-}
-
-.webform-component-fieldset .webform-component label {
-  text-transform: uppercase;
-  font-weight: 400;
-  font-size: 13px;
-}
-
-.webform-component-fieldset,
-.webform-component-file,
-.webform-component-grid {
-  margin-bottom: 40px;
-}
-
-.webform-component-file #edit-submitted-file-upload {
-  max-width: 240px;
-}
-
 .l-main input, .l-main select, .l-main textarea {
   width: 100%;
 }
diff --git a/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.no-query.css b/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.no-query.css
index 2cdd13e4..af67a913 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.no-query.css
+++ b/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.no-query.css
@@ -76,7 +76,7 @@ html body .button,
 #edit-submit--3,
 .webform-submit,
 .webform-previous,
-.button-primary, .page-user-login .login-box.osu a, .node-type-webform #edit-submitted-file-upload-button {
+.button-primary, .page-user-login .login-box.osu a, .node-type-web-form #edit-submitted-file-upload-button {
   font-size: 14px;
   padding: 0.6em 1.3em 0.5em 1.3em;
   display: inline-block;
@@ -108,7 +108,7 @@ html body .button:hover,
 #edit-submit--3:hover,
 .webform-submit:hover,
 .webform-previous:hover,
-.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-webform #edit-submitted-file-upload-button:hover {
+.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-web-form #edit-submitted-file-upload-button:hover {
   text-decoration: none;
 }
 .red-button:hover, input[type=button]:hover,
@@ -120,7 +120,7 @@ html body .button:hover,
 #edit-submit--3:hover,
 .webform-submit:hover,
 .webform-previous:hover,
-.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-webform #edit-submitted-file-upload-button:hover {
+.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-web-form #edit-submitted-file-upload-button:hover {
   background-color: #a20000;
 }
 .red-button:active, input[type=button]:active,
@@ -132,7 +132,7 @@ html body .button:active,
 #edit-submit--3:active,
 .webform-submit:active,
 .webform-previous:active,
-.button-primary:active, .page-user-login .login-box.osu a:active, .node-type-webform #edit-submitted-file-upload-button:active {
+.button-primary:active, .page-user-login .login-box.osu a:active, .node-type-web-form #edit-submitted-file-upload-button:active {
   background-color: #920000;
 }
 .red-button.disabled, input.disabled[type=button],
@@ -144,7 +144,7 @@ html body .disabled.button,
 .disabled#edit-submit--3,
 .disabled.webform-submit,
 .disabled.webform-previous,
-.disabled.button-primary, .page-user-login .login-box.osu a.disabled, .node-type-webform .disabled#edit-submitted-file-upload-button, .red-button[disabled], input[disabled][type=button],
+.disabled.button-primary, .page-user-login .login-box.osu a.disabled, .node-type-web-form .disabled#edit-submitted-file-upload-button, .red-button[disabled], input[disabled][type=button],
 html body [disabled].button,
 [disabled].form-submit,
 [disabled]#edit-preview,
@@ -153,7 +153,7 @@ html body [disabled].button,
 [disabled]#edit-submit--3,
 [disabled].webform-submit,
 [disabled].webform-previous,
-[disabled].button-primary, .page-user-login .login-box.osu a[disabled], .node-type-webform [disabled]#edit-submitted-file-upload-button {
+[disabled].button-primary, .page-user-login .login-box.osu a[disabled], .node-type-web-form [disabled]#edit-submitted-file-upload-button {
   filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=60);
   opacity: 0.6;
   background: false;
@@ -171,7 +171,7 @@ html body .button::-moz-focus-inner,
 #edit-submit--3::-moz-focus-inner,
 .webform-submit::-moz-focus-inner,
 .webform-previous::-moz-focus-inner,
-.button-primary::-moz-focus-inner, .page-user-login .login-box.osu a::-moz-focus-inner, .node-type-webform #edit-submitted-file-upload-button::-moz-focus-inner {
+.button-primary::-moz-focus-inner, .page-user-login .login-box.osu a::-moz-focus-inner, .node-type-web-form #edit-submitted-file-upload-button::-moz-focus-inner {
   padding: 0 !important;
   margin: -1px !important;
 }
@@ -243,31 +243,6 @@ textarea {
   resize: none;
 }
 
-.webform-component label {
-  text-transform: uppercase;
-  font-weight: 600;
-  font-size: 14px;
-}
-.webform-component .description {
-  margin-bottom: 30px;
-}
-
-.webform-component-fieldset .webform-component label {
-  text-transform: uppercase;
-  font-weight: 400;
-  font-size: 13px;
-}
-
-.webform-component-fieldset,
-.webform-component-file,
-.webform-component-grid {
-  margin-bottom: 40px;
-}
-
-.webform-component-file #edit-submitted-file-upload {
-  max-width: 240px;
-}
-
 .l-main input, .l-main select, .l-main textarea {
   width: 100%;
 }
@@ -2478,18 +2453,46 @@ p.search-result__snippet {
   border: 1px solid #8c8c8c;
 }
 
-.node-type-webform .webform-component-fieldset {
-  margin: 40px 0 20px 0;
+.node-type-web-form .webform-component-fieldset {
+  margin: 30px 0 20px 0;
   padding: 20px 1.5em;
 }
-.node-type-webform .webform-component-fieldset legend {
+.node-type-web-form .webform-component-fieldset legend {
   text-transform: uppercase;
   font-weight: 600;
   padding: 0 0.375em;
 }
-.node-type-webform #edit-submitted-file-ajax-wrapper {
+.node-type-web-form #edit-submitted-file-ajax-wrapper {
   padding: 20px 0;
 }
+.node-type-web-form .webform-component > label {
+  text-transform: uppercase;
+  font-weight: 600;
+  margin-bottom: 0.4em;
+}
+.node-type-web-form .webform-component label.option {
+  font-size: 15px;
+  margin-left: 4px;
+}
+.node-type-web-form .webform-component .description, .node-type-web-form .webform-component.form-item, .node-type-web-form .webform-component.form-actions {
+  margin-bottom: 30px;
+}
+.node-type-web-form .webform-component-fieldset .webform-component > label {
+  text-transform: uppercase;
+  font-size: 15px;
+  color: #666666;
+}
+.node-type-web-form .webform-component-fieldset .webform-component.form-item:last-child {
+  margin-bottom: 0;
+}
+.node-type-web-form .webform-component-fieldset,
+.node-type-web-form .webform-component-file,
+.node-type-web-form .webform-component-grid {
+  margin-bottom: 30px;
+}
+.node-type-web-form .webform-component-file #edit-submitted-file-upload {
+  max-width: 240px;
+}
 
 .webform-client-form {
   padding-top: 2em;
diff --git a/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.styles.css b/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.styles.css
index 99db0135..ad36bd4e 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.styles.css
+++ b/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.styles.css
@@ -76,7 +76,7 @@ html body .button,
 #edit-submit--3,
 .webform-submit,
 .webform-previous,
-.button-primary, .page-user-login .login-box.osu a, .node-type-webform #edit-submitted-file-upload-button {
+.button-primary, .page-user-login .login-box.osu a, .node-type-web-form #edit-submitted-file-upload-button {
   font-size: 14px;
   padding: 0.6em 1.3em 0.5em 1.3em;
   display: inline-block;
@@ -108,7 +108,7 @@ html body .button:hover,
 #edit-submit--3:hover,
 .webform-submit:hover,
 .webform-previous:hover,
-.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-webform #edit-submitted-file-upload-button:hover {
+.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-web-form #edit-submitted-file-upload-button:hover {
   text-decoration: none;
 }
 .red-button:hover, input[type=button]:hover,
@@ -120,7 +120,7 @@ html body .button:hover,
 #edit-submit--3:hover,
 .webform-submit:hover,
 .webform-previous:hover,
-.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-webform #edit-submitted-file-upload-button:hover {
+.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-web-form #edit-submitted-file-upload-button:hover {
   background-color: #a20000;
 }
 .red-button:active, input[type=button]:active,
@@ -132,7 +132,7 @@ html body .button:active,
 #edit-submit--3:active,
 .webform-submit:active,
 .webform-previous:active,
-.button-primary:active, .page-user-login .login-box.osu a:active, .node-type-webform #edit-submitted-file-upload-button:active {
+.button-primary:active, .page-user-login .login-box.osu a:active, .node-type-web-form #edit-submitted-file-upload-button:active {
   background-color: #920000;
 }
 .red-button.disabled, input.disabled[type=button],
@@ -144,7 +144,7 @@ html body .disabled.button,
 .disabled#edit-submit--3,
 .disabled.webform-submit,
 .disabled.webform-previous,
-.disabled.button-primary, .page-user-login .login-box.osu a.disabled, .node-type-webform .disabled#edit-submitted-file-upload-button, .red-button[disabled], input[disabled][type=button],
+.disabled.button-primary, .page-user-login .login-box.osu a.disabled, .node-type-web-form .disabled#edit-submitted-file-upload-button, .red-button[disabled], input[disabled][type=button],
 html body [disabled].button,
 [disabled].form-submit,
 [disabled]#edit-preview,
@@ -153,7 +153,7 @@ html body [disabled].button,
 [disabled]#edit-submit--3,
 [disabled].webform-submit,
 [disabled].webform-previous,
-[disabled].button-primary, .page-user-login .login-box.osu a[disabled], .node-type-webform [disabled]#edit-submitted-file-upload-button {
+[disabled].button-primary, .page-user-login .login-box.osu a[disabled], .node-type-web-form [disabled]#edit-submitted-file-upload-button {
   filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=60);
   opacity: 0.6;
   background: false;
@@ -171,7 +171,7 @@ html body .button::-moz-focus-inner,
 #edit-submit--3::-moz-focus-inner,
 .webform-submit::-moz-focus-inner,
 .webform-previous::-moz-focus-inner,
-.button-primary::-moz-focus-inner, .page-user-login .login-box.osu a::-moz-focus-inner, .node-type-webform #edit-submitted-file-upload-button::-moz-focus-inner {
+.button-primary::-moz-focus-inner, .page-user-login .login-box.osu a::-moz-focus-inner, .node-type-web-form #edit-submitted-file-upload-button::-moz-focus-inner {
   padding: 0 !important;
   margin: -1px !important;
 }
@@ -243,31 +243,6 @@ textarea {
   resize: none;
 }
 
-.webform-component label {
-  text-transform: uppercase;
-  font-weight: 600;
-  font-size: 14px;
-}
-.webform-component .description {
-  margin-bottom: 30px;
-}
-
-.webform-component-fieldset .webform-component label {
-  text-transform: uppercase;
-  font-weight: 400;
-  font-size: 13px;
-}
-
-.webform-component-fieldset,
-.webform-component-file,
-.webform-component-grid {
-  margin-bottom: 40px;
-}
-
-.webform-component-file #edit-submitted-file-upload {
-  max-width: 240px;
-}
-
 @media (max-width: 47.5em) {
   .l-main input, .l-main select, .l-main textarea {
     width: 100%;
@@ -2510,18 +2485,46 @@ p.search-result__snippet {
   border: 1px solid #8c8c8c;
 }
 
-.node-type-webform .webform-component-fieldset {
-  margin: 40px 0 20px 0;
+.node-type-web-form .webform-component-fieldset {
+  margin: 30px 0 20px 0;
   padding: 20px 1.5em;
 }
-.node-type-webform .webform-component-fieldset legend {
+.node-type-web-form .webform-component-fieldset legend {
   text-transform: uppercase;
   font-weight: 600;
   padding: 0 0.375em;
 }
-.node-type-webform #edit-submitted-file-ajax-wrapper {
+.node-type-web-form #edit-submitted-file-ajax-wrapper {
   padding: 20px 0;
 }
+.node-type-web-form .webform-component > label {
+  text-transform: uppercase;
+  font-weight: 600;
+  margin-bottom: 0.4em;
+}
+.node-type-web-form .webform-component label.option {
+  font-size: 15px;
+  margin-left: 4px;
+}
+.node-type-web-form .webform-component .description, .node-type-web-form .webform-component.form-item, .node-type-web-form .webform-component.form-actions {
+  margin-bottom: 30px;
+}
+.node-type-web-form .webform-component-fieldset .webform-component > label {
+  text-transform: uppercase;
+  font-size: 15px;
+  color: #666666;
+}
+.node-type-web-form .webform-component-fieldset .webform-component.form-item:last-child {
+  margin-bottom: 0;
+}
+.node-type-web-form .webform-component-fieldset,
+.node-type-web-form .webform-component-file,
+.node-type-web-form .webform-component-grid {
+  margin-bottom: 30px;
+}
+.node-type-web-form .webform-component-file #edit-submitted-file-upload {
+  max-width: 240px;
+}
 
 .webform-client-form {
   padding-top: 2em;
diff --git a/profiles/wcm_base/themes/ocio_omega_base/sass/base/_forms.scss b/profiles/wcm_base/themes/ocio_omega_base/sass/base/_forms.scss
index 64cf94e0..146ee30a 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/sass/base/_forms.scss
+++ b/profiles/wcm_base/themes/ocio_omega_base/sass/base/_forms.scss
@@ -10,44 +10,6 @@ textarea {
   resize: none;
 }
 
-.webform-component {
-  label {
-    text-transform: uppercase;
-    font-weight: 600;
-    font-size: 14px;
-  }
-
-  .description {
-    margin-bottom: 1.5 * $vert-spacing-unit;
-  }
-}
-
-//label style for webcomponents nexted within fieldsets
-.webform-component-fieldset {
-  .webform-component {
-    label {
-      text-transform: uppercase;
-      font-weight: 400;
-      font-size: 13px;
-    }
-  }
-}
-
-//extra bottom margin for certain webfrom components -- add more as needed
-
-.webform-component-fieldset,
-.webform-component-file,
-.webform-component-grid {
-  margin-bottom: 2 * $vert-spacing-unit;
-}
-
-//special style for file upload component
-.webform-component-file {
-  #edit-submitted-file-upload {
-    max-width: 240px;
-  }
-}
-
 @include breakpoint($small, true) {
   .l-main {
     input, select, textarea {
diff --git a/profiles/wcm_base/themes/ocio_omega_base/sass/components/_webform.scss b/profiles/wcm_base/themes/ocio_omega_base/sass/components/_webform.scss
index 4d26475e..16cc19d1 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/sass/components/_webform.scss
+++ b/profiles/wcm_base/themes/ocio_omega_base/sass/components/_webform.scss
@@ -1,17 +1,17 @@
-.node-type-webform {
-	
+.node-type-web-form {
+
 	//fieldset
 	.webform-component-fieldset {
-		margin: 2 * $vert-spacing-unit 0 $vert-spacing-unit 0;
+		margin: 1.5 * $vert-spacing-unit 0 $vert-spacing-unit 0;
 		padding: $vert-spacing-unit $horz-spacing-unit;
-		
+
 		legend {
 			text-transform: uppercase;
 			font-weight: 600;
 			padding: 0 0.25 * $horz-spacing-unit;
 		}
 	}
-	
+
 	//file uploads
 	#edit-submitted-file-ajax-wrapper {
 		padding: $vert-spacing-unit 0;
@@ -19,21 +19,68 @@
 	#edit-submitted-file-upload-button {
 		@extend .red-button;
 	}
-}
 
+  .webform-component {
+    & > label {
+      text-transform: uppercase;
+      font-weight: 600;
+      margin-bottom: 0.4em;
+    }
+
+    label.option {
+      font-size: 15px;
+      margin-left: 4px;
+    }
+
+    .description,
+    &.form-item,
+    &.form-actions  {
+      margin-bottom: 1.5 * $vert-spacing-unit;
+    }
+  }
+
+  //label style for webcomponents nexted within fieldsets
+  .webform-component-fieldset {
+    .webform-component {
+      & > label {
+        text-transform: uppercase;
+        font-size: 15px;
+        color: $md-gray;
+      }
+
+      &.form-item:last-child {
+        margin-bottom: 0;
+      }
+    }
+  }
+
+  //extra bottom margin for certain webfrom components -- add more as needed
 
+  .webform-component-fieldset,
+  .webform-component-file,
+  .webform-component-grid {
+    margin-bottom: 1.5 * $vert-spacing-unit;
+  }
+
+  //special style for file upload component
+  .webform-component-file {
+    #edit-submitted-file-upload {
+      max-width: 240px;
+    }
+  }
+}
 
 .webform-client-form {
 	padding-top: 2em;
-	
+
 	.form-actions {
 		padding-top: 2em;
 	}
-	
+
 	.webform-previous {
 		margin-right: 10px;
 	}
-	
+
 	.messages {
 		border-left: 8px solid $red;
 		margin-bottom: 3em;
@@ -42,14 +89,14 @@
 			margin: 0;
 		}
 	}
-	
+
 	h2.webform-page {
 		@include font-size(2.4);
 		margin: 1.6em 0 0.6em 0;
 		padding-bottom: 6px;
 		border-bottom: 3px solid $lt-gray;
 	}
-	
+
 }
 
 
@@ -59,7 +106,7 @@
   width: 94%;
   margin-top: 2em;
   margin-bottom: 4em;
-  
+
 }
 .webform-progressbar-inner {
   background-color: $blue;
@@ -98,3 +145,4 @@
   font-family: $proxima;
   font-size: 14px;
 }
+
-- 
GitLab