diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 66c999d17684a43e5c8e2045ac9642fc71bb82d5..b4972a60b49f99709e49c81a29d0d4cb9b2b8647 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,4 +1,8 @@
 
+Drupal 7.41, 2015-10-21
+-----------------------
+- Fixed security issues (open redirect). See SA-CORE-2015-004.
+
 Drupal 7.40, 2015-10-14
 -----------------------
 - Made Drupal's code for parsing .info files run much faster and use much less
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 0cf91aa11abc12ee3e2f651b7b9db123546bb7ed..53462f27c983f4c91985938aafefcf272a900260 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -8,7 +8,7 @@
 /**
  * The current system version.
  */
-define('VERSION', '7.40');
+define('VERSION', '7.41');
 
 /**
  * Core API compatibility.
diff --git a/modules/overlay/overlay-parent.js b/modules/overlay/overlay-parent.js
index 7859821b49deef5b24136470edfbbe18233f5604..efb26370c506820f364798da8a3db3306a8427a5 100644
--- a/modules/overlay/overlay-parent.js
+++ b/modules/overlay/overlay-parent.js
@@ -350,7 +350,7 @@ Drupal.overlay.setFocusBefore = function ($element, document) {
  *   TRUE if the URL represents an administrative link, FALSE otherwise.
  */
 Drupal.overlay.isAdminLink = function (url) {
-  if (Drupal.overlay.isExternalLink(url)) {
+  if (!Drupal.urlIsLocal(url)) {
     return false;
   }
 
@@ -378,6 +378,8 @@ Drupal.overlay.isAdminLink = function (url) {
 /**
  * Determine whether a link is external to the site.
  *
+ * Deprecated. Use Drupal.urlIsLocal() instead.
+ *
  * @param url
  *   The URL to be tested.
  *
@@ -385,8 +387,7 @@ Drupal.overlay.isAdminLink = function (url) {
  *   TRUE if the URL is external to the site, FALSE otherwise.
  */
 Drupal.overlay.isExternalLink = function (url) {
-  var re = RegExp('^((f|ht)tps?:)?//(?!' + window.location.host + ')');
-  return re.test(url);
+  return !Drupal.urlIsLocal(url);
 };
 
 /**
@@ -405,7 +406,7 @@ Drupal.overlay.isExternalLink = function (url) {
  */
 Drupal.overlay.getInternalUrl = function (path) {
   var url = Drupal.settings.basePath + path;
-  if (!this.isExternalLink(url)) {
+  if (Drupal.urlIsLocal(url)) {
     return url;
   }
 };
diff --git a/profiles/wcm_base/CHANGELOG.txt b/profiles/wcm_base/CHANGELOG.txt
index 5db10c57dd9ebbede98872038ae8fd4979840c96..0ef5e90964c0af97b6c1d2f7998f05cfa79b64dc 100644
--- a/profiles/wcm_base/CHANGELOG.txt
+++ b/profiles/wcm_base/CHANGELOG.txt
@@ -1,3 +1,13 @@
+WCM Base 7.x-1.x, 2015-10-22
+----------------------------
+- OCIO Landing Page: Added create, delete and move permissions for Landing Page panes.
+- OCIO User Config: Enabled and customized Admin Views for the user admin page.
+- OCIO Omega Base:
+  - Set Landing Page banner images to 100% of page width.
+  - Improvements accessibility of Landing Page banner images.
+- OCIO Search: Remove image, audio and video files from search index.
+- OCIO Web Form: Enable HTML email and set it as the default format.
+
 WCM Base 7.x-1.x, 2015-10-21
 ----------------------------
 - OCIO Omega Base:
diff --git a/profiles/wcm_base/modules/contrib/mailsystem/LICENSE.txt b/profiles/wcm_base/modules/contrib/mailsystem/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d159169d1050894d3ea3b98e1c965c4058208fe1
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mailsystem/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/mailsystem/README.html b/profiles/wcm_base/modules/contrib/mailsystem/README.html
new file mode 100644
index 0000000000000000000000000000000000000000..6b778620586d7f0ea87713dff821572c723ceb35
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mailsystem/README.html
@@ -0,0 +1,113 @@
+<h2 id="mail-system"><a href="http://drupal.org/project/mailsystem">Mail System</a></h2>
+<p>Provides an Administrative UI and Developers API for safely updating the <a href="http://api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7">mail_system</a> configuration variable.</p>
+<h3 id="administrative-ui">Administrative UI</h3>
+<p>The administrative interface is at <code>admin/config/system/mailsystem</code>. A <a href="http://drupal.org/node/1134044">screenshot</a> is available.</p>
+<h3 id="used-by">Used by:</h3>
+<ul>
+  <li><a href="http://drupal.org/project/htmlmail">HTML Mail</a></li>
+  <li><a href="http://drupal.org/project/mimemail">Mime Mail 7.x-1.x-dev</a></li>
+  <li><a href="http://drupal.org/project/postmark">Postmark 7.x-1.x</a></li>
+</ul>
+<h3 id="developers-api">Developers API</h3>
+<p>A module <code>example</code> with a <a href="http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7"><code>MailSystemInterface</code></a> implementation called <code>ExampleMailSystem</code> should add the following in its <code>example.install</code> file:</p>
+<pre>
+<code>/**
+ * Implements hook_enable().
+ */
+function example_enable() {
+  mailsystem_set(array('example' => 'ExampleMailSystem'));
+}
+/**
+ * Implements hook_disable().
+ */
+function example_disable() {
+  mailsystem_clear(array('example' => 'ExampleMailSystem'));
+}
+</code>
+</pre>
+<p>The above settings allow mail sent by <code>example</code> to use <code>ExampleMailSystem</code>. To make <code>ExampleMailSystem</code> the site-wide default for sending mail:</p>
+<pre>
+<code>mailsystem_set(array(mailsystem_default_id() => 'ExampleMailSystem'));
+</code>
+</pre>
+<p>To restore the default mail system:</p>
+<pre>
+<code>mailsystem_set(array(mailsystem_default_id() => mailsystem_default_value()));
+</code>
+</pre>
+<p>Or simply:</p>
+<pre>
+<code>mailsystem_set(mailsystem_defaults());
+</code>
+</pre>
+<p>If module <code>example</code> relies on dependency <code>foo</code> and its <code>FooMailSystem</code> class, then the <code>example.install</code> code should like like this:</p>
+<pre>
+<code>/**
+ * Implements hook_enable().
+ */
+function example_enable() {
+  mailsystem_set(array('example' => 'FooMailSystem'));
+}
+/**
+ * Implements hook_disable().
+ */
+function example_disable() {
+  mailsystem_clear(array('example' => ''));
+}
+</code>
+</pre>
+<p>If module <code>example</code> only wants to use <code>FooMailSystem</code> when sending emails with a key of <code>examail</code>, then the <code>example.install</code> code should look like this:</p>
+<pre>
+<code>/**
+ * Implements hook_enable().
+ */
+function example_enable() {
+  mailsystem_set(array('example_examail' => 'FooMailSystem'));
+}
+/**
+ * Implements hook_disable().
+ */
+function example_disable() {
+  mailsystem_clear(array('example_examail' => ''));
+}
+</code>
+</pre>
+<h4 id="new-in-2.x-branch"><em>(New in 2.x branch)</em></h4>
+<p>To change the site-wide defaults to use the <code>FooMailSystem</code> for formatting messages and the <code>BarMailSystem</code> for sending them:</p>
+<pre>
+<code>mailsystem_set(
+  array(
+    mailsystem_default_id() =&gt; array(
+      'format' =&gt; 'FooMailSystem',
+      'mail' =&gt; 'BarMailSystem',
+    ),
+  )
+);
+</code>
+</pre>
+<p>To change the site-wide defaults to use the <code>FooMailSystem</code> for sending messages, while continuing to use the current system for formatting them:</p>
+<pre>
+<code>mailsystem_set(
+  array(
+    mailsystem_default_id() =&gt; array(
+      'mail' =&gt; 'FooMailsystem',
+    ),
+  )
+);
+</code>
+</pre>
+<h3 id="references">References</h3>
+<dl>
+  <dt><strong><a href="http://api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7"><code>drupal_mail_system()</code> API documentation</a></strong>:</dt>
+  <dd>
+    <p><a href="http://api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7">api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7</a></p>
+  </dd>
+  <dt><strong><a href="http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7"><code>MailSystemInterface</code> API documentation</a></strong>:</dt>
+  <dd>
+    <p><a href="http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7">api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7</a></p>
+  </dd>
+  <dt><strong><a href="http://drupal.org/node/900794">Creating HTML formatted mails in Drupal 7</a></strong>:</dt>
+  <dd>
+    <p><a href="http://drupal.org/node/900794">drupal.org/node/900794</a></p>
+  </dd>
+</dl>
diff --git a/profiles/wcm_base/modules/contrib/mailsystem/README.markdown b/profiles/wcm_base/modules/contrib/mailsystem/README.markdown
new file mode 100644
index 0000000000000000000000000000000000000000..6d549f904a5073de09b1a65d3cd0b08ad84bc9a4
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mailsystem/README.markdown
@@ -0,0 +1,118 @@
+## [Mail System](http://drupal.org/project/mailsystem)
+
+Provides an Administrative UI and Developers API for safely updating the
+[mail_system](http://api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7)
+configuration variable.
+
+### Administrative UI
+
+The administrative interface is at `admin/config/system/mailsystem`.
+A [screenshot](http://drupal.org/node/1134044) is available.
+
+### Used by:
+
+* [HTML Mail](http://drupal.org/project/htmlmail)
+* [Mime Mail 7.x-1.x-dev](http://drupal.org/project/mimemail)
+* [Postmark 7.x-1.x](http://drupal.org/project/postmark)
+
+### Developers API
+
+A module `example` with a
+[`MailSystemInterface`](http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7)
+implementation called `ExampleMailSystem` should add the following in its
+`example.install` file:
+
+    /**
+     * Implements hook_enable().
+     */
+    function example_enable() {
+      mailsystem_set(array('example' =\> 'ExampleMailSystem'));
+    }
+
+    /**
+     * Implements hook_disable().
+     */
+    function example_disable() {
+      mailsystem_clear(array('example' =\> 'ExampleMailSystem'));
+    }
+
+The above settings allow mail sent by `example` to use `ExampleMailSystem`.  To make
+`ExampleMailSystem` the site-wide default for sending mail:
+
+    mailsystem_set(array(mailsystem_default_id() =\> 'ExampleMailSystem'));
+
+To restore the default mail system:
+
+    mailsystem_set(array(mailsystem_default_id() =\> mailsystem_default_value()));
+
+Or simply:
+
+    mailsystem_set(mailsystem_defaults());
+
+If module `example` relies on dependency `foo` and its `FooMailSystem` class, then
+the `example.install` code should like like this:
+
+    /**
+     * Implements hook_enable().
+     */
+    function example_enable() {
+      mailsystem_set(array('example' =\> 'FooMailSystem'));
+    }
+
+    /**
+     * Implements hook_disable().
+     */
+    function example_disable() {
+      mailsystem_clear(array('example' =\> ''));
+    }
+
+If module `example` only wants to use `FooMailSystem` when sending emails with a key
+of `examail`, then the `example.install` code should look like this:
+
+    /**
+     * Implements hook_enable().
+     */
+    function example_enable() {
+      mailsystem_set(array('example_examail' =\> 'FooMailSystem'));
+    }
+
+    /**
+     * Implements hook_disable().
+     */
+    function example_disable() {
+      mailsystem_clear(array('example_examail' =\> ''));
+    }
+
+#### *(New in 2.x branch)*
+
+To change the site-wide defaults to use the `FooMailSystem` for formatting messages and the `BarMailSystem` for sending them:
+
+    mailsystem_set(
+      array(
+        mailsystem_default_id() => array(
+          'format' => 'FooMailSystem',
+          'mail' => 'BarMailSystem',
+        ),
+      )
+    );
+
+To change the site-wide defaults to use the `FooMailSystem` for sending messages, while continuing to use the current system for formatting them:
+
+    mailsystem_set(
+      array(
+        mailsystem_default_id() => array(
+          'mail' => 'FooMailsystem',
+        ),
+      )
+    );
+
+### References
+
+**[`drupal_mail_system()` API documentation](http://api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7)**:
+:    [api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7](http://api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7)
+
+**[`MailSystemInterface` API documentation](http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7)**:
+:    [api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7](http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7)
+
+**[Creating HTML formatted mails in Drupal 7](http://drupal.org/node/900794)**:
+:    [drupal.org/node/900794](http://drupal.org/node/900794)
diff --git a/profiles/wcm_base/modules/contrib/mailsystem/README.txt b/profiles/wcm_base/modules/contrib/mailsystem/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ca302afc12654349ffb31b90026929e9368c5e99
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mailsystem/README.txt
@@ -0,0 +1,134 @@
+[1]Mail System
+
+   Provides an Administrative UI and Developers API for safely updating
+   the [2]mail_system configuration variable.
+
+  Administrative UI
+
+   The administrative interface is at admin/config/system/mailsystem. A
+   [3]screenshot is available.
+
+  Used by:
+
+     * [4]HTML Mail
+     * [5]Mime Mail 7.x-1.x-dev
+     * [6]Postmark 7.x-1.x
+
+  Developers API
+
+   A module example with a [7]MailSystemInterface implementation called
+   ExampleMailSystem should add the following in its example.install file:
+/**
+ * Implements hook_enable().
+ */
+function example_enable() {
+  mailsystem_set(array('example' => 'ExampleMailSystem'));
+}
+/**
+ * Implements hook_disable().
+ */
+function example_disable() {
+  mailsystem_clear(array('example' => 'ExampleMailSystem'));
+}
+
+
+   The above settings allow mail sent by example to use ExampleMailSystem.
+   To make ExampleMailSystem the site-wide default for sending mail:
+mailsystem_set(array(mailsystem_default_id() => 'ExampleMailSystem'));
+
+
+   To restore the default mail system:
+mailsystem_set(array(mailsystem_default_id() => mailsystem_default_value()));
+
+
+   Or simply:
+mailsystem_set(mailsystem_defaults());
+
+
+   If module example relies on dependency foo and its FooMailSystem class,
+   then the example.install code should like like this:
+/**
+ * Implements hook_enable().
+ */
+function example_enable() {
+  mailsystem_set(array('example' => 'FooMailSystem'));
+}
+/**
+ * Implements hook_disable().
+ */
+function example_disable() {
+  mailsystem_clear(array('example' => ''));
+}
+
+
+   If module example only wants to use FooMailSystem when sending emails
+   with a key of examail, then the example.install code should look like
+   this:
+/**
+ * Implements hook_enable().
+ */
+function example_enable() {
+  mailsystem_set(array('example_examail' => 'FooMailSystem'));
+}
+/**
+ * Implements hook_disable().
+ */
+function example_disable() {
+  mailsystem_clear(array('example_examail' => ''));
+}
+
+
+    (New in 2.x branch)
+
+   To change the site-wide defaults to use the FooMailSystem for
+   formatting messages and the BarMailSystem for sending them:
+mailsystem_set(
+  array(
+    mailsystem_default_id() => array(
+      'format' => 'FooMailSystem',
+      'mail' => 'BarMailSystem',
+    ),
+  )
+);
+
+
+   To change the site-wide defaults to use the FooMailSystem for sending
+   messages, while continuing to use the current system for formatting
+   them:
+mailsystem_set(
+  array(
+    mailsystem_default_id() => array(
+      'mail' => 'FooMailsystem',
+    ),
+  )
+);
+
+
+  References
+
+   [8]drupal_mail_system() API documentation:
+          [9]api.drupal.org/api/drupal/includes--mail.inc/function/drupal_
+          mail_system/7
+
+   [10]MailSystemInterface API documentation:
+          [11]api.drupal.org/api/drupal/includes--mail.inc/interface/MailS
+          ystemInterface/7
+
+   [12]Creating HTML formatted mails in Drupal 7:
+          [13]drupal.org/node/900794
+
+References
+
+   1. http://drupal.org/project/mailsystem
+   2. http://api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7
+   3. http://drupal.org/node/1134044
+   4. http://drupal.org/project/htmlmail
+   5. http://drupal.org/project/mimemail
+   6. http://drupal.org/project/postmark
+   7. http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7
+   8. http://api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7
+   9. http://api.drupal.org/api/drupal/includes--mail.inc/function/drupal_mail_system/7
+  10. http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7
+  11. http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7
+  12. http://drupal.org/node/900794
+  13. http://drupal.org/node/900794
diff --git a/profiles/wcm_base/modules/contrib/mailsystem/html_to_text.inc b/profiles/wcm_base/modules/contrib/mailsystem/html_to_text.inc
new file mode 100644
index 0000000000000000000000000000000000000000..08576220ccc53d403eddca676aa9c2cda9b881b0
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mailsystem/html_to_text.inc
@@ -0,0 +1,742 @@
+<?php
+/**
+ * @file
+ * Copy of drupal_html_to_text improvements from issue #299138.
+ */
+
+/**
+ * Perform format=flowed soft wrapping for mail (RFC 3676).
+ *
+ * We use delsp=yes wrapping, but only break non-spaced languages when
+ * absolutely necessary to avoid compatibility issues.
+ *
+ * We deliberately use variable_get('mail_line_endings', MAIL_LINE_ENDINGS)
+ * rather than "\r\n".
+ *
+ * @param $text
+ *   The plain text to process.
+ * @param array $options
+ *   (optional) An array containing one or more of the following keys:
+ *   - indent: A string to indent the text with. Only '>' characters are
+ *     repeated on subsequent wrapped lines. Others are replaced by spaces.
+ *   - max: The maximum length at which to wrap each line. Defaults to 80.
+ *   - stuff: Whether to space-stuff special lines.  Defaults to TRUE.
+ *   - hard: Whether to enforce the maximum line length even if no convenient
+ *     space character is available.  Defaults to FALSE.
+ *   - pad: A string to use for padding short lines to 'max' characters.  If
+ *     more than one character, only the last will be repeated.
+ *   - break: The line break sequence to insert.  The default is one of the
+ *     following:
+ *     - "\r\n": Windows, when $text does not contain a space character.
+ *     - "\n": Non-Windows, when $text does not contain a space character.
+ *     - " \r\n": On Windows, when $text contains at least one space.
+ *     - " \n": Non-Windows, when $text contains at least one space.
+ *
+ * @see drupal_mail()
+ */
+function mailsystem_wrap_mail($text, array $options = array()) {
+  static $defaults;
+  if (!isset($defaults)) {
+    $defaults = array(
+      'indent' => '',
+      'pad' => '',
+      'pad_repeat' => '',
+      'max' => 80,
+      'stuff' => TRUE,
+      'hard' => FALSE,
+      'eol' => variable_get('mail_line_endings', MAIL_LINE_ENDINGS),
+    );
+  }
+  $options += $defaults;
+  if (!isset($options['break'])) {
+    // Allow soft-wrap spaces only when $text contains at least one space.
+    $options['break'] = (strpos($text, ' ') === FALSE ? '' : ' ') . $defaults['eol'];
+  }
+  $options['wrap'] = $options['max'] - drupal_strlen($options['indent']);
+  if ($options['pad']) {
+    $options['pad_repeat'] = drupal_substr($options['pad'], -1, 1);
+  }
+  // The 'clean' indent is applied to all lines after the first one.
+  $options['clean'] = _mailsystem_html_to_text_clean($options['indent']);
+  // Wrap lines according to RFC 3676.
+  $lines = explode($defaults['eol'], $text);
+  array_walk($lines, '_mailsystem_wrap_mail_line', $options);
+  // Expand the lines array on newly-inserted line breaks.
+  $lines = explode($defaults['eol'], implode($defaults['eol'], $lines));
+  // Apply indentation, space-stuffing, and padding.
+  array_walk($lines, '_mailsystem_indent_mail_line', $options);
+  return implode($defaults['eol'], $lines);
+}
+
+/**
+ * Transform an HTML string into plain text, preserving the structure of the
+ * markup. Useful for preparing the body of a node to be sent by e-mail.
+ *
+ * The output will be suitable for use as 'format=flowed; delsp=yes' text
+ * (RFC 3676) and can be passed directly to drupal_mail() for sending.
+ *
+ * We deliberately use variable_get('mail_line_endings', MAIL_LINE_ENDINGS)
+ * rather than "\r\n".
+ *
+ * This function provides suitable alternatives for the following tags:
+ *
+ * <a> <address> <b> <blockquote> <br /> <caption> <cite> <dd> <div> <dl> <dt>
+ * <em> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <ol> <p> <pre> <strong>
+ * <table> <tbody> <td> <tfoot> <thead> <tr> <u> <ul>
+ *
+ * The following tag attributes are supported:
+ * - <a href=...>: Hyperlink destination urls.
+ * - <li value=...>: Ordered list item numbers.
+ * - <ol start=...>: Ordered list start number.
+ *
+ * @param $string
+ *   The string to be transformed.
+ * @param $allowed_tags
+ *   (optional) If supplied, a list of tags that will be transformed. If
+ *   omitted, all supported tags are transformed.
+ *
+ * @return
+ *   The transformed string.
+ *
+ * @see drupal_mail()
+ */
+function mailsystem_html_to_text($string, $allowed_tags = NULL) {
+  $eol = variable_get('mail_line_endings', MAIL_LINE_ENDINGS);
+  // Cache list of supported tags.
+  static $supported_tags;
+  if (!isset($supported_tags)) {
+    $supported_tags = array(
+      'a', 'address', 'b', 'blockquote', 'br', 'cite', 'dd', 'div', 'dl',
+      'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'li',
+      'ol', 'p', 'pre', 'strong', 'table', 'td', 'tr', 'u', 'ul',
+    );
+  }
+
+  // Make sure only supported tags are kept.
+  $allowed_tags = isset($allowed_tags) ? array_intersect($supported_tags, $allowed_tags) : $supported_tags;
+
+  // Parse $string into a DOM tree.
+  $dom = filter_dom_load($string);
+  $notes = array();
+  // Recursively convert the DOM tree into plain text.
+  $text = _mailsystem_html_to_text($dom->documentElement, $allowed_tags, $notes);
+  // Hard-wrap at 1000 characters (including the line break sequence)
+  // and space-stuff special lines.
+  $text = mailsystem_wrap_mail($text, array('max' => 1000 - strlen($eol), 'hard' => TRUE));
+  // Change non-breaking spaces back to regular spaces, and trim line breaks.
+  // chr(160) is the non-breaking space character.
+  $text = str_replace(chr(160), ' ', trim($text, $eol));
+  // Add footnotes;
+  if ($notes) {
+    // Add a blank line before the footnote list.
+    $text .= $eol;
+    foreach ($notes as $url => $note) {
+      $text .= $eol . '[' . $note . '] ' . $url;
+    }
+  }
+  return $text;
+}
+
+/**
+ * Helper function for drupal_html_to_text().
+ *
+ * Recursively converts $node to text, wrapping and indenting as necessary.
+ *
+ * @param $node
+ *   The source DOMNode.
+ * @param $allowed_tags
+ *   A list of tags that will be transformed.
+ * @param array &$notes
+ *   A writeable array of footnote reference numbers, keyed by their
+ *   respective hyperlink destination urls.
+ * @param $line_length
+ *   The maximum length of a line, for wrapping.  Defaults to 80 characters.
+ * @param array $parents
+ *   The list of ancestor tags, from nearest to most distant.  Defaults to an
+ *   empty array().
+ * @param $count
+ *   The number to use for the next list item within an ordered list.  Defaults
+ *   to 1.
+ */
+function _mailsystem_html_to_text(DOMNode $node, array $allowed_tags, array &$notes, $line_length = 80, array $parents = array(), &$count = NULL) {
+  if (!isset($count)) {
+    $count = 1;
+  }
+  $eol = variable_get('mail_line_endings', MAIL_LINE_ENDINGS);
+  if ($node->nodeType === XML_TEXT_NODE) {
+    // For text nodes, we just copy the text content.
+    $text = $node->textContent;
+    // Convert line breaks and trim trailing spaces.
+    $text = preg_replace('/ *\r?\n/', $eol, $text);
+    if (in_array('pre', $parents)) {
+      // Within <pre> tags, all spaces become non-breaking.
+      // chr(160) is the non-breaking space character.
+      $text = str_replace(' ', chr(160), $text);
+    }
+    else {
+      // Outside <pre> tags, collapse whitespace.
+      $text = preg_replace('/[[:space:]]+/', ' ', $text);
+    }
+    return $text;
+  }
+  // Non-text node.
+  $tag = '';
+  $text = '';
+  $child_text = '';
+  $child_count = 1;
+  $indent = '';
+  $prefix = '';
+  $suffix = '';
+  $pad = '';
+  if (isset($node->tagName) && in_array($node->tagName, $allowed_tags)) {
+    $tag = $node->tagName;
+    switch ($tag) {
+      // Turn links with valid hrefs into footnotes.
+      case 'a':
+        $test = !empty($node->attributes);
+        $test = $test && ($href = $node->attributes->getNamedItem('href'));
+        $test = $test && ($url = url(preg_replace('|^' . base_path() . '|', '', $href->nodeValue), array('absolute' => TRUE)));
+        $test = $test && valid_url($url);
+        if ($test) {
+          // Only add links that have not already been added.
+          if (isset($notes[$url])) {
+            $note = $notes[$url];
+          }
+          else {
+            $note = count($notes) + 1;
+            $notes[$url] = $note;
+          }
+          $suffix = ' [' . $note . ']';
+        }
+        break;
+
+      // Generic block-level tags.
+      case 'address':
+      case 'caption':
+      case 'div':
+      case 'p':
+      case 'pre':
+        // Start on a new line except as the first child of a list item.
+        if (!isset($parents[0]) || $parents[0] !== 'li' || !$node->isSameNode($node->parentNode->firstChild)) {
+          $text = $eol;
+        }
+        $suffix = $eol;
+        break;
+
+      // Forced line break.
+      case 'br':
+        $text = $eol;
+        break;
+
+      // Boldface by wrapping with "*" characters.
+      case 'b':
+      case 'strong':
+        $prefix = '*';
+        $suffix = '*';
+        break;
+
+      // Italicize by wrapping with "/" characters.
+      case 'cite':
+      case 'em':
+      case 'i':
+        $prefix = '/';
+        $suffix = '/';
+        break;
+
+      // Underline by wrapping with "_" characters.
+      case 'u':
+        $prefix = '_';
+        $suffix = '_';
+        break;
+
+      // Blockquotes are indented by "> " at each level.
+      case 'blockquote':
+        $text = $eol;
+        // chr(160) is the non-breaking space character.
+        $indent = '>' . chr(160);
+        $suffix = $eol;
+        break;
+
+      // Dictionary definitions are indented by four spaces.
+      case 'dd':
+        // chr(160) is the non-breaking space character.
+        $indent = chr(160) . chr(160) . chr(160) . chr(160);
+        $suffix = $eol;
+        break;
+
+      // Dictionary list.
+      case 'dl':
+        // Start on a new line as the first child of a list item.
+        if (!isset($parents[0]) || $parents[0] !== 'li' || !$node->isSameNode($node->parentNode->firstChild)) {
+          $text = $eol;
+        }
+        $suffix = $eol;
+        break;
+
+      // Dictionary term.
+      case 'dt':
+        $suffix = $eol;
+        break;
+
+      // Header level 1 is prefixed by eight "=" characters.
+      case 'h1':
+        $text = "$eol$eol";
+        // chr(160) is the non-breaking space character.
+        $indent = '========' . chr(160);
+        $pad = chr(160) . '=';
+        $suffix = $eol;
+        break;
+
+      // Header level 2 is prefixed by six "-" characters.
+      case 'h2':
+        $text = "$eol$eol";
+        // chr(160) is the non-breaking space character.
+        $indent = '------' . chr(160);
+        $pad = chr(160) . '-';
+        $suffix = $eol;
+        break;
+
+      // Header level 3 is prefixed by four "." characters and a space.
+      case 'h3':
+        $text = "$eol$eol";
+        // chr(160) is the non-breaking space character.
+        $indent = '....' . chr(160);
+        $suffix = $eol;
+        break;
+
+      // Header level 4 is prefixed by three "." characters and a space.
+      case 'h4':
+        $text = "$eol$eol";
+        // chr(160) is the non-breaking space character.
+        $indent = '...' . chr(160);
+        $suffix = $eol;
+        break;
+
+      // Header level 5 is prefixed by two "." character and a space.
+      case 'h5':
+        $text = "$eol$eol";
+        // chr(160) is the non-breaking space character.
+        $indent = '..' . chr(160);
+        $suffix = $eol;
+        break;
+
+      // Header level 6 is prefixed by one "." character and a space.
+      case 'h6':
+        $text = "$eol$eol";
+        // chr(160) is the non-breaking space character.
+        $indent = '.' . chr(160);
+        $suffix = $eol;
+        break;
+
+      // Horizontal rulers become a line of "-" characters.
+      case 'hr':
+        $text = $eol;
+        $child_text = '-';
+        $pad = '-';
+        $suffix = $eol;
+        break;
+
+      // List items are treated differently depending on the parent tag.
+      case 'li':
+        // Ordered list item.
+        if (reset($parents) === 'ol') {
+          // Check the value attribute.
+          $test = !empty($node->attributes);
+          $test = $test && ($value = $node->attributes->getNamedItem('value'));
+          if ($test) {
+            $count = $value->nodeValue;
+          }
+          // chr(160) is the non-breaking space character.
+          $indent = ($count < 10 ? chr(160) : '') . chr(160) . "$count)" . chr(160);
+          $count++;
+        }
+        // Unordered list item.
+        else {
+          // chr(160) is the non-breaking space character.
+          $indent = chr(160) . '*' . chr(160);
+        }
+        $suffix = $eol;
+        break;
+
+      // Ordered lists.
+      case 'ol':
+        // Start on a new line as the first child of a list item.
+        if (!isset($parents[0]) || $parents[0] !== 'li' || !$node->isSameNode($node->parentNode->firstChild)) {
+          $text = $eol;
+        }
+        // Check the start attribute.
+        $test = !empty($node->attributes);
+        $test = $test && ($value = $node->attributes->getNamedItem('start'));
+        if ($test) {
+          $child_count = $value->nodeValue;
+        }
+        break;
+
+      // Tables require special handling.
+      case 'table':
+        return _mailsystem_html_to_text_table($node, $allowed_tags, $notes, $line_length);
+
+      // Separate adjacent table cells by two non-breaking spaces.
+      case 'td':
+        if (!empty($node->nextSibling)) {
+          // chr(160) is the non-breaking space character.
+          $suffix = chr(160) . chr(160);
+        }
+        break;
+
+      // End each table row with a newline.
+      case 'tr':
+        $suffix = $eol;
+        break;
+
+      // Unordered lists.
+      case 'ul':
+        // Start on a new line as the first child of a list item.
+        if (!isset($parents[0]) || $parents[0] !== 'li' || !$node->isSameNode($node->parentNode->firstChild)) {
+          $text = $eol;
+        }
+        break;
+
+      default:
+        // Coder review complains if there is no default case.
+        break;
+    }
+    // Only add allowed tags to the $parents array.
+    array_unshift($parents, $tag);
+  }
+  // Copy each child node to output.
+  if ($node->hasChildNodes()) {
+    foreach ($node->childNodes as $child) {
+      $child_text .= _mailsystem_html_to_text($child, $allowed_tags, $notes, $line_length - drupal_strlen($indent), $parents, $child_count);    }
+  }
+  // We only add prefix and suffix if the child nodes were non-empty.
+  if ($child_text > '') {
+    // We capitalize the contents of h1 and h2 tags.
+    if ($tag === 'h1' || $tag === 'h2') {
+      $child_text = drupal_strtoupper($child_text);
+    }
+    // Don't add a newline to an existing newline.
+    if ($suffix === $eol && drupal_substr($child_text, - drupal_strlen($eol)) === $eol) {
+      $suffix = '';
+    }
+    // Trim spaces around newlines except with <pre> or inline tags.
+    if (!in_array($tag, array('a', 'b', 'cite', 'em', 'i', 'pre', 'strong', 'u'))) {
+      $child_text = preg_replace('/ *' . $eol . ' */', $eol, $child_text);
+    }
+    // Soft-wrap at effective line length, but don't space-stuff.
+    $child_text = mailsystem_wrap_mail(
+      $prefix . $child_text,
+      array(
+        // chr(160) is the non-breaking space character.
+        'break' => chr(160) . $eol,
+        'indent' => $indent,
+        'max' => $line_length,
+        'pad' => $pad,
+        'stuff' => FALSE,
+      )
+    ) . $suffix;
+    if ($tag === 'pre') {
+      // Perform RFC-3676 soft-wrapping.
+      // chr(160) is the non-breaking space character.
+      $child_text = str_replace(chr(160), ' ', $child_text);
+      $child_text = mailsystem_wrap_mail(
+        $child_text,
+        array('max' => $line_length, 'stuff' => FALSE)
+      );
+      // chr(160) is the non-breaking space character.
+      $child_text = str_replace(' ', chr(160), $child_text);
+    }
+    $text .= $child_text;
+  }
+  return $text;
+}
+
+/**
+ * Helper function for _mailsystem_html_to_text().
+ *
+ * Renders a <table> DOM Node into plain text.  Attributes such as rowspan,
+ * colspan, padding, border, etc. are ignored.
+ *
+ * @param DOMNode $node
+ *   The DOMNode corresponding to the <table> tag and its contents.
+ * @param $allowed_tags
+ *   The list of allowed tags passed to _mailsystem_html_to_text().
+ * @param array &$notes
+ *   A writeable array of footnote reference numbers, keyed by their
+ *   respective hyperlink destination urls.
+ * @param $table_width
+ *   The desired maximum table width, after word-wrapping each table cell.
+ *
+ * @return
+ *   A plain text representation of the table.
+ *
+ * @see _mailsystem_html_to_text()
+ */
+function _mailsystem_html_to_text_table(DOMNode $node, $allowed_tags = NULL, array &$notes = array(), $table_width = 80) {
+  $eol = variable_get('mail_line_endings', MAIL_LINE_ENDINGS);
+  $header = array();
+  $footer = array();
+  $body = array();
+  $text = $eol;
+  $current = $node;
+  while (TRUE) {
+    if (isset($current->tagName)) {
+      switch ($current->tagName) {
+        case 'caption':  // The table caption is added first.
+          $text = _mailsystem_html_to_text($current, $allowed_tags, $notes, $table_width);
+          break;
+
+        case 'tr':
+          switch ($current->parentNode->tagName) {
+            case 'thead':
+              $header[] = $current;
+              break;
+
+            case 'tfoot':
+              $footer[] = $current;
+              break;
+
+            default: // Either 'tbody' or 'table'
+              $body[] = $current;
+              break;
+          }
+          break;
+
+        default:
+          if ($current->hasChildNodes()) {
+            $current = $current->firstChild;
+            continue 2;
+          }
+      }
+    }
+    do {
+      if ($current->nextSibling) {
+        $current = $current->nextSibling;
+        continue 2;
+      }
+      $current = $current->parentNode;
+    } while ($current && !$current->isSameNode($node));
+    break;
+  }
+  // Merge the thead, tbody, and tfoot sections together.
+  if ($rows = array_merge($header, $body, $footer)) {
+    $num_rows = count($rows);
+    // First just count the number of columns.
+    $num_cols = 0;
+    foreach ($rows as $row) {
+      $row_cols = 0;
+      foreach ($row->childNodes as $cell) {
+        if (isset($cell->tagName) && in_array($cell->tagName, array('td', 'th'))) {
+          $row_cols++;
+        }
+      }
+      $num_cols = max($num_cols, $row_cols);
+    }
+    // If any columns were found, calculate each column height and width.
+    if ($num_cols) {
+      // Set up a binary search for best wrap width for each column.
+      $max = max($table_width - $num_cols - 1, 1);
+      $max_wraps = array_fill(0, $num_cols, $max);
+      $try = max(intval(($table_width - 1) / $num_cols - 1), 1);
+      $try_wraps = array_fill(0, $num_cols, $try);
+      $min_wraps = array_fill(0, $num_cols, 1);
+      // Start searching...
+      $change = FALSE;
+      do {
+        $change = FALSE;
+        $widths = array_fill(0, $num_cols, 0);
+        $heights = array_fill(0, $num_rows, 0);
+        $table = array_fill(0, $num_rows, array_fill(0, $num_cols, ''));
+        $breaks = array_fill(0, $num_cols, FALSE);
+        foreach ($rows as $i => $row) {
+          $j = 0;
+          foreach ($row->childNodes as $cell) {
+            if (!isset($cell->tagName) || !in_array($cell->tagName, array('td', 'th'))) {
+              // Skip text nodes.
+              continue;
+            }
+            // Render the cell contents.
+            $cell = _mailsystem_html_to_text($cell, $allowed_tags, $notes, $try_wraps[$j]);
+            // Trim leading line-breaks and trailing whitespace.
+            // chr(160) is the non-breaking space character.
+            $cell = rtrim(ltrim($cell, $eol), ' ' . $eol . chr(160));
+            $table[$i][$j] = $cell;
+            if ($cell > '') {
+              // Split the cell into lines.
+              $lines = explode($eol, $cell);
+              // The row height is the maximum number of lines among all the
+              // cells in that row.
+              $heights[$i] = max($heights[$i], count($lines));
+              foreach ($lines as $line) {
+                $this_width = drupal_strlen($line);
+                // The column width is the maximum line width among all the
+                // lines in that column.
+                if ($this_width > $widths[$j]) {
+                  $widths[$j] = $this_width;
+                  // If the longest line in a column contains at least one
+                  // space character, then the table can be made narrower.
+                  $breaks[$j] = strpos(' ', $line) !== FALSE;
+                }
+              }
+            }
+            $j++;
+          }
+        }
+        // Calculate the total table width;
+        $this_width = array_sum($widths) + $num_cols + 1;
+        if ($this_width > $table_width) {
+          // Wider than desired.
+          if (!in_array(TRUE, $breaks)) {
+            // If there are no more break points, then the table is already as
+            // narrow as it can get, so we're done.
+            break;
+          }
+          foreach ($try_wraps as $i => $wrap) {
+            $max_wraps[$i] = min($max_wraps[$i], $wrap);
+            if ($breaks[$i]) {
+              $new_wrap = intval(($min_wraps[$i] + $max_wraps[$i]) / 2);
+              $new_wrap = min($new_wrap, $widths[$i] - 1);
+              $new_wrap = max($new_wrap, $min_wraps[$i]);
+            }
+            else {
+              // There's no point in trying to make the column narrower than
+              // the widest un-wrappable line in the column.
+              $min_wraps[$i] = $widths[$i];
+              $new_wrap = $widths[$i];
+            }
+            if ($try_wraps[$i] > $new_wrap) {
+              $try_wraps[$i] = $new_wrap;
+              $change = TRUE;
+            }
+          }
+        }
+        elseif ($this_width < $table_width) {
+          // Narrower than desired.
+          foreach ($try_wraps as $i => $wrap) {
+            if ($min_wraps[$i] < $wrap) {
+              $min_wraps[$i] = $wrap;
+            }
+            $new_wrap = intval(($min_wraps[$i] + $max_wraps[$i]) / 2);
+            $new_wrap = max($new_wrap, $widths[$i] + 1);
+            $new_wrap = min($new_wrap, $max_wraps[$i]);
+            if ($try_wraps[$i] < $new_wrap) {
+              $try_wraps[$i] = $new_wrap;
+              $change = TRUE;
+            }
+          }
+        }
+      } while ($change);
+      // Pad each cell to column width and line height.
+      for ($i = 0; $i < $num_rows; $i++) {
+        if ($heights[$i]) {
+          for ($j = 0; $j < $num_cols; $j++) {
+            $cell = $table[$i][$j];
+            // Pad each cell to the maximum number of lines in that row.
+            $lines = array_pad(explode($eol, $cell), $heights[$i], '');
+            foreach ($lines as $k => $line) {
+              // Pad each line to the maximum width in that column.
+              $repeat = $widths[$j] - drupal_strlen($line);
+              if ($repeat > 0) {
+                // chr(160) is the non-breaking space character.
+                $lines[$k] .= str_repeat(chr(160), $repeat);
+              }
+            }
+            $table[$i][$j] = $lines;
+          }
+        }
+      }
+      // Generate the row separator line.
+      $separator = '+';
+      for($i = 0; $i < $num_cols; $i++) {
+        $separator .= str_repeat('-', $widths[$i]) . '+';
+      }
+      $separator .= $eol;
+      for ($i = 0; $i < $num_rows; $i++) {
+        $text .= $separator;
+        if (!$heights[$i]) {
+          continue;
+        }
+        $row = $table[$i];
+        // For each row, iterate first by lines within the row.
+        for ($k = 0; $k < $heights[$i]; $k++) {
+          // Add a vertical-bar at the beginning of each row line.
+          $row_line = '|';
+          $trimmed = '';
+          // Within each row line, iterate by cells within that line.
+          for ($j = 0; $j < $num_cols; $j++) {
+            // Add a vertical bar at the end of each cell line.
+            $row_line .= $row[$j][$k] . '|';
+            // chr(160) is the non-breaking space character.
+            $trimmed .= trim($row[$j][$k], ' ' . $eol . chr(160));
+          }
+          if ($trimmed > '') {
+            // Only print rows that are non-empty.
+            $text .= $row_line . $eol;
+          }
+        }
+      }
+      // Final output ends with a row separator.
+      $text .= $separator;
+    }
+  }
+  // Make sure formatted table content doesn't line-wrap.
+  // chr(160) is the non-breaking space character.
+  return str_replace(' ', chr(160), $text);
+}
+
+/**
+ * Helper function for array_walk in drupal_wrap_mail().
+ *
+ * Inserts $values['break'] sequences to break up $line into parts of no more
+ * than $values['wrap'] characters. Only breaks at space characters, unless
+ * $values['hard'] is TRUE.
+ */
+function _mailsystem_wrap_mail_line(&$line, $key, $values) {
+  $line = wordwrap($line, $values['wrap'], $values['break'], $values['hard']);
+}
+
+/**
+ * Helper function for array_walk in drupal_wrap_mail().
+ *
+ * If $values['pad'] is non-empty, $values['indent'] will be added at the start
+ * of each line, and $values['pad'] at the end, repeating the last character of
+ * $values['pad'] until the line length equals $values['max'].
+ *
+ * If $values['pad'] is empty, $values['indent'] will be added at the start of
+ * the first line, and $values['clean'] at the start of subsequent lines.
+ *
+ * If $values['stuff'] is true, then an extra space character will be added at
+ * the start of any line beginning with a space, a '>', or the word 'From'.
+ *
+ * @see http://www.ietf.org/rfc/rfc3676.txt
+ */
+function _mailsystem_indent_mail_line(&$line, $key, $values) {
+  if ($line == '') {
+    return;
+  }
+  if ($values['pad']) {
+    $line = $values['indent'] . $line;
+    $count = $values['max'] - drupal_strlen($line) - drupal_strlen($values['pad']);
+    if ($count >= 0) {
+      $line .= $values['pad'] . str_repeat($values['pad_repeat'], $count);
+    }
+  }
+  else {
+    $line = $values[$key === 0 ? 'indent' : 'clean'] . $line;
+  }
+  if ($values['stuff']) {
+    // chr(160) is the non-breaking space character.
+    $line = preg_replace('/^(' . chr(160) . '| |>|From)/', ' $1', $line);
+  }
+}
+
+/**
+ * Helper function for drupal_wrap_mail() and drupal_html_to_text().
+ *
+ * Replace all non-quotation markers from a given piece of indentation with
+ * non-breaking space characters.
+ */
+function _mailsystem_html_to_text_clean($indent) {
+  // chr(160) is the non-breaking space character.
+  return preg_replace('/[^>]/', chr(160), $indent);
+}
diff --git a/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.admin.inc b/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.admin.inc
new file mode 100644
index 0000000000000000000000000000000000000000..2dca212cae652377ae58fb2f348cfdf634cc4c57
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.admin.inc
@@ -0,0 +1,202 @@
+<?php
+
+/**
+ * @file
+ * Administrative form for setting the mail_system variable.
+ */
+function mailsystem_admin_settings() {
+  $args = array(
+    '!interface' => url('http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7'),
+    '@interface' => 'MailSystemInterface',
+    '!format' => url('http://api.drupal.org/api/drupal/includes--mail.inc/function/MailSystemInterface%3A%3Aformat/7'),
+    '@format' => 'format()',
+    '!mail' => url('http://api.drupal.org/api/drupal/includes--mail.inc/function/MailSystemInterface%3A%3Amail/7'),
+    '@mail' => 'mail()',
+    '!default_class' => url('http://api.drupal.org/api/drupal/modules--system--system.mail.inc/class/DefaultMailSystem/7'),
+    '@default_class' => mailsystem_default_value(),
+    '%module' => 'module',
+    '%key' => 'key',
+  );
+  $form = array('#submit' => array('mailsystem_admin_settings_submit'));
+  $mail_system = mailsystem_get();
+  $mail_defaults = mailsystem_defaults();
+  $mailsystem_classes = mailsystem_get_classes();
+  $descriptions = array();
+  foreach (system_rebuild_module_data() as $item) {
+    if ($item->status) {
+      $descriptions[$item->name] = (
+        empty($item->info['package'])
+        ? '' : $item->info['package']
+      ) . ' » ' . t('!module module', array('!module' => $item->info['name']));
+    }
+  }
+  asort($descriptions);
+  $form['mailsystem'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Mail System Settings'),
+    '#description' => t(
+      'Drupal provides a default <a href="!interface"><code>@interface</code></a> class called <a href="!default_class"><code>@default_class</code></a>. Modules may provide additional classes. Each <a href="!interface"><code>@interface</code></a> class may be associated with one or more identifiers, composed of a %module and an optional %key. Each email being sent also has a %module and a %key. To decide which class to use, Drupal uses the following search order: <ol><li>The class associated with the %module and %key, if any.</li><li>The class associated with the %module, if any.</li><li>The site-wide default <a href="!interface"><code>@interface</code></a> class.</li></ol>', $args
+    ),
+    '#collapsible' => FALSE,
+    '#tree' => TRUE,
+  );
+  $form['mailsystem'][mailsystem_default_id()] = array(
+    '#type' => 'select',
+    '#title' => t(
+      'Site-wide default <a href="!interface"><code>@interface</code></a> class', $args
+    ),
+    '#options' => $mailsystem_classes,
+    '#default_value' => $mail_system[mailsystem_default_id()],
+  );
+  $mailsystem_classes = array(
+    mailsystem_default_id() => t('Remove this setting.')
+  ) + $mailsystem_classes;
+  foreach (array_diff_key($mail_system, $mail_defaults) as $id => $class) {
+    // Separate $id into $module and $key.
+    $module = $id;
+    while ($module && empty($descriptions[$module])) {
+      // Remove a key from the end
+      $module = implode('_', explode('_', $module, -1));
+    }
+    // If an array key of the $mail_system variable is neither "default-system"
+    // nor begins with a module name, then it should be unset.
+    if (empty($module)) {
+      watchdog('mailsystem', "Removing bogus mail_system key %id.", array('%id' => $id), WATCHDOG_WARNING);
+      unset($mail_system[$id]);
+      continue;
+    }
+    // Set $title to the human-readable module name.
+    $title = preg_replace('/^.* » /', '', $descriptions[$module]);
+    if ($key = substr($id, strlen($module) + 1)) {
+      $title .= " ($key key)";
+    }
+    $title .= ' class';
+    $form['mailsystem'][$id] = array(
+      '#type' => 'select',
+      '#title' => $title,
+      '#options' => $mailsystem_classes,
+      '#default_value' => $class,
+    );
+  }
+  // Generate a list of themes which may used to render emails.
+  $theme_options = array('current' => t('Current'), 'default' => t('Default'));
+  if (module_exists('domain_theme')) {
+    $theme_options['domain'] = t('Domain Theme');
+  }
+  // Get a list of all themes.
+  $themes = list_themes();
+  foreach ($themes as $name => $theme) {
+    if ($theme->status == 1) {
+      $theme_options[$name] = $theme->info['name'];
+    }
+  }
+  $form['mailsystem']['mailsystem_theme'] = array(
+      '#type' => 'select',
+      '#title' => t('Theme to render the emails'),
+      '#description' => t('Select the theme that will be used to render the emails. This can be either the current theme, the default theme, the domain theme or any active theme.'),
+      '#options' => $theme_options,
+      '#default_value' => variable_get('mailsystem_theme', 'current'),
+  );
+  $form['class'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('New Class'),
+    '#description' => t(
+      'Create a new <a href="!interface"><code>@interface</code></a> that inherits its methods from other classes. The new class will be named after the other classes it uses.', $args
+    ),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#tree' => TRUE,
+  );
+  $mailsystem_classes[mailsystem_default_id()] = '--Select--';
+  $form['class']['format'] = array(
+    '#type' => 'select',
+    '#title' => t(
+      'Class to use for the <a href="!format"><code>@format</code></a> method', $args
+    ),
+    '#options' => $mailsystem_classes,
+  );
+  $form['class']['mail'] = array(
+    '#type' => 'select',
+    '#title' => t(
+      'Class to use for the <a href="!mail"><code>@mail</code></a> method', $args
+    ),
+    '#options' => $mailsystem_classes,
+  );
+  $form['identifier'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('New Setting'),
+    '#description' => t('Add a new %module and %key to the settings list.',
+      array(
+        '%module' => 'module',
+        '%key' => 'key',
+      )
+    ),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#tree' => TRUE,
+  );
+  array_unshift($descriptions, t('-- Select --'));
+  $form['identifier']['module'] = array(
+    '#type' => 'select',
+    '#title' => t('Module'),
+    '#options' => $descriptions,
+  );
+  $form['identifier']['key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Key'),
+    '#size' => 80,
+  );
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save settings'),
+  );
+  return $form;
+}
+
+/**
+ * Processes mailsystem_admin_settings form.
+ */
+function mailsystem_admin_settings_submit($form, &$form_state) {
+  variable_set('mailsystem_theme', $form_state['values']['mailsystem']['mailsystem_theme']);
+  // Rebuild the theme registry to make changes needed by theme rendering.
+  drupal_theme_rebuild();
+  unset($form_state['values']['mailsystem']['mailsystem_theme']);
+
+  $default_id = mailsystem_default_id();
+  $mail_system = array(
+    $default_id => (
+      empty($form_state['values'][$default_id])
+      ? mailsystem_default_value()
+      : $form_state['values'][$default_id]
+    )
+  );
+  foreach (element_children($form_state['values']['mailsystem']) as $module) {
+    $class = $form_state['values']['mailsystem'][$module];
+    if (!empty($class) && $class != $default_id) {
+      $mail_system[$module] = $class;
+    }
+  }
+  unset($form_state['values']['mailsystem']);
+  if ($form_state['values']['class']['format'] === mailsystem_default_id()) {
+    unset($form_state['values']['class']['format']);
+  }
+  if ($form_state['values']['class']['mail'] === mailsystem_default_id()) {
+    unset($form_state['values']['class']['mail']);
+  }
+  if ($form_state['values']['class']) {
+    $new_class = mailsystem_create_class($form_state['values']['class']);
+  }
+  else {
+    $new_class = $mail_system[mailsystem_default_id()];
+  }
+  unset($form_state['values']['class']);
+  if ($id = $form_state['values']['identifier']['module']) {
+    if (!empty($form_state['values']['identifier']['key'])) {
+      $id .= '_' . $form_state['values']['identifier']['key'];
+    }
+    $mail_system[$id] = $new_class;
+  }
+  unset($form_state['values']['identifier']);
+  variable_set('mail_system', $mail_system);
+  drupal_set_message(t('The configuration options have been saved.'));
+}
diff --git a/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.info b/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.info
new file mode 100644
index 0000000000000000000000000000000000000000..7d4956fe13f650c3cb70922745af3d106a563db6
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.info
@@ -0,0 +1,14 @@
+package = Mail
+name = Mail System
+description = Provides a user interface for per-module and site-wide mail_system selection.
+php = 5.0
+core = 7.x
+configure = admin/config/system/mailsystem
+dependencies[] = filter
+
+; Information added by drupal.org packaging script on 2012-04-10
+version = "7.x-2.34"
+core = "7.x"
+project = "mailsystem"
+datestamp = "1334082653"
+
diff --git a/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.module b/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.module
new file mode 100644
index 0000000000000000000000000000000000000000..e414280b252f540186c9445dea2e48938d0a057c
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.module
@@ -0,0 +1,353 @@
+<?php
+
+/**
+ * @file
+ * Provide UI for controlling the mail_system variable.
+ */
+
+/**
+ * Implements hook_init().
+ *
+ * Caches the list of MailSystemInterface classes, and removes classes
+ * from the mail_system variable which are no longer available.
+ *
+ * @see mailsystem_get_classes()
+ */
+function mailsystem_init() {
+  mailsystem_get_classes();
+  // @todo Remove this when issue #299138 gets resolved.
+  if (!function_exists('mailsystem_html_to_text')) {
+    module_load_include('inc', 'mailsystem', 'html_to_text');
+  }
+}
+
+/**
+ * Implements hook_permission().
+ *
+ * Defines a permission for managing the mail_system variable.
+ */
+function mailsystem_permission() {
+  return array(
+    'administer mailsystem' => array(
+      'title' => t('Administer Mail System'),
+      'description' => t(
+        'Select the default, per-module, and per-mailing <a href="!interface"><code>@interface</code></a> to use for formatting and sending email messages.',
+        array(
+          '!interface' => url('http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7'),
+          '@interface' => 'MailSystemInterface',
+        )
+      ),
+    ),
+  );
+}
+
+/**
+ * Implements hook_menu().
+ */
+function mailsystem_menu() {
+  $items['admin/config/system/mailsystem'] = array(
+    'title' => 'Mail System',
+    'description' => 'Configure per-module Mail System settings.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('mailsystem_admin_settings'),
+    'access arguments' => array('administer mailsystem'),
+    'file' => 'mailsystem.admin.inc',
+  );
+  return $items;
+}
+
+/**
+ * Returns the id for the default mail_system setting.
+ */
+function mailsystem_default_id() {
+  // @todo: Is there a way to get this from core?
+  return 'default-system';
+}
+
+/**
+ * Returns the value for the default mail_system setting.
+ */
+function mailsystem_default_value() {
+  // @todo: Is there a way to get this from core?
+  return 'DefaultMailSystem';
+}
+
+/**
+ * Returns the default settings for the mail_system variable.
+ */
+function mailsystem_defaults() {
+  return array(mailsystem_default_id() => mailsystem_default_value());
+}
+
+/**
+ * Returns the current mail_system settings.
+ *
+ * @return The contents of the mail_system variable merged with its defaults.
+ */
+function mailsystem_get() {
+  return array_merge(
+    mailsystem_defaults(),
+    variable_get('mail_system', mailsystem_defaults())
+  );
+}
+
+/**
+ * Returns the default list of MailSystemInterface methods.
+ *
+ * @return
+ *   An array whose keys are the names of the methods defined by
+ *   MailSystemInterface and whose values are the default class used to
+ *   provide that method.
+ */
+function mailsystem_default_methods() {
+  $mail_system = mailsystem_get();
+  $default_class = $mail_system[mailsystem_default_id()];
+  $methods = get_class_methods('MailSystemInterface');
+  return array_combine(
+    $methods,
+    array_fill(0, count($methods), $default_class)
+  );
+}
+
+/**
+ * Creates and registers a new MailSystemInterface class.
+ *
+ * The newly-created class gets its name and each of its class methods from the
+ * other classes specified by the $class parameter.
+ *
+ * @param $class An associative array of ($method_name => $class_name) tuples,
+ * where each $method_name is the name of a class method to be created, and
+ * each $class_name is the name of a class to use for that method.
+ *
+ * @return
+ *   The name of the newly-created class if successful; otherwise FALSE.
+ */
+function mailsystem_create_class($classes) {
+  // Merge in defaults.
+  $classes += mailsystem_default_methods();
+  ksort($classes);
+  // Do not create a new class whose methods all derive from the same class.
+  if (count(array_unique($classes)) === 1) {
+    return FALSE;
+  }
+  $class_name = implode('__', $classes);
+  // Ensure that the mailsystem directory exists.
+  $class_dir = file_build_uri('mailsystem');
+  if (!file_prepare_directory($class_dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
+    return FALSE;
+  }
+  // Build the class filename.
+  $class_file = drupal_realpath($class_dir) . DIRECTORY_SEPARATOR . "$class_name.mail.inc";
+  // Strip DRUPAL_ROOT.
+  $drupal_root = drupal_realpath(DRUPAL_ROOT) . DIRECTORY_SEPARATOR;
+  $class_file = preg_replace('#^' . preg_quote($drupal_root, '#') . '#', '', $class_file);
+  // Build the class implementation as a string.
+  $class_contents = '<?php
+class ' . $class_name . ' implements MailSystemInterface {';
+  // Create a protected variable to hold each method class.
+  foreach (array_keys($classes) as $method) {
+    $class_contents .= '
+  protected $' . $method . 'Class;';
+  }
+  // Create a class construction function to populate the variables.
+  $class_contents .= '
+  public function __construct() {';
+  foreach ($classes as $method => $class) {
+    $class_contents .= '
+    if (drupal_autoload_class(\'' . $class . '\')) {
+      $this->' . $method . 'Class = new ' . $class . ';
+    }
+    else {
+      $this->' . $method . 'Class = new ' . mailsystem_default_value() . ';
+    }';
+  }
+  $class_contents .= '
+  }';
+  // Create each class method.
+  foreach (array_keys($classes) as $method) {
+    $class_contents .= '
+  public function ' . $method . '(array $message) {
+    return $this->' . $method . 'Class->' . $method . '($message);
+  }';
+  }
+  $class_contents .= '
+}
+';
+  if (file_unmanaged_save_data($class_contents, $class_file, FILE_EXISTS_REPLACE)) {
+    // Remove any conflicting registry entries to avoid a database error.
+    $class_condition = db_and()
+      ->condition('name', $class_name)
+      ->condition('type', 'class');
+    $file_condition = db_and()
+      ->condition('filename', $class_file);
+    db_delete('registry_file')
+      ->condition($file_condition);
+    db_delete('registry')->condition(
+      db_or()->condition($class_condition)
+      ->condition($file_condition)
+    );
+    // Make sure that registry functions are available.
+    require_once 'includes/registry.inc';
+    // Parse the newly-created class file and add it to the registry.
+    _registry_parse_file($class_file, $class_contents, 'mailsystem');
+    // Clear the mailsystem cache so that it will pick up the new class.
+    drupal_static_reset('mailsystem_get_classes');
+    drupal_set_message(
+      t('Class <code>%class</code> written to <code>%file</code>.',
+        array('%class' => $class_name, '%file' => $class_file)
+      )
+    );
+  }
+  return $class_name;
+}
+
+/**
+ * Helps other modules safely set their own key within mail_system.  This
+ * function should be called from hook_enable() implementations.
+ *
+ * @param $setting  An associative array ($id => $value) where:
+ *   - $id is the machine-readable module name optionally followed by '_'
+ *     and a key.
+ *   - $value is one of
+ *     - (string) The name of a class that implements MailSystemInterface.
+ *     - (array) An associative array whose keys are the names of methods
+ *       defined by MailSystemInterface and whose values are the names of
+ *       the class to use for that method.
+ *
+ * @see drupal_mail(), mailsystem_default_methods()
+ */
+function mailsystem_set(array $setting) {
+  $mail_system = mailsystem_get();
+  foreach ($setting as $key => $class) {
+    if (is_array($class)) {
+      unset($setting[$key]);
+      if ($new_class = mailsystem_create_class($class)) {
+        $setting[$key] = $new_class;
+      }
+    }
+  }
+  variable_set('mail_system', array_merge(mailsystem_get(), $setting));
+}
+
+/**
+ * Helps other modules safely remove their settings from mail_system.  This
+ * function should be called from the other module's hook_disable() function.
+ *
+ * @param $setting  An associative array ($module => $classname) describing
+ * a module and associated MailSystemInterface class that are being disabled.
+ *   - $module is the machine-readable module name.
+ *   - $classname is a class that implements MailSystemInterface.
+ *
+ * If $classname is empty, only the $module entry is removed.
+ *
+ * @param $class
+ *   The name of the class to be removed, if any.
+ */
+function mailsystem_clear(array $setting) {
+  variable_set(
+    'mail_system',
+    array_merge(
+      mailsystem_defaults(),
+      array_diff_key(array_diff(mailsystem_get(), $setting), $setting)
+    )
+  );
+}
+
+/**
+ * Returns a list of classes which implement MailSystemInterface.
+ */
+function &mailsystem_get_classes() {
+  $mailsystem_classes = &drupal_static(__FUNCTION__);
+  if (!isset($mailsystem_classes)) {
+    $mailsystem_classes = array();
+    // @todo Is there a better way to find all mail-related classes?
+    $declared_classes = get_declared_classes();
+    $all_classes = array_combine(
+      $declared_classes,
+      array_fill(0, count($declared_classes), 0)
+    );
+    $mail_classes = db_select('registry', 'registry')
+      ->distinct()
+      ->fields('registry', array('name', 'filename'))
+      ->where("type=:type AND ( filename like :filename OR name like :name )",
+        // Making the HUGE assumption that all classes which implement
+        // MailSystemInterface have filenames containing '.mail.' or
+        // classnames ending in 'MailSystem'.
+        array(
+          ':type' => 'class',
+          ':name' => '%MailSystem',
+          ':filename' => '%.mail.%',
+        )
+      )
+      ->execute()
+      ->fetchAllKeyed();
+    foreach ($mail_classes as $classname => $classfile) {
+      if ( file_exists($classfile)
+        && drupal_autoload_class($classname)
+      ) {
+        $all_classes[$classname] = 1;
+      }
+    }
+    foreach ($all_classes as $classname => $autoload) {
+      if ( ($autoload || preg_match('/MailSystem/', $classname))
+        && ($object = new $classname)
+        && ($object instanceof MailSystemInterface)
+      ) {
+        $mailsystem_classes[$classname] = $classname;
+      }
+      elseif ($autoload) {
+        // Clear classes that are no longer available.
+        db_delete('registry')
+          ->condition('name', $classname)
+          ->execute();
+      }
+    }
+    foreach (array_unique(mailsystem_get()) as $classname) {
+      if (class_exists($classname)) {
+        $mailsystem_classes[$classname] = $classname;
+      }
+      else {
+        mailsystem_clear(array(mailsystem_default_id() => $classname));
+      }
+    }
+    ksort($mailsystem_classes);
+  }
+  return $mailsystem_classes;
+}
+
+/**
+* Implements hook_theme_registry_alter().
+*/
+function mailsystem_theme_registry_alter(&$theme_registry) {
+  module_load_include('inc', 'mailsystem', 'mailsystem.theme');
+  return mailsystem_theme_theme_registry_alter($theme_registry);
+}
+
+/**
+* Retrieves the key of the theme used to render the emails.
+*
+* @todo Add some kind of hook to let other modules alter this behavior.
+*/
+function mailsystem_get_mail_theme() {
+  global $theme_key;
+  $theme = variable_get('mailsystem_theme', 'current');
+  switch ($theme) {
+    case 'default':
+      $theme = variable_get('theme_default', NULL);
+      break;
+    case 'current':
+      $theme = $theme_key;
+      break;
+    case 'domain':
+      // Fetch the theme for the current domain.
+      if (module_exists('domain_theme')) {
+        // Assign the selected theme, based on the active domain.
+        global $_domain;
+        $domain_theme = domain_theme_lookup($_domain['domain_id']);
+        // The above returns -1 on failure.
+        $theme = ($domain_theme != -1) ? $domain_theme['theme'] : $theme_key;
+      }
+      break;
+  }
+  return $theme;
+}
diff --git a/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.theme.inc b/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.theme.inc
new file mode 100644
index 0000000000000000000000000000000000000000..8a22b912949edd3e7a25112cf49da9a7b5aed443
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mailsystem/mailsystem.theme.inc
@@ -0,0 +1,82 @@
+<?php
+
+/**
+* @file
+* The theme system, which controls the output of email messages.
+*/
+
+/**
+* Implements hook_theme_registry_alter().
+*/
+function mailsystem_theme_theme_registry_alter(&$theme_registry) {
+  global $theme_key;
+  static $recursion_prevention = FALSE;
+
+  // Prevent recursive execution.
+  if ($recursion_prevention) {
+    return;
+  }
+  $recursion_prevention = TRUE;
+  $mailsystem_theme = mailsystem_get_mail_theme();
+
+  // Only take action if the mailsystem theme is not the current theme.
+  if ($mailsystem_theme != $theme_key) {
+    $themes = list_themes();
+    // Get the mailsystem theme to be used for rendering emails.
+    if (isset($themes[$mailsystem_theme])) {
+      $theme = clone $themes[$mailsystem_theme];
+      if (isset($theme)) {
+        // Establish variables for further processing.
+        $base_theme = array();
+        if (isset($theme->base_themes)) {
+          foreach (array_keys($theme->base_themes) as $base) {
+            $base_theme[$base] = clone $themes[$base];
+          }
+        }
+        if (isset($theme->base_theme) && !isset($base_theme[$theme->base_theme])) {
+          $base_theme[$theme->base_theme] = clone $themes[$theme->base_theme];
+        }
+        if (isset($theme->engine)) {
+          $theme_engine = $theme->engine;
+        }
+
+        // Include template files to let _theme_load_registry add preprocess
+        // functions.
+        include_once(drupal_get_path('theme', $theme->name) . '/template.php');
+        foreach ($base_theme as $base) {
+          include_once(drupal_get_path('theme', $base->name) . '/template.php');
+        }
+
+        // Get the theme_registry cache.
+        $cache = _theme_load_registry($theme, $base_theme, $theme_engine);
+
+        // Change the registry for hooks with a 'mail theme' element.
+        foreach ($theme_registry as $name => $hook) {
+          if (!empty($hook['mail theme'])) {
+            if (isset($cache[$name])) {
+              $cache[$name]['includes'][] = drupal_get_path('theme', $theme->name) . '/template.php';
+              foreach ($base_theme as $base) {
+                $cache[$name]['includes'][] = drupal_get_path('theme', $base->name) . '/template.php';
+              }
+              // Change the current registry for the new record.
+              $theme_registry[$name] = $cache[$name];
+            }
+
+            // Look for template suggestions.
+            foreach ($cache as $cache_name => $cache_hook) {
+              if (strpos($cache_name, $name . '__') !== FALSE) {
+                $cache_hook['includes'][] = drupal_get_path('theme', $theme->name) . '/template.php';
+                foreach ($base_theme as $base) {
+                  $cache_hook['includes'][] = drupal_get_path('theme', $base->name) . '/template.php';
+                }
+                // Change the current registry for the new record.
+                $theme_registry[$cache_name] = $cache_hook;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  $recursion_prevention = FALSE;
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/CHANGELOG.txt b/profiles/wcm_base/modules/contrib/mimemail/CHANGELOG.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a35cb6e5b88946d2fa810e3c4b75ba6cfbf1a055
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/CHANGELOG.txt
@@ -0,0 +1,214 @@
+Mime Mail 7.x-1.x, xxxx-xx-xx
+-----------------------
+
+Mime Mail 7.x-1.0-beta4, 2015-08-02
+-----------------------
+- #2413495 by sgabe, siggi_kid: Public images not embedded when file default scheme is private
+- #2312747 by Lukas von Blarer: Remove 'itok' token from image URL
+- #2366659 by david_garcia: Attachments created by content generate warnings
+- #2404719 by alexp999: Missing space in RFC headers breaks DKIM
+- #1908318 by jvieille, zionduc, bisonbleu | anrkaid: Sender is double encoded.
+- #2359771 by PascalAnimateur: Support for OG membership tokens.
+- #2218037 by sgabe | pinkonomy: Fixed integrity constraint violation.
+- #2219609 by mitrpaka, sgabe: Convert float properties just for images.
+- #2057703 by New Zeal, sgabe: Warning: is_file() expects a valid path.
+- #2202127 by k.skarlatos: Added List-Unsubscribe header field for bulk mails.
+- #2297135 by tobiasb: Language prefix with absolute-path reference.
+- #2297091 by cameron1729: TLDs in Return-Path trimmed to 4 characters.
+- #2237109 by Dane Powell: Indicate text format for body in Rules.
+
+Mime Mail 7.x-1.0-beta3, 2014-03-05
+-----------------------
+- Public files test incorrect if similar path is not below root.
+
+Mime Mail 7.x-1.0-beta2, 2014-02-26
+-----------------------
+- Stronger authentication for incoming messages.
+- #2031143 by sgabe, das-peter: Support @import by using drupal_load_stylesheet().
+- #2087913 by sgabe | alancsilver: Allow spaces in attachment filenames.
+- #1852694 by clemens.tolboom | Pixelstyle: Convert float to align for images.
+- #2145659 by sgabe, fatherguddha | raincloud: Images with 'itok' token are not embedded.
+- #2119613 by sgabe, david_garcia_garcia: Further improve boundary collision avoidance.
+- #2185909 by cyrus_bt5, ekidman: Extra space in long header fields.
+- #2152705 by gargsuchi: Images with 'itok' token not showing up.
+- #2129149 by pokap | satvision83: Undefined offset in mimemail_headers.
+
+Mime Mail 7.x-1.0-beta1, 2013-10-07
+-----------------------
+- #1702868 by sgabe, kid_icarus: Remove tokens if no replacement value can be generated.
+- #1719570 by sgabe, oadaeh | greggles: Fix for SA-CONTRIB-2012-124.
+- #2020875 by das-peter, Propaganistas: Provide option to set language in Rules actions.
+- #2045699 by sgabe | Punk_UnDeaD: Boundaries are not unique on Windows.
+- #1798324 by sgabe, kienan | ShaneOnABike: Return-Path is incorrectly using sender name.
+- #1790098 by sgabe | edb, Shellingfox: Custom 'from' address comes out as 'Array'.
+- #1979776 by sgabe | cswolf: Hash mark link gets replaced with site URL.
+- #1963412 by sgabe | djg_tram: Content-Disposition should default to 'inline'.
+- #1469828 by sgabe | shadowhitman: Allow to use simple address format only for recipient.
+- #1947018 by sgabe | bendev: Allow sending plain text messages with Rules.
+- #962226 by sgabe | rchuber: Allow custom mailkeys for system and Rules action messages.
+- #1873348 by sgabe | tutumlum: Cannot use tokens in subject and body of HTML email action.
+- #1439918 by sgabe | Lukas von Blarer: 'Link images only' is not working if the file exists as-is.
+- #1538004 by sgabe | djg_tram: Change template naming logic to use module as well.
+- #1719256 by lirantal, sgabe: Handle different files with the same file name.
+- #1922530 by berliner: Callto links in mail body wrongly replaced.
+- #1911558 by Simon Georges, JulienD: Remove useless files[] directive from .info files.
+- #1877928 by sgabe | parasite: Replacing underscore in key is not needed.
+- #1898140 by MiroslavBanov: Engine variable set to NULL on settings page.
+- #1780412 by sgabe, kid_icarus: Option to exclude blocked users from a role.
+- #1814922 by marcusx: Rule sanitizes the $body if populated by a parameter.
+- #1813348 by sgabe | jdhildeb: Sendmail invoked with empty Return-Path.
+- #1469022 by sgabe, das-peter | MI: Add 'Reply-to' field to Rules and system actions.
+- #1773698 by jherencia: Alternatives for mimemail-message.tpl.php do not work.
+- #1585546 by kotnik, bojanz: Rules actions must be in root module directory.
+
+Mime Mail 7.x-1.0-alpha2, 2012-08-22
+-----------------------
+- #1722188 by sgabe | christian death: Split has been deprecated.
+- #1643750 by sgabe | MRV: Remove class attributes from the compressed message.
+- #321026 by sgabe, LUTi | attiks: HTML messages are broken by line breaks.
+- #1605230 by sgabe | mrbubbs: Extra space in subject caused by wordwrap.
+- #1662682 by sgabe, itamar: Value may be left unset in requirements check.
+- #1504782 by rjkuyvenhoven: Update support for Fusion based themes.
+- #1597896 by sgabe | joewickert: Plus symbol encoded as space in URLs.
+- #1515660 by sgabe | philsward: Missing upgrade path for Rules actions.
+- #81707 by sgabe | FredCK, Peters196: Auto-detect appropriate line endings.
+- #1475664 by sgabe | pumpkinkid: Getting 'Array to string conversion' error.
+- #1301876 by sean_fremouw: Regex in mimemail_headers() strips allowed characters.
+- #1432502 by El Bandito: Quotations are not needed to specify an attachment.
+- #1349728 by jherencia: Possibility to configure the theme that will render the email.
+- #1391680 by marcdecaluwe: Headers not correctly set.
+- #1283620 by Cyberwolf: Expose email settings user field to field API.
+- #1372660 by eueco: Set the proper line ending when calling chunk_split().
+- #1388786 by tostinni: mimemail_html_body() fails to retrieve file's URI.
+
+Mime Mail 7.x-1.0-alpha1, 2011-12-18
+-----------------------
+- #1372088 by marcus.n3rd.26: Use uri to load mail.css when sending mail.
+- #1305824 by sgabe: Leave MIME type and use only path to specify an attachment.
+- #1370422 by awagner: Missing delimiter in file_scan_directory().
+- #1275734 by gnindl: Scan recursively for mail.css.
+- #1304332 by sgabe: Token replacement and PHP evaluation in Rules action messages.
+- #1305830 by sgabe | ibes: Set default filename and mimetype to enforce auto detection.
+- #1289584 by sgabe | oguerreiro: Check if 'styles' is set.
+- #1288546 by sgabe | carn1x: Unknown Rules actions.
+- #1066438 by quicksketch, sgabe, guillaumev, oadaeh: Initial support of attachments.
+- #1258302 by ralf.strobel: Replace 'arguments' with 'variables' in hook_theme().
+- #1190144 by Cyberwolf, sgabe: Trim less-than and grater-than chars from Return-Path.
+- #1140538 by sgabe: Site style sheet isn't included.
+- #1232266 by InternetDevels.Com: Engine select form element has wrong array key.
+
+Mime Mail 6.x-1.0, 2011-11-19
+-----------------------
+- #1232264 by InternetDevels.Com: Check for not just NULL but empty From address.
+- #1201154 by guillaumev: Check if attachments is an array and isn't empty.
+- #1203234 by sgabe | Offlein: Store input format setting for Rules and actions.
+- #1227242 by sgabe: Remove unnecessary reference signs.
+- #1076520 by joelstein: Absolute site stylesheets not included.
+- #1258062 by oadaeh: Don't allow an empty e-mail address with the default engine.
+- #1270686 by gmania: Don't add Content-Disposition to multipart/alternative parts.
+- #1260302 by sgabe | prokop1000: Replace encoding detection with UTF-8.
+- #1270656 by sgabe: From header can be an array which causes errors.
+- #1301868 by sean_fremouw: Headers overwritten.
+- #1308628 by sgabe, chriscohen: List function throws notice.
+- #1301924 by sgabe, ibes: Use array for body in Rules and system actions.
+- #417462 by plach, Lukas von Blarer, sgabe: Language prefix is not taken into account.
+- #1181170 by sgabe, Cyberwolf, ibes | windm: Add permission to set user specific settings.
+- #1309248 by sgabe, gmania: Generate not existing ImageCache images before embedding.
+- #1304134 by sdague: Add preference to link images.
+- #1275080 by gmania: Remove the depricated Errors-To header.
+
+Mime Mail 6.x-1.0-beta2, 2011-06-22
+----------------------
+- #1181486 by sgabe: HTML Message not saving in Rules Action form.
+- #1164870 by itserich: Recipient is not an array anymore.
+- #1186690 by samhassell: Can't send multiple attachments.
+
+Mime Mail 6.x-1.0-beta1, 2011-06-04
+----------------------
+- #911612 by geneticdrift: Hidden attachments in some email clients.
+- #1090286 by sgabe: Prepare action messages with drupal_mail() to allow alteration.
+- #1137358 by sgabe: Tokens don't work in the body of Rules action messages
+- #1150224 by sgabe: Run filters on the message body of Rules and system actions.
+- #1090286 by sgabe: Remove process function, fix sending message to a role action.
+- #1116930 by Pol, sgabe: No text alternative if the CSS is too large.
+- #808518 by sgabe: Return only the result from drupal_mail_wrapper().
+- #808518 by claudiu.cristea, sgabe: Split mail preparation from sending.
+- #1108324 by sgabe: Add input filter to HTML message for system and Rules actions.
+- #1114536 by rjbrown99: Pass recipient to the template.
+- #971272 by sgabe: Allow to specify sender's name for Rules action messages.
+- #1167576 by Pol: Accept plaintext and text parameters for system messages.
+- #338460 by hopla: Doens't look for mail.css in Zen sub-themes.
+- #261028 by sgabe, gnosis, mfb, mrfelton, LUTi: SMTP Return-Path Setting.
+- #1175378 by sgabe, samalone: Include module CSS files in email.
+
+Mime Mail 6.x-1.0-alpha8, 2011-03-24
+----------------------
+- #374615 by joelstein: Set starter default value for plain text user reference.
+- #1076222 by papasse, Aron Novak: Check the module path on settings submission.
+- #920904 by fmjrey: Fusion local.css not taken into account.
+- #443964 by sgabe, pillarsdotnet: Skip style sheets with print media.
+- #932962 by clydefrog, arvana, sgabe: Allow attachments to be added by contents.
+- #907716 by isaac.niebeling: Allow non-web-accessible files as attachments.
+- #758922 by eft, sgabe: Use simple address format for PHP mail() on Windows.
+
+Mime Mail 6.x-1.0-alpha7, 2011-01-31
+----------------------
+- #950456 by stella, sgabe: Check if body encoding can be, and is it detected
+- #364198 by mfb, sgabe | HS: CSS code in email
+- #835734 by sgabe | sylvaticus: In some cases CSS optimization causes WSOD
+- #438058 by AlexisWilke, DanChadwick: Remove line feeds in subject
+- #979748 by Romka: Missing include in mimemail_mailengine()
+- #700996 by smk-ka: Custom inline style properties overwritten
+- #960374 by kim-day: Don't set BCC and CC headers if they are empty
+- #961536 by clydefrog: Check if sender is empty, not just null
+- #852698 by sgabe | interestingaftermath: Specify sender's name
+- #685574 by sgabe, Wim Leers | Michelle: Optional site's css embedding
+- #758754 by sgabe | mennonot: Add 'Send HTML e-mail' action
+- #501722 by jpetso, fago, criz, sgabe, aantonop: HTML mail actions for Rules
+- #729658 by sgabe, Agileware: Allow better integration with Domain Access module
+- #960726 by sgabe, clydefrog: Send plaintext message if the HTML body is empty
+
+Mime Mail 6.x-1.0-alpha6, 2010-09-13
+----------------------
+- #629038 by Robbert: Attachments dont respect ‘list’ setting
+- #882960 by sgabe, glynster: CSS Mail Style Sheet Overrides
+- #319229 by javierreartes, tobiasb, sgabe, crifi: Set $attachments in drupal_wrap_mail()
+- #903536 by sgabe: Use variable_del() to remove smtp_library()
+- #456242 by sgabe, kenorb: Use proper operators in if statements with strpos()
+- #882528 by sgabe | Carsten: Template suggestions based on mailkey
+- #752838 by sgabe | dsms: Pass $subject to the template
+- #319384 by sgabe | mariuss: Add $mailkey to body tag as CSS class
+- #796510 by sgabe | smk-ka: Update CSS Compressor
+- #614782 by sgabe, Sutharsan: Update README.txt
+
+Mime Mail 6.x-1.0-alpha5, 2010-08-12
+----------------------
+- #850674 by sgabe, AlexisWilke: Prepare function name testing '_prepare'...
+- #448996 by mfb, hanoii, Sylvain Lecoy: Wrong implementation of hook_mail_alter()
+- #319229 by sgabe, jm.federico, joostvdl, donquixote, fehin, sunfire-design, mariuss: src='Array' if path to image is broken
+- #517306 by sgabe, rdosser: Mime Mail Compress mangles absolute URLs in CSS properties
+- #597448 by sgabe, rmjiv: Unsafe regex pattern in mimemail_extract_files()
+- #535466 by andreiashu, sgabe: WSOD when using Mime Mail Compress without DOM extension
+- #513138 by sgabe, peterx: Undefined variables in mimemail.inc
+- #304476 by sgabe, Thomas_Zahreddin, aaron: PHP Error when Stylesheets don't exist
+- #710116 by sgabe, neoglez: Wrong implementation/namespace conflict of mimemail_prepare()
+
+Mime Mail 6.x-1.0-alpha4, 2010-07-10
+----------------------
+- #642800 by scronide: Enforce requirement of PHP 5.x for Mime Mail Compress
+- #740856 by sgabe, Vicbus: Check if the file part is set in the body
+- #567594 by hanoii: $mailkey is not properly set in drupal_mail_wrapper()
+- #768794 by sgabe, danyg: Check if the name is empty when the address is an object
+- #700996 by sgabe, -Mania-: Custom inline style properties overwritten when using CSS Compressor
+- #729334 by plach: Flawed CSS to XPath conversion for class selectors in Mime Mail CSS Compressor
+- #456260 by sgabe, kenorb, kscheirer, mitchmac: WSOD: smtp_library variable is not removed when Mime Mail has been disabled
+- #698794 by sgabe, mobilis: Attachment Content-Type-fix
+- #629038 by jackinloadup, sgabe: Attachments don't respect list setting
+
+Mime Mail 6.x-1.0-alpha3, 2010-06-16
+----------------------
+- #358439 by folkertdv: Images are only in the first message
+- #448670 by sgabe, gregarios, moritzz: Spaces and Line Breaks are removed from CSS definitions
+- #372710 by LUTi, sgabe, perarnet: HTML emails are text-only in Hotmail
+- #583920 by Sutharsan, sgabe: Can't override mimemail.tpl.php
+- #127876 by sgabe, Sutharsan, jerdavis: Plain text with/without attachment
diff --git a/profiles/wcm_base/modules/contrib/mimemail/LICENSE.txt b/profiles/wcm_base/modules/contrib/mimemail/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d159169d1050894d3ea3b98e1c965c4058208fe1
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/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/mimemail/README.txt b/profiles/wcm_base/modules/contrib/mimemail/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1bb6aa47b2f81af6e06b27d78d72a46696cbbc4e
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/README.txt
@@ -0,0 +1,136 @@
+
+-- SUMMARY --
+
+  This is a Mime Mail component module (for use by other modules).
+    * It permits users to recieve HTML email and can be used by other modules. The mail
+      functionality accepts an HTML message body, mime-endcodes it and sends it.
+    * If the HTML has embedded graphics, these graphics are MIME-encoded and included
+      as a message attachment.
+    * Adopts your site's style by automatically including your theme's stylesheet files in a
+      themeable HTML message format
+   *  If the recipient's preference is available and they prefer plaintext, the HTML will be
+      converted to plain text and sent as-is. Otherwise, the email will be sent in themeable
+      HTML with a plaintext alternative.
+
+  For a full description of the module, visit the project page:
+    http://drupal.org/project/mimemail
+
+  To submit bug reports and feature suggestions, or to track changes:
+    http://drupal.org/project/issues/mimemail
+
+
+-- REQUIREMENTS --
+
+  Mail System module - http://drupal.org/project/mailsystem
+
+
+-- INSTALLATION --
+
+  Hopefully, you know the drill by now :)
+  1. Download the module and extract the files.
+  2. Upload the entire mimemail folder into your Drupal sites/all/modules/
+     or sites/my.site.folder/modules/ directory if you are running a multi-site
+     installation of Drupal and you want this module to be specific to a
+     particular site in your installation.
+  3. Enable the Mime Mail module by navigating to:
+     Administration > Modules
+  4. Adjust settings by navigating to:
+     Administration > Configuration > Mime Mail
+
+
+-- USAGE --
+
+  This module may be required by other modules, but in favor of the recently
+  added system actions and Rules integration, it can be useful by itself too.
+
+  Once installed, any module can send MIME-encoded messages by specifing
+  MimeMailSystem as the responsible mail system for a particular message
+  or all mail sent by one module.
+
+  This can be done through the web by visiting admin/config/system/mailsystem
+  or in a program as follows:
+
+  mailsystem_set(array(
+    '{$module}_{$key}' => 'MimeMailSystem', // Just messages with $key sent by $module.
+    '{$module}' => 'MimeMailSystem', // All messages sent by $module.
+  ));
+
+  You can use the following optional parameters to build the e-mail:
+    'plain':
+      Boolean, whether to send messages in plaintext-only (optional, default is FALSE).
+    'plaintext':
+      Plaintext portion of a multipart e-mail (optional).
+    'attachments':
+      Array of arrays with the path or content, name and MIME type of the file (optional).
+    'headers':
+      A keyed array with headers (optional).
+
+  You can set these in $params either before calling drupal_mail() or in hook_mail()
+  and of course hook_mail_alter().
+
+  Normally, Mime Mail uses email addresses in the form of "name" <address@host.com>,
+  but PHP running on Windows servers requires extra SMTP handling to use this format.
+  If you are running your site on a Windows server and don't have an SMTP solution such
+  as the SMTP module installed, you may need to set the 'Use the simple format of
+  user@example.com for all email addresses' option on the configuration settings page.
+
+  This module creates a user preference for receiving plaintext-only messages.
+  This preference will be honored by all messages if the format is not explicitly set
+  and the user has access to edit this preference (allowed by default).
+
+  Email messages are formatted using the mimemail-message.tpl.php template.
+  This includes a CSS style sheet and uses an HTML version of the text.
+  The included CSS is either:
+    the mail.css file found anywhere in your theme folder or
+    the combined CSS style sheets of your theme if enabled.
+
+  Since some email clients (namely Outlook 2007 and GMail) is tend to only regard
+  inline CSS, you can use the Compressor to convert CSS styles into inline style
+  attributes. It transmogrifies the HTML source by parsing the CSS and inserting the
+  CSS definitions into tags within the HTML based on the CSS selectors. To use the
+  Compressor, just enable it.
+
+  To create a custom mail template copy the mimemail-message.tpl.php file from
+  the mimemail/theme directory into your default theme's folder. Both general and
+  by-mailkey theming can be performed:
+    mimemail-message--[module]--[key].tpl.php (for messages with a specific module and key)
+    mimemail-message--[module].tpl.php (for messages with a specific module)
+    mimemail-message--[key].tpl.php (for messages with a specific key)
+    mimemail-message.tpl.php (for all messages)
+
+  Messages can be rendered using different themes. You can choose the following
+  settings to render the e-mail:
+    'current': Theme currently used by the user who runs drupal_mail().
+    'default': Default theme, obtained via variable theme_default.
+    'domain': Theme obtained via Domain Theme module.
+  or any other active theme.
+
+  Images with absolute URL will be available as remote content. To embed images
+  into emails you have to use a relative URL or an internal path. Due to security
+  concerns, only files residing in the public file system (e.g sites/default/files)
+  can be used by default.
+
+  For example:
+    instead of http://www.mysite.com/sites/default/files/mypicture.jpg
+    use /home/www/public_html/drupal/sites/default/files/mypicture.jpg
+    or /sites/default/files/mypicture.jpg
+    or public://mypicture.jpg
+
+  The 'send arbitrary files' permission allows you to attach or embed files located
+  outside Drupal's public files directory. Note that this has security implications:
+  arbitrary means even your settings.php! Give to trusted roles only!
+
+
+-- CREDITS --
+
+  MAINTAINER: Allie Micka < allie at pajunas dot com >
+
+  * Allie Micka
+    Mime enhancements and HTML mail code
+
+  * Gerhard Killesreiter
+    Original mail and mime code
+
+  * Robert Castelo
+    HTML to Text and other functionality
+
diff --git a/profiles/wcm_base/modules/contrib/mimemail/includes/mimemail.admin.inc b/profiles/wcm_base/modules/contrib/mimemail/includes/mimemail.admin.inc
new file mode 100644
index 0000000000000000000000000000000000000000..ca71e54e3cf648f0ec7595f671fb74bc55282728
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/includes/mimemail.admin.inc
@@ -0,0 +1,154 @@
+<?php
+
+/**
+ * @file
+ * Configuration settings page for sending MIME-encoded emails.
+ */
+
+/**
+ * Configuration form.
+ */
+function mimemail_admin_settings() {
+  // Check for the existence of a mail.css file in the default theme folder.
+  $theme = variable_get('theme_default', NULL);
+  $mailstyle = drupal_get_path('theme', $theme) . '/mail.css';
+  // Disable site style sheets including option if found.
+  if (is_file($mailstyle)) {
+    variable_set('mimemail_sitestyle', 0);
+    $disable_sitestyle = TRUE;
+  }
+  else {
+    $disable_sitestyle = FALSE;
+  }
+
+  $form = array();
+  $form['mimemail']['mimemail_name'] = array(
+    '#type'          => 'textfield',
+    '#title'         => t('Sender name'),
+    '#default_value' => variable_get('mimemail_name', variable_get('site_name', 'Drupal')),
+    '#size'          => 60,
+    '#maxlength'     => 128,
+    '#description'   => t('The name that all site emails will be from when using default engine.'),
+  );
+  $form['mimemail']['mimemail_mail'] = array(
+    '#type'          => 'textfield',
+    '#title'         => t('Sender e-mail address'),
+    '#default_value' => variable_get('mimemail_mail', variable_get('site_mail', ini_get('sendmail_from'))),
+    '#size'          => 60,
+    '#maxlength'     => 128,
+    '#description'   => t('The email address that all site e-mails will be from when using default engine.'),
+  );
+  $form['mimemail']['mimemail_simple_address'] = array(
+    '#type'          => 'checkbox',
+    '#title'         => t('Use simple address format'),
+    '#default_value' => variable_get('mimemail_simple_address', FALSE),
+    '#description' => t('Use the simple format of user@example.com for all recipient email addresses.'),
+  );
+  $form['mimemail']['mimemail_sitestyle'] = array(
+    '#type'          => 'checkbox',
+    '#title'         => t('Include site style sheets'),
+    '#default_value' => variable_get('mimemail_sitestyle', TRUE),
+    '#description'   => t('Gather all style sheets when no mail.css found in the default theme directory.'),
+    '#disabled'      => $disable_sitestyle,
+  );
+  $form['mimemail']['mimemail_textonly'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Send plain text email only'),
+    '#default_value' => variable_get('mimemail_textonly', FALSE),
+    '#description' => t('This option disables the use of email messages with graphics and styles. All messages will be converted to plain text.'),
+  );
+  $form['mimemail']['mimemail_linkonly'] = array(
+    '#type'          => 'checkbox',
+    '#title'         => t('Link images only'),
+    '#default_value' => variable_get('mimemail_linkonly', 0),
+    '#description'   => t('This option disables the embedding of images. All image will be available as external content. This can make email messages much smaller.'),
+  );
+  if (module_exists('mimemail_compress')) {
+    $form['mimemail']['mimemail_preserve_class'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Preserve class attributes'),
+      '#default_value' => variable_get('mimemail_preserve_class', 0),
+      '#description' => t('This option disables the removing of class attributes from the message source. Useful for debugging the style of the message.'),
+    );
+  }
+
+  // Get a list of all formats.
+  $formats = filter_formats();
+  foreach ($formats as $format) {
+    $format_options[$format->format] = $format->name;
+  }
+  $form['mimemail']['mimemail_format'] = array(
+    '#type' => 'select',
+    '#title' => t('E-mail format'),
+    '#options' => $format_options,
+    '#default_value' => variable_get('mimemail_format', filter_fallback_format()),
+    '#access' => count($formats) > 1,
+    '#attributes' => array('class' => array('filter-list')),
+    '#description' => t('The filter set that will be applied to the message body.
+      If you are using Mime Mail as default mail sytem, make sure to enable
+      "Convert line breaks into HTML" and "Convert URLs into links" with a long
+      enough maximum length for e.g. password reset URLs!'),
+  );
+
+  $form['mimemail']['advanced'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Advanced settings'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['mimemail']['advanced']['mimemail_incoming'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Process incoming messages posted to this site'),
+    '#default_value' => variable_get('mimemail_incoming', FALSE),
+    '#description' => t('This is an advanced setting that should not be enabled unless you know what you are doing.'),
+  );
+  $form['mimemail']['advanced']['mimemail_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Message validation string'),
+    '#default_value' => variable_get('mimemail_key', drupal_random_key()),
+    '#required' => TRUE,
+    '#description' => t('This string will be used to validate incoming messages. It can be anything, but must be used on both sides of the transfer.'),
+  );
+
+  // Get the available mail engines.
+  $engines = mimemail_get_engines();
+  foreach ($engines as $module => $engine) {
+    $engine_options[$module] = $engine['name'] . ': ' . $engine['description'];
+  }
+  // Hide the settings if only 1 engine is available.
+  if (count($engines) == 1) {
+    reset($engines);
+    variable_set('mimemail_engine', key($engines));
+    $form['mimemail']['mimemail_engine'] = array(
+      '#type' => 'hidden',
+      '#value' => variable_get('mimemail_engine', 'mimemail'),
+    );
+  }
+  else {
+    $form['mimemail']['mimemail_engine'] = array(
+      '#type' => 'select',
+      '#title' => t('E-mail engine'),
+      '#default_value' => variable_get('mimemail_engine', 'mimemail'),
+      '#options' => $engine_options,
+      '#description' => t('Choose an engine for sending mails from your site.'),
+    );
+  }
+
+  if (variable_get('mimemail_engine', 'mail')) {
+    $settings = module_invoke(variable_get('mimemail_engine', 'mimemail'), 'mailengine', 'settings');
+    if ($settings) {
+      $form['mimemail']['engine_settings'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Engine specific settings'),
+      );
+      foreach ($settings as $name => $value) {
+        $form['mimemail']['engine_settings'][$name] = $value;
+      }
+    }
+  }
+  else {
+    drupal_set_message(t('Please choose a mail engine.'), 'error');
+  }
+
+  return system_settings_form($form);
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/includes/mimemail.incoming.inc b/profiles/wcm_base/modules/contrib/mimemail/includes/mimemail.incoming.inc
new file mode 100644
index 0000000000000000000000000000000000000000..ff1d43f7e30ae1e6b0c622eba1a2e4fb791fcecf
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/includes/mimemail.incoming.inc
@@ -0,0 +1,211 @@
+<?php
+
+/**
+ * @file
+ * Functions that handle inbound messages to mimemail.
+ */
+
+/**
+ * Receive messages POSTed from an external source.
+ *
+ * This function enables messages to be sent via POST or some other RFC822
+ * source input (e.g. directly from a mail server).
+ *
+ * @return
+ *   The POSTed message.
+ */
+function mimemail_post() {
+  if (!isset($_POST['token']) || empty($_POST['token'])) {
+    return drupal_access_denied();
+  }
+
+  if (isset($_POST['message']) && !empty($_POST['message'])) {
+    $key = variable_get('mimemail_key', drupal_random_key());
+    $hash = hash_hmac('sha1', $_POST['message'], $key);
+    if ($hash != $_POST['token']) {
+      watchdog('access denied', 'Authentication error for POST e-mail', WATCHDOG_WARNING);
+      return drupal_access_denied();
+    }
+    else {
+      return mimemail_incoming($_POST['message']);
+    }
+  }
+
+  return drupal_access_denied();
+}
+
+/**
+ * Parses an externally received message.
+ *
+ * @param $message
+ *   The message to parse.
+ */
+function mimemail_incoming($message) {
+  $mail = mimemail_parse($message);
+
+  foreach (module_implements('mimemail_incoming_alter') as $module) {
+    call_user_func_array($module . '_mimemail_incoming_alter', $mail);
+  }
+
+  module_invoke_all('mimemail_incoming', $mail);
+}
+
+/**
+ * Parses a message into its parts.
+ *
+ * @param string $message
+ *   The message to parse.
+ *
+ * @return array
+ *   The parts of the message.
+ */
+function mimemail_parse($message) {
+  // Provides a "headers", "content-type" and "body" element.
+  $mail = mimemail_parse_headers($message);
+
+  // Get an address-only version of "From" (useful for user_load() and such).
+  $mail['from'] = preg_replace('/.*\b([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4})\b.*/i', '\1', drupal_strtolower($mail['headers']['From']));
+
+  // Get a subject line, which may be cleaned up/modified later.
+  $mail['subject'] = $mail['headers']['Subject'];
+
+  // Make an array to hold any non-content attachments.
+  $mail['attachments'] = array();
+
+  // We're dealing with a multi-part message.
+  $mail['parts'] = mimemail_parse_boundary($mail);
+
+  foreach ($mail['parts'] as $i => $part_body) {
+    $part = mimemail_parse_headers($part_body);
+    $sub_parts = mimemail_parse_boundary($part);
+
+    // Content is encoded in a multipart/alternative section.
+    if (count($sub_parts) > 1) {
+      foreach ($sub_parts as $j => $sub_part_body) {
+        $sub_part = mimemail_parse_headers($sub_part_body);
+        if ($sub_part['content-type'] == 'text/plain') {
+          $mail['text'] = mimemail_parse_content($sub_part);
+        }
+        if ($sub_part['content-type'] == 'text/html') {
+          $mail['html'] = mimemail_parse_content($sub_part);
+        }
+        else {
+          $mail['attachments'][] = mimemail_parse_attachment($sub_part);
+        }
+      }
+    }
+
+    if (($part['content-type'] == 'text/plain') && !isset($mail['text'])) {
+      $mail['text'] = mimemail_parse_content($part);
+    }
+    elseif (($part['content-type'] == 'text/html') && !isset($mail['html'])) {
+      $mail['html'] = mimemail_parse_content($part);
+    }
+    else {
+      $mail['attachments'][] = mimemail_parse_attachment($part);
+    }
+  }
+
+  // Make sure our text and html parts are accounted for.
+  if (isset($mail['html']) && !isset($mail['text'])) {
+    $mail['text'] = preg_replace('|<style.*</style>|mis', '', $mail['html']);
+    $mail['text'] = drupal_html_to_text($mail['text']);
+  }
+  elseif (isset($mail['text']) && !isset($mail['html'])) {
+    $mail['html'] = check_markup($mail['text'], variable_get('mimemail_format', filter_fallback_format()));
+  }
+
+  // Last ditch attempt - use the body as-is.
+  if (!isset($mail['text'])) {
+    $mail['text'] = mimemail_parse_content($mail);
+    $mail['html'] = check_markup($mail['text'], variable_get('mimemail_format', filter_fallback_format()));
+  }
+
+  return $mail;
+}
+
+/**
+ * Split a multi-part message using MIME boundaries.
+ */
+function mimemail_parse_boundary($part) {
+  $m = array();
+  if (preg_match('/.*boundary="?([^";]+)"?.*/', $part['headers']['Content-Type'], $m)) {
+    $boundary = "\n--" . $m[1];
+    $body     = str_replace("$boundary--", '', $part['body']);
+    return array_slice(explode($boundary, $body), 1);
+  }
+  return array($part['body']);
+}
+
+/**
+ * Split a message (or message part) into its headers and body section.
+ */
+function mimemail_parse_headers($message) {
+  // Split out body and headers.
+  if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $message, $match)) {
+    list($hdr, $body) = array($match[1], $match[2]);
+  }
+
+  // Un-fold the headers.
+  $hdr = preg_replace(array("/\r/", "/\n(\t| )+/"), array('', ' '), $hdr);
+
+  $headers = array();
+  foreach (explode("\n", trim($hdr)) as $row) {
+    $split = strpos($row, ':');
+    $name = trim(drupal_substr($row, 0, $split));
+    $val = trim(drupal_substr($row, $split+1));
+    $headers[$name] = $val;
+  }
+
+  $type = (preg_replace('/\s*([^;]+).*/', '\1', $headers['Content-Type']));
+
+  return array('headers' => $headers, 'body' => $body, 'content-type' => $type);
+}
+
+/**
+ * Return a decoded MIME part in UTF-8.
+ */
+function mimemail_parse_content($part) {
+  $content = $part['body'];
+
+  // Decode this part.
+  if ($encoding = drupal_strtolower($part['headers']['Content-Transfer-Encoding'])) {
+    switch ($encoding) {
+      case 'base64':
+        $content = base64_decode($content);
+        break;
+      case 'quoted-printable':
+        $content = quoted_printable_decode($content);
+        break;
+      // 7bit is the RFC default.
+      case '7bit':
+        break;
+    }
+  }
+
+  // Try to convert character set to UTF-8.
+  if (preg_match('/.*charset="?([^";]+)"?.*/', $part['headers']['Content-Type'], $m)) {
+    $content = drupal_convert_to_utf8($content, $m[1]);
+  }
+
+  return $content;
+}
+
+/**
+ * Convert a MIME part into a file array.
+ */
+function mimemail_parse_attachment($part) {
+  $m = array();
+  if (preg_match('/.*filename="?([^";])"?.*/', $part['headers']['Content-Disposition'], $m)) {
+    $name = $m[1];
+  }
+  elseif (preg_match('/.*name="?([^";])"?.*/', $part['headers']['Content-Type'], $m)) {
+    $name = $m[1];
+  }
+
+  return array(
+    'filename' => $name,
+    'filemime' => $part['content-type'],
+    'content'  => mimemail_parse_content($part),
+  );
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/includes/mimemail.mail.inc b/profiles/wcm_base/modules/contrib/mimemail/includes/mimemail.mail.inc
new file mode 100644
index 0000000000000000000000000000000000000000..04774faab8346f8ddba414bf969ae62addff41c7
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/includes/mimemail.mail.inc
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Mime Mail implementations of MailSystemInterface.
+ */
+
+/**
+ * Modify the Drupal mail system to send HTML emails.
+ */
+class MimeMailSystem implements MailSystemInterface {
+  /**
+   * Concatenate and wrap the e-mail body for HTML mails.
+   *
+   * @param array $message
+   *   A message array, as described in hook_mail_alter() with optional
+   *   parameters described in mimemail_prepare_message().
+   *
+   * @return array
+   *   The formatted $message.
+   */
+  public function format(array $message) {
+    if (is_array($message['body'])) {
+      $message['body'] = implode("\n\n", $message['body']);
+    }
+
+    if (preg_match('/plain/', $message['headers']['Content-Type'])) {
+      $message['body'] = check_markup($message['body'], variable_get('mimemail_format', filter_fallback_format()));
+    }
+
+    $engine = variable_get('mimemail_engine', 'mimemail');
+    $mailengine = $engine . '_mailengine';
+    $engine_prepare_message = $engine . '_prepare_message';
+
+    if (function_exists($engine_prepare_message)) {
+      $message = $engine_prepare_message($message);
+    }
+    else {
+      $message = mimemail_prepare_message($message);
+    }
+
+    return $message;
+  }
+  /**
+   * Send an HTML e-mail message, using Drupal variables and default settings.
+   *
+   * @param array $message
+   *   A message array, as described in hook_mail_alter() with optional
+   *   parameters described in mimemail_prepare_message().
+   *
+   * @return boolean
+   *   TRUE if the mail was successfully accepted, otherwise FALSE.
+   */
+  public function mail(array $message) {
+    $engine = variable_get('mimemail_engine', 'mimemail');
+    $mailengine = $engine . '_mailengine';
+
+    if (!$engine || !function_exists($mailengine)) {
+      return FALSE;
+    }
+
+    return $mailengine('send', $message);
+  }
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/mimemail.inc b/profiles/wcm_base/modules/contrib/mimemail/mimemail.inc
new file mode 100644
index 0000000000000000000000000000000000000000..3dbb0052d03a3ff0467ec3f2fe9bb496f8d99b77
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/mimemail.inc
@@ -0,0 +1,577 @@
+<?php
+
+/**
+ * @file
+ * Common mail functions for sending e-mail. Originally written by Gerhard.
+ *
+ *   Allie Micka <allie at pajunas dot com>
+ */
+
+/**
+ * Attempts to RFC822-compliant headers for the mail message or its MIME parts.
+ *
+ * @todo Could use some enhancement and stress testing.
+ *
+ * @param array $headers
+ *   An array of headers.
+ *
+ * @return string
+ *   A string containing the headers.
+ */
+function mimemail_rfc_headers($headers) {
+  $header = '';
+  $crlf = variable_get('mimemail_crlf', MAIL_LINE_ENDINGS);
+  foreach ($headers as $key => $value) {
+    $key = trim($key);
+    // Collapse spaces and get rid of newline characters.
+    $value = preg_replace('/(\s+|\n|\r|^\s|\s$)/', ' ', $value);
+    // Fold headers if they're too long.
+    // A CRLF may be inserted before any WSP.
+    // @see http://tools.ietf.org/html/rfc2822#section-2.2.3
+    if (drupal_strlen($value) > 60) {
+      // If there's a semicolon, use that to separate.
+      if (count($array = preg_split('/;\s*/', $value)) > 1) {
+        $value = trim(join(";$crlf ", $array));
+      }
+      else {
+        $value = wordwrap($value, 50, "$crlf ", FALSE);
+      }
+    }
+    $header .= $key . ": " . $value . $crlf;
+  }
+  return trim($header);
+}
+
+/**
+ * Gives useful defaults for standard email headers.
+ *
+ * @param array $headers
+ *   Message headers.
+ * @param string $from
+ *   The address of the sender.
+ *
+ * @return array
+ *   Overwrited headers.
+ */
+function mimemail_headers($headers, $from = NULL) {
+  $default_from = variable_get('site_mail', ini_get('sendmail_from'));
+
+  // Overwrite standard headers.
+  if ($from) {
+    if (!isset($headers['From']) || $headers['From'] == $default_from) {
+      $headers['From'] = $from;
+    }
+    if (!isset($headers['Sender']) || $headers['Sender'] == $default_from) {
+      $headers['Sender'] = $from;
+    }
+    // This may not work. The MTA may rewrite the Return-Path.
+    if (!isset($headers['Return-Path']) || $headers['Return-Path'] == $default_from) {
+      // According to IANA the current longest TLD is 23 characters.
+      if (preg_match('/[a-z\d\-\.\+_]+@(?:[a-z\d\-]+\.)+[a-z\d]{2,23}/i', $from, $matches)) {
+        $headers['Return-Path'] = "<$matches[0]>";
+      }
+    }
+  }
+
+  // Convert From header if it is an array.
+  if (is_array($headers['From'])) {
+    $headers['From'] = mimemail_address($headers['From']);
+  }
+
+  // Run all headers through mime_header_encode() to convert non-ascii
+  // characters to an rfc compliant string, similar to drupal_mail().
+  foreach ($headers as $key => $value) {
+    // According to RFC 2047 addresses MUST NOT be encoded.
+    if ($key !== 'From' && $key !== 'Sender') {
+      $headers[$key] = mime_header_encode($value);
+    }
+  }
+
+  return $headers;
+}
+
+/**
+ * Extracts links to local images from HTML documents.
+ *
+ * @param string $html
+ *   A string containing the HTML source of the message.
+ *
+ * @return array
+ *   An array containing the document body and the extracted files like the following.
+ *     array(
+ *       array(
+ *         'name' => document name
+ *         'content' => html text, local image urls replaced by Content-IDs,
+ *         'Content-Type' => 'text/html; charset=utf-8')
+ *       array(
+ *         'name' => file name,
+ *         'file' => reference to local file,
+ *         'Content-ID' => generated Content-ID,
+ *         'Content-Type' => derived using mime_content_type if available, educated guess otherwise
+ *        )
+ *     )
+ */
+function mimemail_extract_files($html) {
+  $pattern = '/(<link[^>]+href=[\'"]?|<object[^>]+codebase=[\'"]?|@import |[\s]src=[\'"]?)([^\'>"]+)([\'"]?)/mis';
+  $content = preg_replace_callback($pattern, '_mimemail_replace_files', $html);
+
+  $encoding = '8Bit';
+  $body = explode("\n", $content);
+  foreach ($body as $line) {
+    if (drupal_strlen($line) > 998) {
+      $encoding = 'base64';
+      break;
+    }
+  }
+  if ($encoding == 'base64') {
+    $content = rtrim(chunk_split(base64_encode($content)));
+  }
+
+  $document = array(array(
+    'Content-Type' => "text/html; charset=utf-8",
+    'Content-Transfer-Encoding' => $encoding,
+    'content' => $content,
+  ));
+
+  $files = _mimemail_file();
+
+  return array_merge($document, $files);
+}
+
+/**
+ * Callback function for preg_replace_callback().
+ */
+function _mimemail_replace_files($matches) {
+  return stripslashes($matches[1]) . _mimemail_file($matches[2]) . stripslashes($matches[3]);
+}
+
+/**
+ * Helper function to extract local files.
+ *
+ * @param string $url
+ *   (optional) The URI or the absolute URL to the file.
+ * @param string $content
+ *   (optional) The actual file content.
+ * @param string $name
+ *   (optional) The file name.
+ * @param string $type
+ *   (optional) The file type.
+ * @param string $disposition
+ *   (optional) The content disposition. Defaults to inline.
+ *
+ * @return
+ *   The Content-ID and/or an array of the files on success or the URL on failure.
+ */
+function _mimemail_file($url = NULL, $content = NULL, $name = '', $type = '', $disposition = 'inline') {
+  static $files = array();
+  static $ids = array();
+
+  if ($url) {
+    $image = preg_match('!\.(png|gif|jpg|jpeg)$!i', $url);
+    $linkonly = variable_get('mimemail_linkonly', 0);
+    // The file exists on the server as-is. Allows for non-web-accessible files.
+    if (@is_file($url) && $image && !$linkonly) {
+      $file = $url;
+    }
+    else {
+      $url = _mimemail_url($url, 'TRUE');
+      // The $url is absolute, we're done here.
+      $scheme = file_uri_scheme($url);
+      if ($scheme == 'http' || $scheme == 'https' || preg_match('!mailto:!', $url)) {
+        return $url;
+      }
+      // The $url is a non-local URI that needs to be converted to a URL.
+      else {
+        $file = (drupal_realpath($url)) ? drupal_realpath($url) : file_create_url($url);
+      }
+    }
+  }
+  // We have the actual content.
+  elseif ($content) {
+    $file = $content;
+  }
+
+  if (isset($file)) {
+    $is_file = @is_file($file);
+
+    if ($is_file) {
+      $access = user_access('send arbitrary files');
+      $in_public_path = strpos(@drupal_realpath($file), drupal_realpath('public://')) === 0;
+      if (!$in_public_path && !$access) {
+        return $url;
+      }
+    }
+
+    if (!$name) {
+      $name = $is_file ? basename($file) : 'attachment.dat';
+    }
+    if (!$type) {
+      $type = $is_file ? file_get_mimetype($file) : file_get_mimetype($name);
+    }
+
+    $id = md5($file) .'@'. $_SERVER['HTTP_HOST'];
+
+    // Prevent duplicate items.
+    if (isset($ids[$id])) {
+      return 'cid:'. $ids[$id];
+    }
+
+    $new_file = array(
+      'name' => $name,
+      'file' => $file,
+      'Content-ID' => $id,
+      'Content-Disposition' => $disposition,
+      'Content-Type' => $type,
+    );
+
+    $files[] = $new_file;
+    $ids[$id] = $id;
+
+    return 'cid:' . $id;
+  }
+  // The $file does not exist and no $content, return the $url if possible.
+  elseif ($url) {
+    return $url;
+  }
+
+  $ret = $files;
+  $files = array();
+  $ids = array();
+
+  return $ret;
+}
+
+/**
+ * Build a multipart body.
+ *
+ * @param array $parts
+ *   An associative array containing the parts to be included:
+ *   - name: A string containing the name of the attachment.
+ *   - content: A string containing textual content.
+ *   - file: A string containing file content.
+ *   - Content-Type: A string containing the content type of either file or content. Mandatory
+ *     for content, optional for file. If not present, it will be derived from file the file if
+ *     mime_content_type is available. If not, application/octet-stream is used.
+ *   - Content-Disposition: (optional) A string containing the disposition. Defaults to inline.
+ *   - Content-Transfer-Encoding: (optional) Base64 is assumed for files, 8bit for other content.
+ *   - Content-ID: (optional) for in-mail references to attachements.
+ *   Name is mandatory, one of content and file is required, they are mutually exclusive.
+ * @param string $content_type
+ *   (optional) A string containing the content-type for the combined message. Defaults to
+ *   multipart/mixed.
+ *
+ * @return array
+ *   An associative array containing the following elements:
+ *   - body: A string containing the MIME-encoded multipart body of a mail.
+ *   - headers: An array that includes some headers for the mail to be sent.
+ */
+function mimemail_multipart_body($parts, $content_type = 'multipart/mixed; charset=utf-8', $sub_part = FALSE) {
+  // Control variable to avoid boundary collision.
+  static $part_num = 0;
+
+  $boundary = sha1(uniqid($_SERVER['REQUEST_TIME'], TRUE)) . $part_num++;
+  $body = '';
+  $headers = array(
+    'Content-Type' => "$content_type; boundary=\"$boundary\"",
+  );
+  if (!$sub_part) {
+    $headers['MIME-Version'] = '1.0';
+    $body = "This is a multi-part message in MIME format.\n";
+  }
+
+  foreach ($parts as $part) {
+    $part_headers = array();
+
+    if (isset($part['Content-ID'])) {
+      $part_headers['Content-ID'] = '<' . $part['Content-ID'] . '>';
+    }
+
+    if (isset($part['Content-Type'])) {
+      $part_headers['Content-Type'] = $part['Content-Type'];
+    }
+
+    if (isset($part['Content-Disposition'])) {
+      $part_headers['Content-Disposition'] = $part['Content-Disposition'];
+    }
+    elseif (strpos($part['Content-Type'], 'multipart/alternative') === FALSE) {
+      $part_headers['Content-Disposition'] = 'inline';
+    }
+
+    if (isset($part['Content-Transfer-Encoding'])) {
+      $part_headers['Content-Transfer-Encoding'] = $part['Content-Transfer-Encoding'];
+    }
+
+    // Mail content provided as a string.
+    if (isset($part['content']) && $part['content']) {
+      if (!isset($part['Content-Transfer-Encoding'])) {
+        $part_headers['Content-Transfer-Encoding'] = '8bit';
+      }
+      $part_body = $part['content'];
+      if (isset($part['name'])) {
+        $part_headers['Content-Type'] .= '; name="' . $part['name'] . '"';
+        $part_headers['Content-Disposition'] .= '; filename="' . $part['name'] . '"';
+      }
+
+    // Mail content references in a filename.
+    }
+    else {
+      if (!isset($part['Content-Transfer-Encoding'])) {
+        $part_headers['Content-Transfer-Encoding'] = 'base64';
+      }
+
+      if (!isset($part['Content-Type'])) {
+        $part['Content-Type'] = file_get_mimetype($part['file']);
+      }
+
+      if (isset($part['name'])) {
+        $part_headers['Content-Type'] .= '; name="' . $part['name'] . '"';
+        $part_headers['Content-Disposition'] .= '; filename="' . $part['name'] . '"';
+      }
+
+      if (isset($part['file'])) {
+        $file = (@is_file($part['file'])) ? file_get_contents($part['file']) : $part['file'];
+        $part_body = chunk_split(base64_encode($file), 76, variable_get('mimemail_crlf', "\n"));
+
+      }
+    }
+
+    $body .= "\n--$boundary\n";
+    $body .= mimemail_rfc_headers($part_headers) . "\n\n";
+    $body .= isset($part_body) ? $part_body : '';
+  }
+  $body .= "\n--$boundary--\n";
+
+  return array('headers' => $headers, 'body' => $body);
+}
+
+/**
+ * Callback for preg_replace_callback().
+ */
+function _mimemail_expand_links($matches) {
+  return $matches[1] . _mimemail_url($matches[2]);
+}
+
+/**
+ * Generate a multipart message body with a text alternative for some HTML text.
+ *
+ * @param string $body
+ *   The HTML message body.
+ * @param string $subject
+ *   The message subject.
+ * @param boolean $plain
+ *   (optional) Whether the recipient prefers plaintext-only messages. Defaults to FALSE.
+ * @param string $plaintext
+ *   (optional) The plaintext message body.
+ * @param array $attachments
+ *   (optional) The files to be attached to the message.
+ *
+ * @return array
+ *   An associative array containing the following elements:
+ *   - body: A string containing the MIME-encoded multipart body of a mail.
+ *   - headers: An array that includes some headers for the mail to be sent.
+ *
+ * The first mime part is a multipart/alternative containing mime-encoded sub-parts for
+ * HTML and plaintext. Each subsequent part is the required image or attachment.
+ */
+function mimemail_html_body($body, $subject, $plain = FALSE, $plaintext = NULL, $attachments = array()) {
+  if (empty($plaintext)) {
+    // @todo Remove once filter_xss() can handle direct descendant selectors in inline CSS.
+    // @see http://drupal.org/node/1116930
+    // @see http://drupal.org/node/370903
+    // Pull out the message body.
+    preg_match('|<body.*?</body>|mis', $body, $matches);
+    $plaintext = drupal_html_to_text($matches[0]);
+  }
+  if ($plain) {
+    // Plain mail without attachment.
+    if (empty($attachments)) {
+      $content_type = 'text/plain';
+      return array(
+        'body' => $plaintext,
+        'headers' => array('Content-Type' => 'text/plain; charset=utf-8'),
+      );
+    }
+    // Plain mail with attachement.
+    else {
+      $content_type = 'multipart/mixed';
+      $parts = array(array(
+      'content' => $plaintext,
+        'Content-Type' => 'text/plain; charset=utf-8',
+      ));
+    }
+  }
+  else {
+    $content_type = 'multipart/mixed';
+
+    $plaintext_part = array('Content-Type' => 'text/plain; charset=utf-8', 'content' => $plaintext);
+
+    // Expand all local links.
+    $pattern = '/(<a[^>]+href=")([^"]*)/mi';
+    $body = preg_replace_callback($pattern, '_mimemail_expand_links', $body);
+
+    $mime_parts = mimemail_extract_files($body);
+
+    $content = array($plaintext_part, array_shift($mime_parts));
+    $content = mimemail_multipart_body($content, 'multipart/alternative', TRUE);
+    $parts = array(array('Content-Type' => $content['headers']['Content-Type'], 'content' => $content['body']));
+
+    if ($mime_parts) {
+      $parts = array_merge($parts, $mime_parts);
+      $content = mimemail_multipart_body($parts, 'multipart/related; type="multipart/alternative"', TRUE);
+      $parts = array(array('Content-Type' => $content['headers']['Content-Type'], 'content' => $content['body']));
+    }
+  }
+
+  if (is_array($attachments) && !empty($attachments)) {
+    foreach ($attachments as $a) {
+      $a = (object) $a;
+      $path = isset($a->uri) ? $a->uri : (isset($a->filepath) ? $a->filepath : NULL);
+      $content = isset($a->filecontent) ? $a->filecontent : NULL;
+      $name = isset($a->filename) ? $a->filename : NULL;
+      $type = isset($a->filemime) ? $a->filemime : NULL;
+      _mimemail_file($path, $content, $name, $type, 'attachment');
+      $parts = array_merge($parts, _mimemail_file());
+    }
+  }
+
+  return mimemail_multipart_body($parts, $content_type);
+}
+
+/**
+ * Helper function to format URLs.
+ *
+ * @param string $url
+ *   The file path.
+ * @param boolean $to_embed
+ *   (optional) Wheter the URL is used to embed the file. Defaults to NULL.
+ *
+ * @return string
+ *   A processed URL.
+ */
+function _mimemail_url($url, $to_embed = NULL) {
+  global $base_url;
+  $url = urldecode($url);
+
+  $to_link = variable_get('mimemail_linkonly', 0);
+  $is_image = preg_match('!\.(png|gif|jpg|jpeg)!i', $url);
+  $is_absolute = file_uri_scheme($url) != FALSE || preg_match('!(mailto|callto|tel)\:!', $url);
+
+  if (!$to_embed) {
+    if ($is_absolute) {
+      return str_replace(' ', '%20', $url);
+    }
+  }
+  else {
+    $url = preg_replace('!^' . base_path() . '!', '', $url, 1);
+    if ($is_image) {
+      // Remove security token from URL, this allows for styled image embedding.
+      // @see https://drupal.org/drupal-7.20-release-notes
+      $url = preg_replace('/\\?itok=.*$/', '', $url);
+      if ($to_link) {
+        // Exclude images from embedding if needed.
+        $url = file_create_url($url);
+        $url = str_replace(' ', '%20', $url);
+      }
+    }
+    return $url;
+  }
+
+  $url = str_replace('?q=', '', $url);
+  @list($url, $fragment) = explode('#', $url, 2);
+  @list($path, $query) = explode('?', $url, 2);
+
+  // If we're dealing with an intra-document reference, return it.
+  if (empty($path)) {
+    return '#' . $fragment;
+  }
+
+  // Get a list of enabled languages.
+  $languages = language_list('enabled');
+  $languages = $languages[1];
+
+  // Default language settings.
+  $prefix = '';
+  $language = language_default();
+
+  // Check for language prefix.
+  $path = trim($path, '/');
+  $args = explode('/', $path);
+  foreach ($languages as $lang) {
+    if (!empty($args) && $args[0] == $lang->prefix) {
+      $prefix = array_shift($args);
+      $language = $lang;
+      $path = implode('/', $args);
+      break;
+    }
+  }
+
+  $options = array(
+    'query' => ($query) ? drupal_get_query_array($query) : array(),
+    'fragment' => $fragment,
+    'absolute' => TRUE,
+    'language' => $language,
+    'prefix' => $prefix,
+  );
+
+  $url = url($path, $options);
+
+  // If url() added a ?q= where there should not be one, remove it.
+  if (preg_match('!^\?q=*!', $url)) {
+    $url = preg_replace('!\?q=!', '', $url);
+  }
+
+  $url = str_replace('+', '%2B', $url);
+  return $url;
+}
+
+/**
+ * Formats an address string.
+ *
+ * @todo Could use some enhancement and stress testing.
+ *
+ * @param mixed $address
+ *   A user object, a text email address or an array containing name, mail.
+ * @param boolean $simplify
+ *   Determines if the address needs to be simplified. Defaults to FALSE.
+ *
+ * @return string
+ *   A formatted address string or FALSE.
+ */
+function mimemail_address($address, $simplify = FALSE) {
+  if (is_array($address)) {
+    // It's an array containing 'mail' and/or 'name'.
+    if (isset($address['mail'])) {
+      $output = '';
+      if (empty($address['name']) || $simplify) {
+        return $address['mail'];
+      }
+      else {
+        return '"' . addslashes(mime_header_encode($address['name'])) . '" <' . $address['mail'] . '>';
+      }
+    }
+    // It's an array of address items.
+    $addresses = array();
+    foreach ($address as $a) {
+      $addresses[] = mimemail_address($a);
+    }
+    return $addresses;
+  }
+
+  // It's a user object.
+  if (is_object($address) && isset($address->mail)) {
+    if (empty($address->name) || $simplify) {
+      return $address->mail;
+    }
+    else {
+      return '"' . addslashes(mime_header_encode($address->name)) . '" <' . $address->mail . '>';
+    }
+  }
+
+  // It's formatted or unformatted string.
+  // @todo: shouldn't assume it's valid - should try to re-parse
+  if (is_string($address)) {
+    return $address;
+  }
+
+  return FALSE;
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/mimemail.info b/profiles/wcm_base/modules/contrib/mimemail/mimemail.info
new file mode 100644
index 0000000000000000000000000000000000000000..2d5d028f3722fc68a9be2d0b0960cc7f073be318
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/mimemail.info
@@ -0,0 +1,22 @@
+name = Mime Mail
+description = Send MIME-encoded emails with embedded images and attachments.
+dependencies[] = mailsystem
+dependencies[] = system (>=7.24)
+package = Mail
+core = 7.x
+
+configure = admin/config/system/mimemail
+
+files[] = includes/mimemail.mail.inc
+
+; Tests
+files[] = tests/mimemail.test
+files[] = tests/mimemail_rules.test
+files[] = tests/mimemail_compress.test
+
+; Information added by Drupal.org packaging script on 2015-08-02
+version = "7.x-1.0-beta4"
+core = "7.x"
+project = "mimemail"
+datestamp = "1438530555"
+
diff --git a/profiles/wcm_base/modules/contrib/mimemail/mimemail.install b/profiles/wcm_base/modules/contrib/mimemail/mimemail.install
new file mode 100644
index 0000000000000000000000000000000000000000..a09034c658adb8d5970a534696627fca8386d62a
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/mimemail.install
@@ -0,0 +1,113 @@
+<?php
+
+/**
+ * @file
+ * Install, update and uninstall functions for Mime Mail module.
+ */
+
+/**
+ * Implements hook_enable().
+ */
+function mimemail_enable() {
+  module_load_include('module', 'mailsystem');
+  mailsystem_set(
+    array(
+      mailsystem_default_id() => 'MimeMailSystem',
+      'mimemail' => 'MimeMailSystem',
+    )
+  );
+
+  user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('edit mimemail user settings'));
+}
+
+/**
+ * Implements hook_disable().
+ */
+function mimemail_disable() {
+  mailsystem_clear(array('mimemail' => 'MimeMailSystem'));
+  variable_set('mimemail_alter', FALSE);
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function mimemail_uninstall() {
+  $variables = array(
+    'mimemail_alter',
+    'mimemail_crlf',
+    'mimemail_engine',
+    'mimemail_incoming',
+    'mimemail_key',
+    'mimemail_textonly',
+    'mimemail_sitestyle',
+    'mimemail_name',
+    'mimemail_mail',
+    'mimemail_format',
+    'mimemail_simple_address',
+    'mimemail_linkonly',
+    'mimemail_preserve_class'
+  );
+  foreach ($variables as $variable) {
+    variable_del($variable);
+  }
+}
+
+/**
+ * Implements hook_requirements().
+ *
+ * Ensures that the newly-required Mail System module is available, or else
+ * disables the Mime Mail module and returns an informative error message.
+ */
+function mimemail_requirements($phase) {
+  if ($phase === 'install' || module_exists('mailsystem')) {
+    return array();
+  }
+  $args = array(
+    '!mailsystem' => url('http://drupal.org/project/mailsystem'),
+    '%mailsystem' => 'Mail System',
+    '!mimemail' => url('http://drupal.org/project/mimemail'),
+    '%mimemail' => 'Mime Mail',
+  );
+  if ( module_enable(array('mailsystem'))
+    && module_load_include('module', 'mailsystem')
+  ) {
+    drupal_set_message(
+      t('The %mailsystem module has been enabled because the %mimemail module now requires it.', $args)
+    );
+    return array();
+  }
+  return array(
+    'mimemail_mailsystem' => array(
+      'title' => t('%mailsystem module', $args),
+      'value' => t('Not installed'),
+      'description' => t(
+        'The <a href="!smtp">%mimemail</a> module dependencies have changed.  Please download and install the required <a href="!mailsystem">%mailsystem</a> module, then re-enable the <a href="!mimemail">%mimemail</a> module.', $args
+      ),
+      'severity' => REQUIREMENT_ERROR,
+    ),
+  );
+}
+
+/**
+ * Check installation requirements.
+ */
+function mimemail_update_7000() {
+  if ($requirements = mimemail_requirements('runtime')) {
+    throw new DrupalUpdateException($requirements['mimemail_mailsystem']['description']);
+  }
+}
+
+/**
+ * Deletes useless variables.
+ */
+function mimemail_update_7001() {
+  variable_del('mimemail_theme');
+}
+
+/**
+ * Generate new key for authenticating incoming messages.
+ */
+function mimemail_update_7002() {
+  variable_set('mimemail_key', drupal_random_key());
+  return t('Mime Mail has generated a new key to authenticate incoming messages.');
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/mimemail.module b/profiles/wcm_base/modules/contrib/mimemail/mimemail.module
new file mode 100644
index 0000000000000000000000000000000000000000..21164b8b61bde79c1505b4571fccea31197e9ac8
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/mimemail.module
@@ -0,0 +1,392 @@
+<?php
+
+/**
+ * @file
+ * Component module for sending Mime-encoded emails.
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function mimemail_menu() {
+  $path = drupal_get_path('module', 'mimemail') . '/includes';
+  // Configuration links.
+  $items['admin/config/system/mimemail'] = array(
+    'title' => 'Mime Mail',
+    'description' => 'Manage mime mail system settings.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('mimemail_admin_settings'),
+    'access arguments' => array('administer site configuration'),
+    'file' => 'mimemail.admin.inc',
+    'file path' => $path,
+  );
+  $items['mimemail'] = array(
+    'page callback' => 'mimemail_post',
+    'access callback' => 'mimemail_incoming_access',
+    'type' => MENU_CALLBACK,
+    'file' => 'mimemail.incoming.inc',
+    'file path' => $path,
+  );
+  return $items;
+}
+
+/**
+ * Implements hook_permission().
+ */
+function mimemail_permission() {
+  return array(
+    'edit mimemail user settings' => array(
+      'title' => t('Edit Mime Mail user settings'),
+      'description' => t('Edit user specific settings for Mime Mail.'),
+    ),
+    'send arbitrary files' => array(
+      'title' => t('Send arbitrary files'),
+      'description' => t('Attach or embed files located outside the public files directory.'),
+      'restrict access' => TRUE,
+    ),
+  );
+}
+
+/**
+ * Access callback to process incoming messages.
+ */
+function mimemail_incoming_access() {
+  return variable_get('mimemail_incoming', FALSE);
+}
+
+/**
+ * Implements hook_field_extra_fields().
+ */
+function mimemail_field_extra_fields() {
+  $extra['user']['user'] = array(
+    'form' => array(
+      'mimemail' => array(
+        'label' => t('Email'),
+        'description' => t('Mime Mail module settings form elements.'),
+        'weight' => 0,
+      ),
+    ),
+    'display' => array(
+      'mimemail' => array(
+        'label' => t('Email'),
+        'description' => t('Mime Mail module settings form elements.'),
+        'weight' => 0,
+      ),
+    ),
+  );
+
+  return $extra;
+}
+
+/**
+ * Implements hook_user_view().
+ */
+function mimemail_user_view($account, $view_mode, $langcode) {
+  $account->content['mimemail'] = array(
+    '#type' => 'user_profile_category',
+    '#title' => t('Email'),
+  );
+
+  $account->content['mimemail']['textonly'] = array(
+    '#type' => 'user_profile_item',
+    '#title' => t('Plaintext email only'),
+    '#markup' => empty($account->data['mimemail_textonly']) ? t('No') : t('Yes'),
+  );
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Adds the Mime Mail settings on the user settings page.
+ */
+function mimemail_form_user_profile_form_alter(&$form, &$form_state) {
+  if ($form['#user_category'] == 'account') {
+    $account = $form['#user'];
+    $form['mimemail'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Email settings'),
+      '#weight' => 5,
+      '#collapsible' => TRUE,
+      '#access' => user_access('edit mimemail user settings'),
+    );
+    $form['mimemail']['mimemail_textonly'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Plaintext email only'),
+      '#default_value' => !empty($account->data['mimemail_textonly']) ? $account->data['mimemail_textonly'] : FALSE,
+      '#description' => t('Check this option if you do not wish to receive email messages with graphics and styles.'),
+    );
+  }
+}
+
+/**
+ * Implements hook_user_presave().
+ */
+function mimemail_user_presave(&$edit, $account, $category) {
+  $edit['data']['mimemail_textonly'] = isset($edit['mimemail_textonly']) ? $edit['mimemail_textonly'] : 0;
+}
+
+/**
+ * Implements hook_theme().
+ */
+function mimemail_theme() {
+  module_load_include('inc', 'mimemail', 'theme/mimemail.theme');
+  return mimemail_theme_theme();
+}
+
+/**
+ * Implements hook_mail().
+ */
+function mimemail_mail($key, &$message, $params) {
+  $context = $params['context'];
+  $options = array('clear' => TRUE);
+
+  // Prepare the array of the attachments.
+  $attachments = array();
+  $attachments_string = trim($params['attachments']);
+  if (!empty($attachments_string)) {
+    $attachment_lines = array_filter(explode("\n", trim($attachments_string)));
+    foreach ($attachment_lines as $filepath) {
+      $attachments[] = array(
+        'filepath' => trim($filepath),
+      );
+    }
+  }
+
+  // We handle different address headers if set.
+  $address_headers = array(
+    'cc' => 'Cc',
+    'bcc' => 'Bcc',
+    'reply-to' => 'Reply-to',
+    'list-unsubscribe' => 'List-Unsubscribe',
+  );
+  foreach ($address_headers as $param_key => $address_header) {
+    $params[$param_key] = empty($params[$param_key]) ? array() : explode(',', $params[$param_key]);
+    if (!empty($params[$param_key])) {
+      foreach ($params[$param_key] as $key => $address) {
+        $params[$param_key][$key] = token_replace($address, $context, $options);
+      }
+      $message['headers'][$address_header] = implode(',', $params[$param_key]);
+    }
+  }
+
+  $message['to'] = token_replace($message['to'], $context, $options);
+  $message['subject'] = token_replace($context['subject'], $context, $options);
+  $message['body'][] = token_replace($context['body'], $context, $options);
+  $message['params']['plaintext'] = token_replace($params['plaintext'], $context, $options);
+  $message['params']['attachments'] = $attachments;
+}
+
+/**
+ * Retreives a list of all available mailer engines.
+ *
+ * @return array
+ *   Mailer engine names.
+ */
+function mimemail_get_engines() {
+  $engines = array();
+  foreach (module_implements('mailengine') as $module) {
+    $engines[$module] = module_invoke($module, 'mailengine', 'list');
+  }
+  return $engines;
+}
+
+/**
+ * Implements hook_mailengine().
+ *
+ * @param string $op
+ *   The operation to perform on the message.
+ * @param array $message
+ *   The message to perform the operation on.
+ *
+ * @return boolean
+ *   Returns TRUE if the operation was successful or FALSE if it was not.
+ */
+function mimemail_mailengine($op, $message = array()) {
+  module_load_include('inc', 'mimemail');
+
+  switch ($op) {
+    case 'list':
+      $engine = array(
+        'name' => t('Mime Mail'),
+        'description' => t("Default mailing engine."),
+      );
+      return $engine;
+    case 'settings':
+      // Not implemented.
+      break;
+    case 'multiple':
+    case 'single':
+    case 'send':
+      // Default values.
+      $default = array(
+        'to' => '',
+        'subject' => '',
+        'body' => '',
+        'from' => '',
+        'headers' => ''
+      );
+      $message = array_merge($default, $message);
+
+      // If 'Return-Path' isn't already set in php.ini, we pass it separately
+      // as an additional parameter instead of in the header.
+      // However, if PHP's 'safe_mode' is on, this is not allowed.
+      if (isset($message['headers']['Return-Path']) && !ini_get('safe_mode')) {
+        $return_path_set = strpos(ini_get('sendmail_path'), ' -f');
+        if (!$return_path_set) {
+          $return_path = trim($message['headers']['Return-Path'], '<>');
+          unset($message['headers']['Return-Path']);
+        }
+      }
+
+      $crlf = variable_get('mimemail_crlf', MAIL_LINE_ENDINGS);
+
+      $recipients = (!is_array($message['to'])) ? array($message['to']) : $message['to'];
+      $subject = mime_header_encode($message['subject']);
+      $body = preg_replace('@\r?\n@', $crlf, $message['body']);
+      $headers = mimemail_rfc_headers($message['headers']);
+
+      $result = TRUE;
+      foreach ($recipients as $to) {
+        if (isset($return_path) && !empty($return_path)) {
+          if (isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') !== FALSE) {
+            // On Windows, PHP will use the value of sendmail_from for the
+            // Return-Path header.
+            $old_from = ini_get('sendmail_from');
+            ini_set('sendmail_from', $return_path);
+            $result = @mail($to, $subject, $body, $headers) && $result;
+            ini_set('sendmail_from', $old_from);
+          }
+          else {
+            // On most non-Windows systems, the "-f" option to the sendmail command
+            // is used to set the Return-Path.
+            $result = @mail($to, $subject, $body, $headers, '-f' . $return_path) && $result;
+          }
+        }
+        else {
+          // The optional $additional_parameters argument to mail() is not allowed
+          // if safe_mode is enabled. Passing any value throws a PHP warning and
+          // makes mail() return FALSE.
+          $result = @mail($to, $subject, $body, $headers) && $result;
+        }
+      }
+
+      return $result;
+  }
+
+  return FALSE;
+}
+
+/**
+ * Prepares the message for sending.
+ *
+ * @param array $message
+ *   An array containing the message data. The optional parameters are:
+ *   - plain: Whether to send the message as plaintext only or HTML. If evaluates to TRUE,
+ *     then the message will be sent as plaintext.
+ *   - plaintext: Optional plaintext portion of a multipart email.
+ *   - attachments: An array of arrays which describe one or more attachments.
+ *     Existing files can be added by path, dinamically-generated files
+ *     can be added by content. The internal array contains the following elements:
+ *      - filepath: Relative Drupal path to an existing file (filecontent is NULL).
+ *      - filecontent: The actual content of the file (filepath is NULL).
+ *      - filename: The filename of the file.
+ *      - filemime: The MIME type of the file.
+ *      The array of arrays looks something like this:
+ *      Array
+ *      (
+ *        [0] => Array
+ *        (
+ *         [filepath] => '/sites/default/files/attachment.txt'
+ *         [filecontent] => 'My attachment.'
+ *         [filename] => 'attachment.txt'
+ *         [filemime] => 'text/plain'
+ *        )
+ *      )
+ *
+ * @return array
+ *   All details of the message.
+ */
+function mimemail_prepare_message($message) {
+  module_load_include('inc', 'mimemail');
+
+  $module = $message['module'];
+  $key = $message['key'];
+  $to = $message['to'];
+  $from = $message['from'];
+  $subject = $message['subject'];
+  $body = $message['body'];
+
+  $headers = isset($message['params']['headers']) ? $message['params']['headers'] : array();
+  $plain = isset($message['params']['plain']) ? $message['params']['plain'] : NULL;
+  $plaintext = isset($message['params']['plaintext']) ? $message['params']['plaintext'] : NULL;
+  $attachments = isset($message['params']['attachments']) ? $message['params']['attachments'] : array();
+
+  $site_name = variable_get('site_name', 'Drupal');
+  $site_mail = variable_get('site_mail', ini_get('sendmail_from'));
+  $simple_address = variable_get('mimemail_simple_address', 0);
+
+  // Override site mails default sender when using default engine.
+  if ((empty($from) || $from == $site_mail)
+      && variable_get('mimemail_engine', 'mimemail') == 'mimemail') {
+    $mimemail_name = variable_get('mimemail_name', $site_name);
+    $mimemail_mail = variable_get('mimemail_mail', $site_mail);
+    $from = array(
+      'name' => !empty($mimemail_name) ? $mimemail_name : $site_name,
+      'mail' => !empty($mimemail_mail) ? $mimemail_mail : $site_mail,
+    );
+  }
+
+  // Body is empty, this is a plaintext message.
+  if (empty($body)) {
+    $plain = TRUE;
+  }
+  // Try to determine recipient's text mail preference.
+  elseif (is_null($plain)) {
+    if (is_object($to) && isset($to->data['mimemail_textonly'])) {
+      $plain = $to->data['mimemail_textonly'];
+    }
+    elseif (is_string($to) && valid_email_address($to)) {
+      if (is_object($account = user_load_by_mail($to)) && isset($account->data['mimemail_textonly'])) {
+        $plain = $account->data['mimemail_textonly'];
+        // Might as well pass the user object to the address function.
+        $to = $account;
+      }
+    }
+  }
+
+  // Removing newline character introduced by _drupal_wrap_mail_line();
+  $subject = str_replace(array("\n"), '', trim(drupal_html_to_text($subject)));
+
+  $hook = array(
+    'mimemail_message__' . $key,
+    'mimemail_message__' . $module .'__'. $key,
+  );
+
+  $variables = array(
+    'module' => $module,
+    'key' => $key,
+    'recipient' => $to,
+    'subject' => $subject,
+    'body' => $body
+  );
+
+  $body = theme($hook, $variables);
+
+  foreach (module_implements('mail_post_process') as $module) {
+    $function = $module . '_mail_post_process';
+    $function($body, $key);
+  }
+
+  $plain = $plain || variable_get('mimemail_textonly', 0);
+  $from = mimemail_address($from);
+  $mail = mimemail_html_body($body, $subject, $plain, $plaintext, $attachments);
+  $headers = array_merge($message['headers'], $headers, $mail['headers']);
+
+  $message['to'] = mimemail_address($to, $simple_address);
+  $message['from'] = $from;
+  $message['subject'] = $subject;
+  $message['body'] = $mail['body'];
+  $message['headers'] = mimemail_headers($headers, $from);
+
+  return $message;
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/mimemail.rules.inc b/profiles/wcm_base/modules/contrib/mimemail/mimemail.rules.inc
new file mode 100644
index 0000000000000000000000000000000000000000..29a6dee5ccccd09a54a715f7e9ec4fed7d862b8c
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/mimemail.rules.inc
@@ -0,0 +1,360 @@
+<?php
+
+/**
+ * @file
+ * Rules actions for sending Mime-encoded emails.
+ *
+ * @addtogroup rules
+ * @{
+ */
+
+/**
+ * Implements hook_rules_action_info().
+ */
+function mimemail_rules_action_info() {
+  return array(
+    'mimemail' => array(
+      'label' => t('Send HTML e-mail'),
+      'group' => t('System'),
+      'parameter' => array(
+        'key' => array(
+          'type' => 'text',
+          'label' => t('Key'),
+          'description' => t('A key to identify the e-mail sent.'),
+        ),
+        'to' => array(
+          'type' => 'text',
+          'label' => t('To'),
+          'description' => t("The mail's recipient address. The formatting of this string must comply with RFC 2822."),
+        ),
+        'cc' => array(
+          'type' => 'text',
+          'label' => t('CC Recipient'),
+          'description' => t("The mail's carbon copy address. You may separate multiple addresses with comma."),
+          'optional' => TRUE,
+        ),
+        'bcc' => array(
+          'type' => 'text',
+          'label' => t('BCC Recipient'),
+          'description' => t("The mail's blind carbon copy address. You may separate multiple addresses with comma."),
+          'optional' => TRUE,
+        ),
+        'from_name' => array(
+          'type' => 'text',
+          'label' => t('Sender name'),
+          'description' => t("The sender's name. Leave it empty to use the site-wide configured name."),
+          'optional' => TRUE,
+        ),
+        'from_mail' => array(
+          'type' => 'text',
+          'label' => t('Sender e-mail address'),
+          'description' => t("The sender's address. Leave it empty to use the site-wide configured address."),
+          'optional' => TRUE,
+        ),
+        'reply_to' => array(
+          'type' => 'text',
+          'label' => t('Reply e-mail address'),
+          'description' => t("The address to reply to. Leave it empty to use the sender's address."),
+          'optional' => TRUE,
+        ),
+        'list_unsubscribe' => array(
+          'type' => 'text',
+          'label' => t('Unsubscription e-mail and/or URL'),
+          'description' => t("An e-mail address and/or a URL which can be used for unsubscription. Values must be enclosed by angel brackets and separated by a comma."),
+          'optional' => TRUE,
+        ),
+        'subject' => array(
+          'type' => 'text',
+          'label' => t('Subject'),
+          'description' => t("The mail's subject."),
+          'translatable' => TRUE,
+        ),
+        'body' => array(
+          'type' => 'text',
+          'label' => t('Body'),
+          'description' => t('The mail\'s HTML body. Will be formatted using the text format selected on the <a href="@url">settings</a> page.', array('@url' => url('admin/config/system/mimemail'))),
+          'sanitize' => TRUE,
+          'optional' => TRUE,
+          'translatable' => TRUE,
+        ),
+        'plaintext' => array(
+          'type' => 'text',
+          'label' => t('Plain text body'),
+          'description' => t("The mail's plaintext body."),
+          'optional' => TRUE,
+          'translatable' => TRUE,
+        ),
+        'attachments' => array(
+          'type' => 'text',
+          'label' => t('Attachments'),
+          'description' => t("The mail's attachments, one file per line e.g. \"files/images/mypic.png\" without quotes."),
+          'optional' => TRUE,
+        ),
+        'language' => array(
+          'type' => 'token',
+          'label' => t('Language'),
+          'description' => t('If specified, the language used for getting the mail message and subject.'),
+          'options list' => 'entity_metadata_language_list',
+          'optional' => TRUE,
+          'default value' => LANGUAGE_NONE,
+          'default mode' => 'selector',
+        ),
+      ),
+      'base' => 'rules_action_mimemail',
+      'access callback' => 'rules_system_integration_access',
+    ),
+    'mimemail_to_users_of_role' => array(
+      'label' => t('Send HTML mail to all users of a role'),
+      'group' => t('System'),
+      'parameter' => array(
+        'key' => array(
+          'type' => 'text',
+          'label' => t('Key'),
+          'description' => t('A key to identify the e-mail sent.'),
+        ),
+        'roles' => array(
+          'type' => 'list<integer>',
+          'label' => t('Roles'),
+          'options list' => 'entity_metadata_user_roles',
+          'description' => t('Select the roles whose users should receive the mail.'),
+        ),
+        'active' => array(
+          'type' => 'boolean',
+          'label' =>('Send to active users'),
+          'description' => t('Send mail only to active users.'),
+        ),
+        'from_name' => array(
+          'type' => 'text',
+          'label' => t('Sender name'),
+          'description' => t("The sender's name. Leave it empty to use the site-wide configured name."),
+          'optional' => TRUE,
+        ),
+        'from_mail' => array(
+          'type' => 'text',
+          'label' => t('Sender e-mail address'),
+          'description' => t("The sender's address. Leave it empty to use the site-wide configured address."),
+          'optional' => TRUE,
+        ),
+        'subject' => array(
+          'type' => 'text',
+          'label' => t('Subject'),
+          'description' => t("The mail's subject."),
+          'translatable' => TRUE,
+        ),
+        'body' => array(
+          'type' => 'text',
+          'label' => t('Body'),
+          'description' => t("The mail's message HTML body."),
+          'optional' => TRUE,
+          'translatable' => TRUE,
+        ),
+        'plaintext' => array(
+          'type' => 'text',
+          'label' => t('Plaintext body'),
+          'description' => t("The mail's message plaintext body."),
+          'optional' => TRUE,
+          'translatable' => TRUE,
+        ),
+        'attachments' => array(
+          'type' => 'text',
+          'label' => t('Attachments'),
+          'description' => t("The mail's attachments, one file per line e.g. \"files/images/mypic.png\" without quotes."),
+          'optional' => TRUE,
+        ),
+        'language_user' => array(
+          'type' => 'boolean',
+          'label' => t("Send mail in each recipient's language"),
+          'description' => t("If checked, the mail message and subject will be sent in each user's preferred language. <strong>You can safely leave the language selector below empty if this option is selected.</strong>"),
+        ),
+        'language' => array(
+          'type' => 'token',
+          'label' => t('Fixed language'),
+          'description' => t('If specified, the fixed language used for getting the mail message and subject.'),
+          'options list' => 'entity_metadata_language_list',
+          'optional' => TRUE,
+          'default value' => LANGUAGE_NONE,
+          'default mode' => 'selector',
+        ),
+      ),
+      'base' => 'rules_action_mimemail_to_users_of_role',
+      'access callback' => 'rules_system_integration_access',
+    ),
+  );
+}
+
+/**
+ * Implements hook_rules_action_base_upgrade_map_name().
+ */
+function mimemail_rules_action_mail_upgrade_map_name($element) {
+  return 'mimemail';
+}
+
+/**
+ * Implements hook_rules_action_base_upgrade_map_name().
+ */
+function mimemail_rules_action_mail_to_user_upgrade_map_name($element) {
+  return 'mimemail';
+}
+
+/**
+ * Implements hook_rules_action_base_upgrade_map_name().
+ */
+function mimemail_rules_action_mail_to_users_of_role_upgrade_map_name($element) {
+  return 'mimemail_to_users_of_role';
+}
+
+/**
+ * Implements hook_rules_action_base_upgrade().
+ */
+function mimemail_rules_action_mail_upgrade($element, RulesPlugin $target) {
+  $target->settings['key'] = $element['#settings']['key'];
+  $target->settings['from_name'] = $element['#settings']['sender'];
+  $target->settings['from_mail'] = $element['#settings']['from'];
+  $target->settings['body'] = $element['#settings']['message_html'];
+  $target->settings['plaintext'] = $element['#settings']['message_plaintext'];
+}
+
+/**
+ * Implements hook_rules_action_base_upgrade().
+ */
+function mimemail_rules_action_mail_to_user_upgrade($element, RulesPlugin $target) {
+  switch ($element['#settings']['#argument map']['user']) {
+    case 'author':
+      $token = 'node:author';
+      break;
+    case 'author_unchanged':
+      $token = 'node-unchanged:author';
+      break;
+    case 'user':
+      $token = 'site:current-user';
+      break;
+  }
+  $target->settings['to:select'] = $token . ':mail';
+  mimemail_rules_action_mail_upgrade($element, $target);
+}
+
+/**
+ * Implements hook_rules_action_base_upgrade().
+ */
+function mimemail_rules_action_mail_to_users_of_role_upgrade($element, RulesPlugin $target) {
+  $target->settings['roles'] = $element['#settings']['recipients'];
+  mimemail_rules_action_mail_upgrade($element, $target);
+}
+
+/**
+ * Action Implementation: Send HTML mail.
+ */
+function rules_action_mimemail($key, $to, $cc = NULL, $bcc = NULL, $from_name = NULL, $from_mail = NULL, $reply_to = NULL, $list_unsubscribe = NULL, $subject, $body, $plaintext = NULL, $attachments = array(), $langcode, $settings, RulesState $state, RulesPlugin $element) {
+  module_load_include('inc', 'mimemail');
+
+  // Set the sender name and from address.
+  if (empty($from_mail)) {
+    $from = NULL;
+  }
+  else {
+    $from = array(
+      'name' => $from_name,
+      'mail' => $from_mail,
+    );
+    // Create an address string.
+    $from = mimemail_address($from);
+  }
+
+  // Figure out the language to use - fallback is the system default.
+  $languages = language_list();
+  $language = isset($languages[$langcode]) ? $languages[$langcode] : language_default();
+
+  $params = array(
+    'context' => array(
+      'subject' => $subject,
+      'body' => $body,
+      'action' => $element,
+      'state' => $state,
+    ),
+    'cc' => $cc,
+    'bcc' => $bcc,
+    'reply-to' => $reply_to,
+    'list-unsubscribe' => $list_unsubscribe,
+    'plaintext' => $plaintext,
+    'attachments' => $attachments,
+  );
+
+  drupal_mail('mimemail', $key, $to, $language, $params, $from);
+}
+
+/**
+ * Action: Send HTML mail to all users of a specific role group(s).
+ */
+function rules_action_mimemail_to_users_of_role($key, $roles, $active, $from_name = NULL, $from_mail = NULL, $subject, $body, $plaintext = NULL, $attachments = array(), $use_userlang = FALSE, $langcode= NULL, $settings, RulesState $state, RulesPlugin $element) {
+  module_load_include('inc', 'mimemail');
+
+  // Set the sender name and from address.
+  if (empty($from_mail)) {
+    $from = NULL;
+  }
+  else {
+    $from = array(
+      'name' => $from_name,
+      'mail' => $from_mail,
+    );
+    // Create an address string.
+    $from = mimemail_address($from);
+  }
+
+  $query = db_select('users', 'u');
+  $query->fields('u', array('mail', 'language'));
+
+  if ($active) {
+    $query->condition('u.status', 1, '=');
+  }
+
+  if (in_array(DRUPAL_AUTHENTICATED_RID, $roles)) {
+    $query->condition('u.uid', 0, '>');
+  }
+  else {
+    $query->join('users_roles', 'r', 'u.uid = r.uid');
+    $query->condition('r.rid', $roles, 'IN');
+    $query->distinct();
+  }
+
+  $result = $query->execute();
+
+  $params = array(
+    'context' => array(
+      'subject' => $subject,
+      'body' => $body,
+      'action' => $element,
+      'state' => $state,
+    ),
+    'plaintext' => $plaintext,
+    'attachments' => $attachments,
+  );
+
+  // Create language list before initializing foreach.
+  $languages = language_list();
+
+  $message = array('result' => TRUE);
+  foreach ($result as $row) {
+    // Decide which language to use.
+    if (!$use_userlang || empty($row->language) || !isset($languages[$row->language])) {
+      $language = isset($languages[$langcode]) ? $languages[$langcode] : language_default();
+    }
+    else {
+      $language = $languages[$row->language];
+    }
+
+    $message = drupal_mail('mimemail', $key, $row->mail, $language, $params, $from);
+    if (!$message['result']) {
+      break;
+    }
+  }
+  if ($message['result']) {
+    $role_names = array_intersect_key(user_roles(TRUE), array_flip($roles));
+    watchdog('rules', 'Successfully sent HTML email to the role(s) %roles.', array('%roles' => implode(', ', $role_names)));
+  }
+}
+
+/**
+ * @}
+ */
+
diff --git a/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_action/mimemail_action.info b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_action/mimemail_action.info
new file mode 100644
index 0000000000000000000000000000000000000000..e6ede6a841136a15d2c821fe68983f77f0425b70
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_action/mimemail_action.info
@@ -0,0 +1,14 @@
+name = "Mime Mail Action"
+description = "Provide actions for Mime Mail."
+package = Mail
+dependencies[] = mimemail
+dependencies[] = trigger
+core = 7.x
+
+
+; Information added by Drupal.org packaging script on 2015-08-02
+version = "7.x-1.0-beta4"
+core = "7.x"
+project = "mimemail"
+datestamp = "1438530555"
+
diff --git a/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_action/mimemail_action.module b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_action/mimemail_action.module
new file mode 100644
index 0000000000000000000000000000000000000000..5ad51d61b50ca10e6deef25f070da9452a8eeb42
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_action/mimemail_action.module
@@ -0,0 +1,197 @@
+<?php
+
+/**
+ * @file
+ * Provide actions for Mime Mail.
+ */
+
+/**
+ * Implements hook_action_info().
+ */
+function mimemail_action_info() {
+  return array(
+    'mimemail_send_email_action' => array(
+      'type' => 'system',
+      'label' => t('Send HTML e-mail'),
+      'configurable' => TRUE,
+      'triggers' => array('any'),
+    ),
+  );
+}
+
+/**
+ * Implements a configurable Drupal action. Sends an email.
+ */
+function mimemail_send_email_action($entity, $context) {
+  if (empty($context['node'])) {
+    if (get_class($entity) == 'OgMembership') {
+      $context['user'] = user_load($entity->etid);
+    } else {
+      $context['node'] = $entity;
+    }
+  }
+
+  $to = token_replace($context['to'], $context);
+
+  // If the recipient is a registered user with a language preference, use
+  // the recipient's preferred language. Otherwise, use the system default
+  // language.
+  $account = user_load_by_mail($to);
+  if ($account) {
+    $language = user_preferred_language($account);
+  }
+  else {
+    $language = language_default();
+  }
+
+  $params = array(
+    'context' => array(
+      'subject' => token_replace($context['subject'], $context),
+      'body' => token_replace($context['body'], $context),
+    ),
+    'key' => $context['key'],
+    'cc' => $context['cc'],
+    'bcc' => $context['bcc'],
+    'reply-to' => $context['reply-to'],
+    'plaintext' => token_replace($context['plaintext'], $context),
+    'attachments' => $context['attachments'],
+  );
+
+  drupal_mail('mimemail', $context['key'], $to, $language, $params);
+}
+
+/**
+ * Form for configurable Drupal action to send an HTML mail.
+ */
+function mimemail_send_email_action_form($context) {
+  $context += array(
+    'key' => '',
+    'to' => '',
+    'cc' => '',
+    'bcc' => '',
+    'reply-to' => '',
+    'subject' => '',
+    'body' => '',
+    'format' => filter_fallback_format(),
+    'plaintext' => '',
+    'attachments' => ''
+  );
+
+  $form['key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Key'),
+    '#default_value' => $context['key'],
+    '#description' => t('A key to identify the e-mail sent.'),
+    '#required' => TRUE,
+  );
+  $form['to'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Recipient'),
+    '#default_value' => $context['to'],
+    '#maxlength' => 254,
+    '#description' => t('The email address to which the message should be sent OR enter [node:author:mail], [comment:author:mail], etc. if you would like to send an e-mail to the author of the original post.'),
+    '#required' => TRUE,
+  );
+  $form['cc'] = array(
+    '#type' => 'textfield',
+    '#title' => t('CC Recipient'),
+    '#default_value' => $context['cc'],
+    '#description' => t("The mail's carbon copy address. You may separate multiple addresses with comma."),
+    '#required' => FALSE,
+  );
+  $form['bcc'] = array(
+    '#type' => 'textfield',
+    '#title' => t('BCC Recipient'),
+    '#default_value' => $context['bcc'],
+    '#description' => t("The mail's blind carbon copy address. You may separate multiple addresses with comma."),
+    '#required' => FALSE,
+  );
+  $form['reply-to'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Reply e-mail address'),
+    '#default_value' => $context['reply-to'],
+    '#description' => t("The address to reply to. Leave it empty to use the sender's address."),
+    '#required' => FALSE,
+  );
+  $form['subject'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Subject'),
+    '#maxlength' => 254,
+    '#default_value' => $context['subject'],
+    '#description' => t("The subject of the message."),
+  );
+  $form['body'] = array(
+    '#type' => 'text_format',
+    '#title' => t('Body'),
+    '#default_value' => $context['body'],
+    '#format' => $context['format'],
+    '#description' => t('The HTML message that should be sent. You may include placeholders like [node:title], [user:name], and [comment:body] to represent data that will be different each time message is sent. Not all placeholders will be available in all contexts.'),
+  );
+  $form['plaintext'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Plain text body'),
+    '#default_value' => $context['plaintext'],
+    '#description' => t('Optional plaintext portion of a multipart message. You may include placeholders like [node:title], [user:name], and [comment:body] to represent data that will be different each time message is sent. Not all placeholders will be available in all contexts.'),
+  );
+  $form['attachments'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Attachments'),
+    '#default_value' => $context['attachments'],
+    '#description' => t('A list of attachments, one file per line e.g. "files/images/mypic.png" without quotes.'),
+  );
+
+  return $form;
+}
+
+/**
+ * Validate the action form.
+ */
+function mimemail_send_email_action_validate($form, $form_state) {
+  $to = trim($form_state['values']['to']);
+  if (!valid_email_address($to) && strpos($to, ':mail') === FALSE) {
+    form_set_error('to', t('Enter a valid email address or use a token e-mail address such as %author.', array('%author' => '[node:author:mail]')));
+  }
+
+  $cc = explode(',', $form_state['values']['cc']);
+  foreach ($cc as $recipient) {
+    $recipient = trim($recipient);
+    if (!empty($recipient) && !valid_email_address($recipient) && strpos($recipient, ':mail') === FALSE) {
+      form_set_error('cc', t('Enter a valid email address or use a token e-mail address such as %author.', array('%author' => '[node:author:mail]')));
+    }
+  }
+
+  $bcc = explode(',', $form_state['values']['bcc']);
+  foreach ($bcc as $recipient) {
+    $recipient = trim($recipient);
+    if (!empty($recipient) && !valid_email_address($recipient) && strpos($recipient, ':mail') === FALSE) {
+      form_set_error('bcc', t('Enter a valid email address or use a token e-mail address such as %author.', array('%author' => '[node:author:mail]')));
+    }
+  }
+
+  $reply_to = trim($form_state['values']['reply-to']);
+  if (!empty($reply_to) && !valid_email_address($reply_to) && strpos($reply_to, ':mail') === FALSE) {
+    form_set_error('reply-to', t('Enter a valid email address or use a token e-mail address such as %author.', array('%author' => '[node:author:mail]')));
+  }
+}
+
+/**
+ * Handle submission of the action form.
+ */
+function mimemail_send_email_action_submit($form, $form_state) {
+  $form_values = $form_state['values'];
+
+  $params = array(
+    'key' => $form_values['key'],
+    'to' => $form_values['to'],
+    'cc' => $form_values['cc'],
+    'bcc' => $form_values['bcc'],
+    'reply-to' => $form_values['reply-to'],
+    'subject' => $form_values['subject'],
+    'body' => $form_values['body']['value'],
+    'format' => $form_values['body']['format'],
+    'plaintext' => $form_values['plaintext'],
+    'attachments' => $form_values['attachments'],
+  );
+
+  return $params;
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.inc b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.inc
new file mode 100644
index 0000000000000000000000000000000000000000..dcf3f0aa9a8319b3cdc7a24cd5cce46ff18e3ba0
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.inc
@@ -0,0 +1,267 @@
+<?php
+
+/**
+ * @file
+ * Converts CSS styles into inline style attributes.
+ *
+ * Code based on Emogrifier by Pelago Design (http://www.pelagodesign.com).
+ */
+
+/**
+ * Separate CSS from HTML for processing
+ */
+function mimemail_compress_clean_message($message) {
+  $parts = array();
+  preg_match('|(<style[^>]+)>(.*)</style>|mis', $message, $matches);
+  if (isset($matches[0]) && isset($matches[2])) {
+    $css = str_replace('<!--', '', $matches[2]);
+    $css = str_replace('-->', '', $css);
+    $css = preg_replace('|\{|', "\n{\n", $css);
+    $css = preg_replace('|\}|', "\n}\n", $css);
+    $html = str_replace($matches[0], '', $message);
+    $parts = array('html' => $html, 'css' => $css);
+  }
+  return $parts;
+}
+
+/**
+ * Compress HTML and CSS into combined message
+ */
+class mimemail_compress {
+  private $html = '';
+  private $css = '';
+  private $unprocessable_tags = array('wbr');
+
+  public function mimemail_compress($html = '', $css = '') {
+    $this->html = $html;
+    $this->css  = $css;
+  }
+
+  // There are some HTML tags that DOMDocument cannot process,
+  // and will throw an error if it encounters them.
+  // These functions allow you to add/remove them if necessary.
+  // It only strips them from the code (does not remove actual nodes).
+  public function add_unprocessable_tag($tag) {
+    $this->unprocessable_tags[] = $tag;
+  }
+
+  public function remove_unprocessable_tag($tag) {
+    if (($key = array_search($tag, $this->unprocessable_tags)) !== FALSE) {
+      unset($this->unprocessableHTMLTags[$key]);
+    }
+  }
+
+  public function compress() {
+    if (!class_exists('DOMDocument', FALSE)) {
+      return $this->html;
+    }
+
+    $body = $this->html;
+    // Process the CSS here, turning the CSS style blocks into inline CSS.
+    if (count($this->unprocessable_tags)) {
+      $unprocessable_tags = implode('|', $this->unprocessable_tags);
+      $body = preg_replace("/<($unprocessable_tags)[^>]*>/i", '', $body);
+    }
+
+    $err = error_reporting(0);
+    $doc = new DOMDocument();
+
+    // Try to set character encoding.
+    if (function_exists('mb_convert_encoding')) {
+      $body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8");
+      $doc->encoding= "UTF-8";
+    }
+
+    $doc->strictErrorChecking = FALSE;
+    $doc->formatOutput = TRUE;
+    $doc->loadHTML($body);
+    $doc->normalizeDocument();
+
+    $xpath = new DOMXPath($doc);
+
+    // Get rid of comments.
+    $css = preg_replace('/\/\*.*\*\//sU', '', $this->css);
+
+    // Process the CSS file for selectors and definitions.
+    preg_match_all('/^\s*([^{]+){([^}]+)}/mis', $css, $matches);
+
+    $all_selectors = array();
+    foreach ($matches[1] as $key => $selector_string) {
+      // If there is a blank definition, skip.
+      if (!strlen(trim($matches[2][$key]))) continue;
+      // Else split by commas and duplicate attributes so we can sort by selector precedence.
+      $selectors = explode(',', $selector_string);
+      foreach ($selectors as $selector) {
+        // Don't process pseudo-classes.
+        if (strpos($selector, ':') !== FALSE) continue;
+        $all_selectors[] = array(
+          'selector' => $selector,
+          'attributes' => $matches[2][$key],
+          'index' => $key, // Keep track of where it appears in the file, since order is important.
+        );
+      }
+    }
+
+    // Now sort the selectors by precedence.
+    usort($all_selectors, array('self', 'sort_selector_precedence'));
+
+    // Before we begin processing the CSS file, parse the document for inline
+    // styles and append the normalized properties (i.e., 'display: none'
+    // instead of 'DISPLAY: none') as selectors with full paths (highest
+    // precedence), so they override any file-based selectors.
+    $nodes = @$xpath->query('//*[@style]');
+    if ($nodes->length > 0) {
+      foreach ($nodes as $node) {
+        $style = preg_replace_callback('/[A-z\-]+(?=\:)/S', create_function('$matches', 'return strtolower($matches[0]);'), $node->getAttribute('style'));
+        $all_selectors[] = array(
+          'selector' => $this->calculateXPath($node),
+          'attributes' => $style,
+        );
+      }
+    }
+
+    foreach ($all_selectors as $value) {
+      // Query the body for the xpath selector.
+      $nodes = $xpath->query($this->css_to_xpath(trim($value['selector'])));
+
+      foreach ($nodes as $node) {
+        // If it has a style attribute, get it, process it, and append (overwrite) new stuff.
+        if ($node->hasAttribute('style')) {
+          // Break it up into an associative array.
+          $old_style = $this->css_style_to_array($node->getAttribute('style'));
+          $new_style = $this->css_style_to_array($value['attributes']);
+          // New styles overwrite the old styles (not technically accurate, but close enough).
+          $compressed = array_merge($old_style, $new_style);
+          $style = '';
+          foreach ($compressed as $k => $v) {
+            $style .= (drupal_strtolower($k) . ':' . $v . ';');
+          }
+        }
+        else {
+          // Otherwise create a new style.
+          $style = trim($value['attributes']);
+        }
+        $node->setAttribute('style', $style);
+
+        // Convert float to align for images.
+        $float = preg_match ('/float:(left|right)/', $style, $matches);
+        if ($node->nodeName == 'img' && $float) {
+          $node->setAttribute('align', $matches[1]);
+          $node->setAttribute('vspace', 5);
+          $node->setAttribute('hspace', 5);
+        }
+      }
+    }
+
+    // This removes styles from your email that contain display:none. You could comment these out if you want.
+    $nodes = $xpath->query('//*[contains(translate(@style," ",""), "display:none")]');
+    foreach ($nodes as $node) {
+      $node->parentNode->removeChild($node);
+    }
+
+    if (variable_get('mimemail_preserve_class', 0) == FALSE) {
+      $nodes = $xpath->query('//*[@class]');
+      foreach ($nodes as $node) {
+        $node->removeAttribute('class');
+      }
+    }
+
+    error_reporting($err);
+
+    return $doc->saveHTML();
+  }
+
+  private static function sort_selector_precedence($a, $b) {
+    $precedenceA = self::get_selector_precedence($a['selector']);
+    $precedenceB = self::get_selector_precedence($b['selector']);
+
+    // We want these sorted ascendingly so selectors with lesser precedence get processed first and selectors with greater precedence get sorted last.
+    return ($precedenceA == $precedenceB) ? ($a['index'] < $b['index'] ? -1 : 1) : ($precedenceA < $precedenceB ? -1 : 1);
+  }
+
+  private static function get_selector_precedence($selector) {
+    $precedence = 0;
+    $value = 100;
+    // Ids: worth 100, classes: worth 10, elements: worth 1.
+    $search = array('\#', '\.', '');
+
+    foreach ($search as $s) {
+      if (trim($selector == '')) break;
+      $num = 0;
+      $selector = preg_replace('/' . $s . '\w+/', '', $selector, -1, $num);
+      $precedence += ($value * $num);
+      $value /= 10;
+    }
+
+    return $precedence;
+  }
+
+  /**
+   * Right now we only support CSS 1 selectors, but include CSS2/3 selectors are fully possible.
+   *
+   * @see http://plasmasturm.org/log/444
+   */
+  private function css_to_xpath($selector) {
+    if (drupal_substr($selector, 0, 1) == '/') {
+      // Already an XPath expression.
+      return $selector;
+    }
+    // Returns an Xpath selector.
+    $search = array(
+      '/\s+>\s+/', // Matches any F element that is a child of an element E.
+      '/(\w+)\s+\+\s+(\w+)/', // Matches any F element that is a child of an element E.
+      '/\s+/', // Matches any F element that is a descendant of an E element.
+      '/(\w)\[(\w+)\]/', // Matches element with attribute.
+      '/(\w)\[(\w+)\=[\'"]?(\w+)[\'"]?\]/', // Matches element with EXACT attribute.
+      '/(\w+)?\#([\w\-]+)/e', // Matches id attributes.
+      '/(\w+|\*)?((\.[\w\-]+)+)/e', // Matches class attributes.
+    );
+    $replace = array(
+      '/',
+      '\\1/following-sibling::*[1]/self::\\2',
+      '//',
+      '\\1[@\\2]',
+      '\\1[@\\2="\\3"]',
+      "(strlen('\\1') ? '\\1' : '*').'[@id=\"\\2\"]'",
+      "(strlen('\\1') ? '\\1' : '*').'[contains(concat(\" \",normalize-space(@class),\" \"),concat(\" \",\"'.implode('\",\" \"))][contains(concat(\" \",normalize-space(@class),\" \"),concat(\" \",\"',explode('.',substr('\\2',1))).'\",\" \"))]'",
+    );
+    return '//' . preg_replace($search, $replace, trim($selector));
+  }
+
+  private function css_style_to_array($style) {
+    $definitions = explode(';', $style);
+    $css_styles = array();
+    foreach ($definitions as $def) {
+      if (empty($def) || strpos($def, ':') === FALSE) continue;
+      list($key, $value) = explode(':', $def, 2);
+      if (empty($key) || empty($value)) continue;
+      $css_styles[trim($key)] = trim($value);
+    }
+    return $css_styles;
+  }
+
+  /**
+   * Get the full path to a DOM node.
+   *
+   * @param DOMNode $node
+   *   The node to analyze.
+   *
+   * @return string
+   *   The full xpath to a DOM node.
+   *
+   * @see http://stackoverflow.com/questions/2643533/php-getting-xpath-of-a-domnode
+   */
+  function calculateXPath(DOMNode $node) {
+    $xpath = '';
+    $q = new DOMXPath($node->ownerDocument);
+
+    do {
+        $position = 1 + $q->query('preceding-sibling::*[name()="' . $node->nodeName . '"]', $node)->length;
+        $xpath = '/' . $node->nodeName . '[' . $position . ']' . $xpath;
+        $node = $node->parentNode;
+    }
+    while (!$node instanceof DOMDocument);
+
+    return $xpath;
+  }
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.info b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.info
new file mode 100644
index 0000000000000000000000000000000000000000..4733b2142853af012d4d9b3c91bfce4828acf975
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.info
@@ -0,0 +1,14 @@
+name = Mime Mail CSS Compressor
+description = Converts CSS to inline styles in an HTML message. (Requires the PHP DOM extension.)
+package = Mail
+dependencies[] = mimemail
+core = 7.x
+
+files[] = mimemail_compress.inc
+
+; Information added by Drupal.org packaging script on 2015-08-02
+version = "7.x-1.0-beta4"
+core = "7.x"
+project = "mimemail"
+datestamp = "1438530555"
+
diff --git a/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.install b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.install
new file mode 100644
index 0000000000000000000000000000000000000000..1e3bdc8d3e2bd8e7da5b50ff09534e1520b96809
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.install
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Install, update and uninstall functions for Mime Mail Compress module.
+ */
+
+/**
+ * Implements hook_requirements().
+ */
+function mimemail_compress_requirements($phase) {
+  $requirements = array();
+  // Ensure translations don't break at install time.
+  $t = get_t();
+
+  // Test PHP DOM extension.
+  if (extension_loaded('dom')) {
+    $requirements['dom']['value'] = $t('Enabled');
+  }
+  else {
+    $requirements['dom'] = array(
+      'description' => $t('Mime Mail Compress requires the PHP DOM extension to be enabled.'),
+      'severity' => REQUIREMENT_ERROR,
+      'value' => $t('Disabled'),
+    );
+  }
+
+  $requirements['dom']['title'] = $t('PHP DOM extension');
+
+  return $requirements;
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.module b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.module
new file mode 100644
index 0000000000000000000000000000000000000000..e538fc4311d254919f5fd4f1006e36b62aa9672c
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_compress/mimemail_compress.module
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Component module for sending Mime-encoded emails.
+ */
+
+/**
+ * Implements mail_post_process().
+ */
+function mimemail_compress_mail_post_process(&$message, $mailkey) {
+  module_load_include('inc', 'mimemail_compress');
+  // Separate CSS from HTML for processing.
+  $parts = mimemail_compress_clean_message($message);
+  // Compress HTML and CSS into combined message.
+  if (!empty($parts)) {
+    $output = new mimemail_compress($parts['html'], $parts['css']);
+    $output = $output->compress();
+    $message = $output;
+  }
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_example/mimemail_example.info b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_example/mimemail_example.info
new file mode 100644
index 0000000000000000000000000000000000000000..649bc3a6a90fbdfdff9541fac09169772df99252
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_example/mimemail_example.info
@@ -0,0 +1,12 @@
+name = Mime Mail Example
+description = Example of how to use the Mime Mail module.
+dependencies[] = mimemail
+package = Example modules
+core = 7.x
+
+; Information added by Drupal.org packaging script on 2015-08-02
+version = "7.x-1.0-beta4"
+core = "7.x"
+project = "mimemail"
+datestamp = "1438530555"
+
diff --git a/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_example/mimemail_example.install b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_example/mimemail_example.install
new file mode 100644
index 0000000000000000000000000000000000000000..4f06264082e82bfb1e43d70d26cd10ab8b051d72
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_example/mimemail_example.install
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Install, update and uninstall functions for Mime Mail Example module.
+ */
+
+/**
+ * Implements hook_enable().
+ */
+function mimemail_example_enable() {
+  mailsystem_set(array('mimemail_example' => 'MimeMailSystem'));
+}
+
+/**
+ * Implements hook_disable().
+ */
+function mimemail_example_disable() {
+  mailsystem_clear(array('mimemail_example' => 'MimeMailSystem'));
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_example/mimemail_example.module b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_example/mimemail_example.module
new file mode 100644
index 0000000000000000000000000000000000000000..85fe957d8a5b5e9f7589cfc0dc7cac3ef4509c13
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/modules/mimemail_example/mimemail_example.module
@@ -0,0 +1,170 @@
+<?php
+
+/**
+ * @file
+ * Core and contrib hook implementations for Mime Mail Example module.
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function mimemail_example_menu() {
+  $items['example/mimemail_example'] = array(
+    'title' => 'Mime Mail Example',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('mimemail_example_form'),
+    'access arguments' => array('access content'),
+  );
+
+  return $items;
+}
+
+/**
+ * Implements hook_mail().
+ */
+function mimemail_example_mail($key, &$message, $params) {
+  $message['subject'] = $params['subject'];
+  $message['body'][] = $params['body'];
+}
+
+/**
+ * The example email contact form.
+ */
+function mimemail_example_form() {
+  global $user;
+
+  $form['intro'] = array(
+    '#markup' => t('Use this form to send a HTML message to an e-mail address. No spamming!'),
+  );
+
+  $form['key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Key'),
+    '#default_value' => 'test',
+    '#required' => TRUE,
+  );
+
+  $form['to'] = array(
+    '#type' => 'textfield',
+    '#title' => t('To'),
+    '#default_value' => $user->mail,
+    '#required' => TRUE,
+  );
+
+  $form['from'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Sender name'),
+  );
+
+  $form['from_mail'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Sender e-mail address'),
+  );
+
+  $form['params'] = array(
+    '#tree' => TRUE,
+    'headers' => array(
+      'Cc' => array(
+        '#type' => 'textfield',
+        '#title' => t('Cc'),
+      ),
+      'Bcc' => array(
+        '#type' => 'textfield',
+        '#title' => t('Bcc'),
+      ),
+      'Reply-to' => array(
+        '#type' => 'textfield',
+        '#title' => t('Reply to'),
+      ),
+      'List-unsubscribe' => array(
+        '#type' => 'textfield',
+        '#title' => t('List-unsubscribe'),
+      ),
+    ),
+    'subject' => array(
+      '#type' => 'textfield',
+      '#title' => t('Subject'),
+    ),
+    'body' => array(
+      '#type' => 'textarea',
+      '#title' => t('HTML message'),
+    ),
+    'plain' => array(
+      '#type' => 'hidden',
+      '#states' => array(
+        'value' => array(
+          ':input[name="body"]' => array('value' => ''),
+        ),
+      ),
+    ),
+    'plaintext' => array(
+      '#type' => 'textarea',
+      '#title' => t('Plain text message'),
+    ),
+    'attachments' => array(
+      '#name' => 'files[attachment]',
+      '#type' => 'file',
+      '#title' => t('Choose a file to send as attachment'),
+    ),
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Send message'),
+  );
+
+  return $form;
+}
+
+/**
+ * Form validation logic for the email contact form.
+ */
+function mimemail_example_form_validate($form, &$form_state) {
+  $values = &$form_state['values'];
+
+  if (!valid_email_address($values['to'])) {
+    form_set_error('to', t('That e-mail address is not valid.'));
+  }
+
+  $file = file_save_upload('attachment');
+  if ($file) {
+    $file = file_move($file, 'public://');
+    $values['params']['attachments'][] = array(
+      'filepath' => $file->uri,
+    );
+  }
+}
+
+/**
+ * Form submission logic for the email contact form.
+ */
+function mimemail_example_form_submit($form, &$form_state) {
+  $values = $form_state['values'];
+
+  $module = 'mimemail_example';
+  $key = $values['key'];
+  $to = $values['to'];
+  $language = language_default();
+  $params = $values['params'];
+
+  if (!empty($values['from_mail'])) {
+    module_load_include('inc', 'mimemail');
+    $from = mimemail_address(array(
+      'name' => $values['from'],
+      'mail' => $values['from_mail'],
+    ));
+  }
+  else {
+    $from = $values['from'];
+  }
+
+  $send = TRUE;
+
+  $result = drupal_mail($module, $key, $to, $language, $params, $from, $send);
+  if ($result['result'] == TRUE) {
+    drupal_set_message(t('Your message has been sent.'));
+  }
+  else {
+    drupal_set_message(t('There was a problem sending your message and it was not sent.'), 'error');
+  }
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/tests/mimemail.test b/profiles/wcm_base/modules/contrib/mimemail/tests/mimemail.test
new file mode 100644
index 0000000000000000000000000000000000000000..5896a3c13c246b7189b78f2dcba970faedc6b641
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/tests/mimemail.test
@@ -0,0 +1,99 @@
+<?php
+
+/**
+ * @file
+ * Functionality tests for the Mime Mail module.
+ *
+ * @ingroup mimemail
+ */
+
+require_once(dirname(__FILE__) . '/../mimemail.inc');
+
+/**
+ * Tests helper functions from the Mime Mail module.
+ */
+class MimeMailUnitTestCase extends DrupalUnitTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Mime Mail unit tests',
+      'description' => 'Test that Mime Mail helper functions work properly.',
+      'group' => 'Mime Mail',
+    );
+  }
+
+  function setUp() {
+    drupal_load('module', 'mimemail');
+    parent::setUp();
+  }
+
+  function testHeaders() {
+    // Test the regular expression for extracting the mail address.
+    $chars = array('-', '.', '+', '_');
+    $name = $this->randomString();
+    $local = $this->randomName() . $chars[array_rand($chars)] . $this->randomName();
+    $domain = $this->randomName() . '-' . $this->randomName() . '.' . $this->randomName(rand(2,4));
+    $headers = mimemail_headers(array(), "$name <$local@$domain>");
+    $result = $headers['Return-Path'];
+    $expected = "<$local@$domain>";
+    $this->assertIdentical($result, $expected, 'Return-Path header field correctly set.');
+  }
+
+  function testUrl() {
+    $result = _mimemail_url('#');
+    $this->assertIdentical($result, '#', 'Hash mark URL without fragment left intact.');
+
+    $url = '/sites/default/files/styles/thumbnail/public/image.jpg?itok=Wrl6Qi9U';
+    $result = _mimemail_url($url, TRUE);
+    $expected = 'sites/default/files/styles/thumbnail/public/image.jpg';
+    $this->assertIdentical($result, $expected, 'Security token removed from styled image URL.');
+
+    $expected = $url = 'public://' . $this->randomName() . ' '. $this->randomName() . '.' . $this->randomName(3);
+    $result = _mimemail_url($url, TRUE);
+    $this->assertIdentical($result, $expected, 'Space in the filename of the attachment left intact.');
+  }
+
+}
+
+/**
+ * Tests functions from the Mime Mail module.
+ */
+class MimeMailWebTestCase extends DrupalWebTestCase {
+  protected $adminUser;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Mime Mail web tests',
+      'description' => 'Test that Mime Mail works properly.',
+      'group' => 'Mime Mail',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp('mailsystem', 'mimemail');
+
+    $permissions = array(
+      'access administration pages',
+      'administer site configuration',
+    );
+
+    // Check to make sure that the array of permissions are valid.
+    $this->checkPermissions($permissions, TRUE);
+
+    // Create and login user.
+    $this->adminUser = $this->drupalCreateUser($permissions);
+    $this->drupalLogin($this->adminUser);
+  }
+
+  public function testUrl() {
+    $this->drupalPost('admin/config/system/mimemail',
+      array('mimemail_linkonly' => TRUE),
+      t('Save configuration'));
+
+    $url = 'public://' . $this->randomName() . ' '. $this->randomName() . '.jpg';
+    $result = _mimemail_url($url, TRUE);
+    $expected = str_replace(' ', '%20', file_create_url($url));
+    $message = 'Stream wrapper converted to web accessible URL for linked image.';
+    $this->assertIdentical($result, $expected, $message);
+   }
+
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/tests/mimemail_compress.test b/profiles/wcm_base/modules/contrib/mimemail/tests/mimemail_compress.test
new file mode 100644
index 0000000000000000000000000000000000000000..2b05613ef9ee39aee8adfabacb3eaea6d37947bd
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/tests/mimemail_compress.test
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Functionality tests for the Mime Mail Compress module.
+ *
+ * @ingroup mimemail
+ */
+
+require_once(dirname(__FILE__) . '/../modules/mimemail_compress/mimemail_compress.inc');
+
+/**
+ * Tests helper functions from the Mime Mail Compress module.
+ */
+class MimeMailCompressUnitTestCase extends DrupalUnitTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Mime Mail Compress unit tests',
+      'description' => 'Test that Mime Mail Compress helper functions work properly.',
+      'group' => 'Mime Mail',
+    );
+  }
+
+  function setUp() {
+    drupal_load('module', 'mimemail_compress');
+    parent::setUp();
+  }
+
+
+
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/tests/mimemail_rules.test b/profiles/wcm_base/modules/contrib/mimemail/tests/mimemail_rules.test
new file mode 100644
index 0000000000000000000000000000000000000000..68dfdcf5df4e613c53aa0e60a202b244b55257a2
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/tests/mimemail_rules.test
@@ -0,0 +1,225 @@
+<?php
+
+/**
+ * @file
+ * Functionality tests for the Rules integration in the Mime Mail module.
+ *
+ * @ingroup mimemail
+ */
+
+/**
+ * Tests the Rules integration.
+ */
+class MimeMailRulesTestCase extends DrupalWebTestCase {
+  protected $adminUser;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Rules integration',
+      'description' => 'Test the Rules integration.',
+      'group' => 'Mime Mail',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp('mailsystem', 'locale', 'entity', 'entity_token', 'rules', 'mimemail');
+
+    $permissions = array(
+      'access administration pages',
+      'edit mimemail user settings',
+      'administer languages',
+      'administer rules',
+      'bypass rules access',
+      'access rules debug',
+    );
+
+    // Check to make sure that the array of permissions are valid.
+    $this->checkPermissions($permissions, TRUE);
+
+    // Create and login user.
+    $this->adminUser = $this->drupalCreateUser($permissions);
+    $this->drupalLogin($this->adminUser);
+
+    // Enable another language too.
+    foreach (array('de', 'it') as $langcode) {
+      $edit = array();
+      $edit['langcode'] = $langcode;
+      $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
+    }
+
+    // Make sure we are not using a stale list.
+    drupal_static_reset('language_list');
+  }
+
+  /**
+   * Create rule with "mimemail" action and fire it.
+   */
+  public function testMailToUserAction() {
+    $settings = array(
+      'key' => 'mail-key-' . $this->randomName(),
+      'to'  => $this->randomName() . '@example.com',
+      'from' => $this->randomName() . '@example.com',
+      'subject' => $this->randomName(),
+      'body' => $this->randomName(60) . '<div></div><br /><hr>',
+      'plaintext' => $this->randomName(30) . '<div></div><br /><hr>',
+    );
+
+    // Set no language for the mail and check if the system default is used.
+    $rule = rule();
+    $rule->action('mimemail', array(
+      'key' => $settings['key'],
+      'to' => $settings['to'],
+      'from_mail' => $settings['from'],
+      'subject' => $settings['subject'],
+      'body' => $settings['body'],
+      'plaintext' => $settings['plaintext'],
+      'language' => '',
+    ))->save();
+
+    $rule->execute();
+    $mails = $this->drupalGetMails(array('key' => $settings['key']));
+    $this->assertEqual(count($mails), 1);
+    $mail = reset($mails);
+    $this->assertEqual($mail['to'], $settings['to']);
+    $this->assertEqual($mail['from'], $settings['from']);
+    $this->assertEqual($mail['subject'], $settings['subject']);
+    $this->assertEqual($mail['params']['context']['body'], $settings['body']);
+    $this->assertEqual($mail['params']['plaintext'], $settings['plaintext']);
+    $this->assertEqual($mail['language']->language, language_default('language'));
+
+    // Explicitly set another language for the mail.
+    $rule_action = $rule->elementMap()->lookup(3);
+    unset($rule_action->settings['language:select']);
+    $rule_action->settings['language'] = 'de';
+    $rule_action->settings['key'] = $settings['key'];
+    $rule->save();
+    $rule->execute();
+    $mails = $this->drupalGetMails(array('key' => $settings['key']));
+    $this->assertEqual(count($mails), 2);
+    $mail = end($mails);
+    $this->assertEqual($mail['language']->language, 'de');
+  }
+
+  /**
+   * Create rule with "mimemail_to_users_of_role" action and fire it.
+   */
+  public function testMailToUsersOfRoleAction() {
+    $languages = language_list();
+
+    // Add more users and roles.
+    $users = array(
+      $this->randomName() . '@example.com' => 'en',
+      $this->randomName() . '@example.com' => 'de',
+      $this->randomName() . '@example.com' => 'it',
+      $this->randomName() . '@example.com' => '',
+      $this->randomName() . '@example.com' => 'invalid',
+    );
+
+    $mimemail_role = $this->drupalCreateRole(array());
+
+    foreach ($users as $email => $language) {
+      $user = $this->drupalCreateUser(array(
+        'access administration pages',
+      ));
+      $user->language = $language;
+      $user->mail = $email;
+      $user->roles[$mimemail_role] = $mimemail_role;
+      user_save($user);
+    }
+
+    $settings = array(
+      'key' => 'mail-key-' . $this->randomName(),
+      'from' => $this->randomName() . '@example.com',
+      'subject' => $this->randomName(),
+      'body' => $this->randomName(60) . '<div></div><br /><hr>',
+      'plaintext' => $this->randomName(30) . '<div></div><br /><hr>',
+    );
+
+    // Rest the collected mails.
+    variable_set('drupal_test_email_collector', array());
+
+    // Send mails to all users of a role and respect the language of the users.
+    // Don't enforce a specific language as fallback use the system default.
+    $rule = rule();
+    $rule->action('mimemail_to_users_of_role', array(
+      'key' => $settings['key'],
+      'from_mail' => $settings['from'],
+      'subject' => $settings['subject'],
+      'body' => $settings['body'],
+      'plaintext' => $settings['plaintext'],
+      'roles' => array($mimemail_role => $mimemail_role),
+      'active' => TRUE,
+      'language_user' => TRUE,
+      'language' => '',
+    ));
+    $rule->save();
+    $rule->execute();
+    $mails = $this->drupalGetMails(array('key' => $settings['key']));
+    $this->assertEqual(count($mails), count($users));
+    $mail = reset($mails);
+    $this->assertEqual($mail['from'], $settings['from']);
+    $this->assertEqual($mail['subject'], $settings['subject']);
+    $this->assertEqual($mail['params']['context']['body'], $settings['body']);
+    $this->assertEqual($mail['params']['plaintext'], $settings['plaintext']);
+    foreach ($mails as $mail) {
+      // If the user hasn't a proper language the system default has to be used
+      // if the rules action doesn't provide a language to use.
+      $user_language = (!empty($languages[$users[$mail['to']]])) ? $users[$mail['to']] : language_default('language');
+      $this->assertEqual($mail['language']->language, $user_language);
+    }
+
+    // Rest the collected mails.
+    variable_set('drupal_test_email_collector', array());
+
+    // Send mails to all users of a role and respect the language of the users.
+    // Enforce German as fallback language if an user doesn't have a language.
+    $rule->elementMap()->lookup(3)->settings['language'] = 'de';
+    $rule->save();
+    $rule->execute();
+    $mails = $this->drupalGetMails(array('key' => $settings['key']));
+    $this->assertEqual(count($mails), count($users));
+    foreach ($mails as $mail) {
+      // If the user hasn't a proper language the language set in the rules
+      // action has to be used.
+      $user_language = (!empty($languages[$users[$mail['to']]])) ? $users[$mail['to']] : 'de';
+      $this->assertEqual($mail['language']->language, $user_language);
+    }
+
+    // Rest the collected mails.
+    variable_set('drupal_test_email_collector', array());
+
+    // Send mails to all users of a role but use the same language for all.
+    $rule->elementMap()->lookup(3)->settings['language_user'] = FALSE;
+    $rule->elementMap()->lookup(3)->settings['language'] = 'it';
+    $rule->save();
+    $rule->execute();
+    $mails = $this->drupalGetMails(array('key' => $settings['key']));
+    foreach ($mails as $mail) {
+      $this->assertEqual($mail['language']->language, 'it');
+    }
+
+    // Rest the collected mails.
+    variable_set('drupal_test_email_collector', array());
+
+    // Send mails to all users of a role except deactivated users.
+    // Disable one of the users.
+    reset($users);
+    $user = user_load_by_mail(key($users));
+    $user->status = 0;
+    user_save($user);
+    $rule->execute();
+    $mails = $this->drupalGetMails(array('key' => $settings['key']));
+    $this->assertEqual(count($mails), count($users) - 1);
+
+    // Rest the collected mails.
+    variable_set('drupal_test_email_collector', array());
+
+    // Send mails to all users, also to deactivated ones.
+    $rule->elementMap()->lookup(3)->settings['active'] = FALSE;
+    $rule->save();
+    $rule->execute();
+    $mails = $this->drupalGetMails(array('key' => $settings['key']));
+    // One user is disabled but it should be ignored.
+    $this->assertEqual(count($mails), count($users));
+  }
+}
diff --git a/profiles/wcm_base/modules/contrib/mimemail/theme/mimemail-message.tpl.php b/profiles/wcm_base/modules/contrib/mimemail/theme/mimemail-message.tpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..179573d5c81537e4da762af7b574ca50e0bdc4cf
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/theme/mimemail-message.tpl.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Default theme implementation to format an HTML mail.
+ *
+ * Copy this file in your default theme folder to create a custom themed mail.
+ * Rename it to mimemail-message--[module]--[key].tpl.php to override it for a
+ * specific mail.
+ *
+ * Available variables:
+ * - $recipient: The recipient of the message
+ * - $subject: The message subject
+ * - $body: The message body
+ * - $css: Internal style sheets
+ * - $module: The sending module
+ * - $key: The message identifier
+ *
+ * @see template_preprocess_mimemail_message()
+ */
+?>
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <?php if ($css): ?>
+    <style type="text/css">
+      <!--
+      <?php print $css ?>
+      -->
+    </style>
+    <?php endif; ?>
+  </head>
+  <body id="mimemail-body" <?php if ($module && $key): print 'class="'. $module .'-'. $key .'"'; endif; ?>>
+    <div id="center">
+      <div id="main">
+        <?php print $body ?>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/profiles/wcm_base/modules/contrib/mimemail/theme/mimemail.theme.inc b/profiles/wcm_base/modules/contrib/mimemail/theme/mimemail.theme.inc
new file mode 100644
index 0000000000000000000000000000000000000000..2a2df7cffda308dde12a7ffb3a321c8c128f5249
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/mimemail/theme/mimemail.theme.inc
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * @file
+ * The theme system, which controls the output of the messages.
+ */
+
+function mimemail_theme_theme() {
+  $path = drupal_get_path('module', 'mimemail') . '/theme';
+
+  return array(
+    'mimemail_message' => array(
+      'variables' => array('module' => NULL, 'key' => NULL, 'recipient' => NULL, 'subject' => NULL, 'body' => NULL),
+      'template' => 'mimemail-message',
+      'pattern' => 'mimemail_message__',
+      'file' => 'mimemail.theme.inc',
+      'mail theme' => TRUE,
+      'path' => $path,
+    )
+  );
+}
+
+/**
+ * A preprocess function for theme('mimemail_message').
+ *
+ * The $variables array initially contains the following arguments:
+ * - $recipient: The recipient of the message
+ * - $key:  The mailkey associated with the message
+ * - $subject: The message subject
+ * - $body:  The message body
+ *
+ * @see mimemail-message.tpl.php
+ */
+function template_preprocess_mimemail_message(&$variables) {
+  $theme = mailsystem_get_mail_theme();
+  $themepath = drupal_get_path('theme', $theme);
+
+  $sitestyle = variable_get('mimemail_sitestyle', 1);
+  $mailstyles = file_scan_directory($themepath, '#^mail\.css*$#');
+
+  // Check recursively for the existence of a mail.css file in the theme folder.
+  if (!empty($mailstyles)) {
+    foreach ($mailstyles as $mailstyle) {
+      $styles = $mailstyle->uri;
+    }
+  }
+  // If no mail.css was found and the site style sheets including is enabled,
+  // gather all style sheets and embed a version of all style definitions.
+  elseif ($sitestyle) {
+    // Grab local.css if it exists (support for Fusion based themes).
+    $local = $themepath . '/css/local.css';
+    if (@file_exists($local)) {
+      $css_all = drupal_add_css($local, array('group' => CSS_THEME));
+    }
+    else {
+      $css_all = drupal_add_css();
+    }
+    $css_files = array();
+    foreach ($css_all as $key => $options) {
+      if ($options['group'] == CSS_THEME && $options['type'] == 'file' &&
+        ($options['media'] == 'all' || $options['media'] == 'screen')) {
+        $css_files[$key] = $options;
+      }
+    }
+    if (variable_get('preprocess_css', FALSE)) {
+      $pattern = '|<link.*href="' . $GLOBALS['base_url'] . '/([^"?]*)[?"].*|';
+      $replacement = '\1';
+    }
+    else {
+      $pattern = array(
+        '/<([^<>]*)>/', // Remove the style tag.
+        '/@import\s+url\("([^"]+)"\);+/', // Remove the import directive.
+        '|' . $GLOBALS['base_url'] . '/([^"?]*)[?"].*|' // Remove the base URL.
+      );
+      $replacement = array('', '\1', '\1');
+    }
+    $styles = preg_replace($pattern, $replacement, drupal_get_css($css_files));
+  }
+
+  $css = '';
+  if (isset($styles)) {
+    // Process each style sheet.
+    foreach (explode("\n", $styles) as $style) {
+      if (!empty($style)) {
+        $css .= drupal_load_stylesheet($style, TRUE);
+      }
+    }
+
+    // Wordwrap to adhere to RFC821
+    $css = wordwrap($css, 700);
+  }
+
+  // Set styles for the message.
+  $variables['css'] = $css;
+
+  // Set template alternatives.
+  $variables['theme_hook_suggestions'][] = 'mimemail_message__' . str_replace('-', '_', $variables['key']);
+
+   // Process identifiers to be proper CSS classes.
+  $variables['module'] = str_replace('_', '-', $variables['module']);
+  $variables['key'] = str_replace('_', '-', $variables['key']);
+}
diff --git a/profiles/wcm_base/modules/contrib/webform/components/date.inc b/profiles/wcm_base/modules/contrib/webform/components/date.inc
index f84c2f23e863e20c1991ba7c7e4d494b4c655a7d..2450f73a96d822940934cfbc4e04423a173ae7bc 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/date.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/date.inc
@@ -25,6 +25,7 @@ function _webform_defaults_date() {
       'datepicker' => 1,
       'title_display' => 0,
       'description' => '',
+      'description_above' => FALSE,
       'private' => FALSE,
       'analysis' => FALSE,
     ),
@@ -462,7 +463,7 @@ function _webform_submit_date($component, $value) {
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_date($component, $value, $format = 'html') {
+function _webform_display_date($component, $value, $format = 'html', $submission = array()) {
   $value = webform_date_array(isset($value[0]) ? $value[0] : '', 'date');
 
   return array(
diff --git a/profiles/wcm_base/modules/contrib/webform/components/email.inc b/profiles/wcm_base/modules/contrib/webform/components/email.inc
index d4077924a7ccd380ce3880fdf4d2d0047bd96897..8e3e6169092088c2a78e6481f0b4d45fd27c7017 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/email.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/email.inc
@@ -24,6 +24,7 @@ function _webform_defaults_email() {
       'disabled' => 0,
       'title_display' => 0,
       'description' => '',
+      'description_above' => FALSE,
       'placeholder' => '',
       'attributes' => array(),
       'private' => FALSE,
@@ -257,13 +258,14 @@ function _webform_validate_email($form_element, &$form_state) {
                          implode('][', $form_element ['#parents']),
                          TRUE,  // Required validation is done elsewhere.
                          $component['extra']['multiple'],
+                         FALSE, // No tokens are allowed in user input.
                          $format);
 }
 
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_email($component, $value, $format = 'html') {
+function _webform_display_email($component, $value, $format = 'html', $submission = array()) {
   return array(
     '#title' => $component['name'],
     '#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before',
@@ -334,6 +336,13 @@ function _webform_table_email($component, $value) {
   return check_plain(empty($value[0]) ? '' : $value[0]);
 }
 
+/**
+ * Implements _webform_action_set_component().
+ */
+function _webform_action_set_email($component, &$element, &$form_state, $value) {
+  $element['#value'] = $value;
+  form_set_value($element, $value, $form_state);
+}
 
 /**
  * Implements _webform_csv_headers_component().
diff --git a/profiles/wcm_base/modules/contrib/webform/components/fieldset.inc b/profiles/wcm_base/modules/contrib/webform/components/fieldset.inc
index 8b43ae331aa08e4e43587585d800443529a85f0e..763e5211118f04bd8b9b10b1202d224cf3cb830f 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/fieldset.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/fieldset.inc
@@ -19,6 +19,7 @@ function _webform_defaults_fieldset() {
       'collapsible' => 0,
       'collapsed' => 0,
       'description' => '',
+      'description_above' => FALSE,
       'private' => FALSE,
     ),
   );
@@ -82,7 +83,7 @@ function webform_fieldset_prerender($element) {
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_fieldset($component, $value, $format = 'html') {
+function _webform_display_fieldset($component, $value, $format = 'html', $submission = array()) {
   if ($format == 'text') {
     $element = array(
       '#title' => $component['name'],
diff --git a/profiles/wcm_base/modules/contrib/webform/components/file.inc b/profiles/wcm_base/modules/contrib/webform/components/file.inc
index 6ec752c8b9e1cd5e33a13b5947e54101ea39a4ea..1f7c99ef10f162cc79d2f61630b14f2a9e77a3ef 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/file.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/file.inc
@@ -27,6 +27,7 @@ function _webform_defaults_file() {
       'progress_indicator' => 'throbber',
       'title_display' => 0,
       'description' => '',
+      'description_above' => FALSE,
       'attributes' => array(),
       'private' => FALSE,
       'analysis' => FALSE,
@@ -47,6 +48,10 @@ function _webform_theme_file() {
       'render element' => 'element',
       'file' => 'components/file.inc',
     ),
+    'webform_managed_file' => array(
+      'render element' => 'element',
+      'file' => 'components/file.inc',
+    ),
   );
 }
 
@@ -161,7 +166,7 @@ function _webform_edit_file($component) {
       '#type' => 'textfield',
       '#title' => t('Rename files'),
       '#default_value' => $component['extra']['rename'],
-      '#description' => t('You may optionally use tokens to create a pattern used to rename files upon submission. Omit the extension; it will be added automatically.').' '.theme('webform_token_help', array('groups' => array('node', 'submission'))),
+      '#description' => t('You may optionally use tokens to create a pattern used to rename files upon submission. Omit the extension; it will be added automatically.') . ' ' . theme('webform_token_help', array('groups' => array('node', 'submission'))),
       '#weight' => 6,
       '#element_validate' => array('_webform_edit_file_rename_validate'),
     );
@@ -342,6 +347,7 @@ function _webform_render_file($component, $value = NULL, $filter = TRUE, $submis
 
   $element = array(
     '#type' => 'managed_file',
+    '#theme' => 'webform_managed_file',
     '#title' => $filter ? webform_filter_xss($component['name']) : $component['name'],
     '#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before',
     '#required' => $component['required'],
@@ -369,6 +375,42 @@ function _webform_render_file($component, $value = NULL, $filter = TRUE, $submis
   return $element;
 }
 
+/**
+ * Returns HTML for a webform managed file element.
+ *
+ * See #2495821 and #2497909. The core theme_file_managed_file creates a
+ * wrapper around the element with the element's id, thereby creating 2 elements
+ * with the same id.
+ *
+ * @param $variables
+ *   An associative array containing:
+ *   - element: A render element representing the file.
+ *
+ */
+function theme_webform_managed_file($variables) {
+  $element = $variables['element'];
+
+  $attributes = array();
+
+  // For webform use, do not add the id to the wrapper.
+  //if (isset($element['#id'])) {
+  //  $attributes['id'] = $element['#id'];
+  //}
+
+  if (!empty($element['#attributes']['class'])) {
+    $attributes['class'] = (array) $element['#attributes']['class'];
+  }
+  $attributes['class'][] = 'form-managed-file';
+
+  // This wrapper is required to apply JS behaviors and CSS styling.
+  $output = '';
+  $output .= '<div' . drupal_attributes($attributes) . '>';
+  $output .= drupal_render_children($element);
+  $output .= '</div>';
+  return $output;
+}
+
+
 /**
  * Implements _webform_submit_component().
  */
@@ -406,7 +448,7 @@ function webform_file_allow_access($element) {
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_file($component, $value, $format = 'html') {
+function _webform_display_file($component, $value, $format = 'html', $submission = array()) {
   $fid = isset($value[0]) ? $value[0] : NULL;
   return array(
     '#title' => $component['name'],
diff --git a/profiles/wcm_base/modules/contrib/webform/components/grid.inc b/profiles/wcm_base/modules/contrib/webform/components/grid.inc
index 3e5bab8997e5b44bbd71d9e55408889c58d5388f..fbb88272539ea9c5db217600ecc4372ab2974c99 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/grid.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/grid.inc
@@ -30,6 +30,7 @@ function _webform_defaults_grid() {
       'custom_question_keys' => 0,
       'sticky' => TRUE,
       'description' => '',
+      'description_above' => FALSE,
       'private' => FALSE,
       'analysis' => TRUE,
     ),
@@ -104,7 +105,7 @@ function _webform_edit_grid($component) {
       '#type' => 'textarea',
       '#title' => t('Options'),
       '#default_value' => $component['extra']['options'],
-      '#description' => t('Options to select across the top. One option per line. <strong>Key-value pairs MUST be specified as "safe_key|Some readable option"</strong>. Use of only alphanumeric characters and underscores is recommended in keys.') . ' ' .theme('webform_token_help'),
+      '#description' => t('Options to select across the top. One option per line. <strong>Key-value pairs MUST be specified as "safe_key|Some readable option"</strong>. Use of only alphanumeric characters and underscores is recommended in keys.') . ' ' . theme('webform_token_help'),
       '#cols' => 60,
       '#rows' => 5,
       '#weight' => -3,
@@ -264,7 +265,7 @@ function webform_expand_grid($element) {
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_grid($component, $value, $format = 'html') {
+function _webform_display_grid($component, $value, $format = 'html', $submission = array()) {
   $node = node_load($component['nid']);
   $questions = _webform_select_options_from_text($component['extra']['questions'], TRUE);
   $questions = _webform_select_replace_tokens($questions, $node);
@@ -529,9 +530,10 @@ function theme_webform_grid($variables) {
     // Render each radio button in the row.
     $radios = form_process_radios($question_element);
     foreach (element_children($radios) as $key) {
-      $radios[$key]['#title'] = $question_element['#title'] . ' - ' . $radios[$key]['#title'];
+      $radio_title = $radios[$key]['#title'];
+      $radios[$key]['#title'] = $question_element['#title'] . ' - ' . $radio_title;
       $radios[$key]['#title_display'] = 'invisible';
-      $row[] = array('data' => drupal_render($radios[$key]), 'class' => array('checkbox', 'webform-grid-option'));
+      $row[] = array('data' => drupal_render($radios[$key]), 'class' => array('checkbox', 'webform-grid-option'), 'data-label' => array($radio_title));
     }
     if ($right_titles) {
       $row[] = array('data' => isset($question_titles[1]) ? webform_filter_xss($question_titles[1]) : '', 'class' => array('webform-grid-question'));
diff --git a/profiles/wcm_base/modules/contrib/webform/components/hidden.inc b/profiles/wcm_base/modules/contrib/webform/components/hidden.inc
index 0740018f649421e282b09010309b30997e21565b..2e9c07a3d4c76d1e89c0bdcab39989bee3285fd6 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/hidden.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/hidden.inc
@@ -103,7 +103,7 @@ function _webform_render_hidden($component, $value = NULL, $filter = TRUE, $subm
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_hidden($component, $value, $format = 'html') {
+function _webform_display_hidden($component, $value, $format = 'html', $submission = array()) {
   $element = array(
     '#title' => $component['name'],
     '#markup' => isset($value[0]) ? $value[0] : NULL,
@@ -170,6 +170,14 @@ function _webform_table_hidden($component, $value) {
   return check_plain(empty($value[0]) ? '' : $value[0]);
 }
 
+/**
+ * Implements _webform_action_set_component().
+ */
+function _webform_action_set_hidden($component, &$element, &$form_state, $value) {
+  $element['#value'] = $value;
+  form_set_value($element, $value, $form_state);
+}
+
 /**
  * Implements _webform_csv_headers_component().
  */
diff --git a/profiles/wcm_base/modules/contrib/webform/components/markup.inc b/profiles/wcm_base/modules/contrib/webform/components/markup.inc
index 6ceefb26c89b7be70bab22a77795afae0269fadc..6d8b8cf1447654be15c7132de1f38d5c5456a312 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/markup.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/markup.inc
@@ -44,7 +44,7 @@ function _webform_edit_markup($component) {
     '#type' => 'text_format',
     '#title' => t('Value'),
     '#default_value' => $component['value'],
-    '#description' => t('Markup allows you to enter custom HTML or PHP logic into your form.') . theme('webform_token_help'),
+    '#description' => t('Markup allows you to enter custom HTML into your form.') . ' ' . theme('webform_token_help', array('groups' => array('node', 'submission'))),
     '#weight' => -1,
     '#format' => $component['extra']['format'],
     '#element_validate' => array('_webform_edit_markup_validate'),
@@ -80,33 +80,88 @@ function _webform_edit_markup_validate($form, &$form_state) {
  * Implements _webform_render_component().
  */
 function _webform_render_markup($component, $value = NULL, $filter = TRUE, $submission = NULL) {
-  $node = isset($component['nid']) ? node_load($component['nid']) : NULL;
 
   $element = array(
     '#type' => 'markup',
     '#title' => $filter ? NULL : $component['name'],
     '#weight' => $component['weight'],
-    '#markup' => $filter ? webform_replace_tokens($component['value'], $node, NULL, NULL, $component['extra']['format']) : $component['value'],
+    '#markup' => $component['value'],
     '#format' => $component['extra']['format'],
     '#theme_wrappers' => array('webform_element'),
     '#translatable' => array('title', 'markup'),
     '#access' => $component['extra']['display_on'] != 'display',
+    '#webform_nid' => isset($component['nid']) ? $component['nid'] : NULL,
+    '#webform_submission' => $submission,
+    '#webform_format' => $component['extra']['format'],
   );
 
+  if ($filter) {
+    $element['#after_build'] = array('_webform_render_markup_after_build');
+  }
+
   return $element;
 }
 
+ /**
+ * Helper function to replace tokens in markup component.
+ *
+ * Required to have access to current form values from $form_state.
+ */
+function _webform_render_markup_after_build($form_element, &$form_state) {
+  global $user;
+  $node = node_load($form_element['#webform_nid']);
+  $submission = NULL;
+
+  // Convert existing submission data to an in-progress submission.
+  $form_state_for_submission = $form_state;
+  $form_state_for_submission['values']['submitted'] = $form_state['#conditional_values'];
+  module_load_include('inc', 'webform', 'includes/webform.submissions');
+  $submission = webform_submission_create($node, $user, $form_state_for_submission, TRUE, $form_element['#webform_submission']);
+
+  // Replace tokens using the current or generated submission.
+  $value = webform_replace_tokens($form_element['#markup'], $node, $submission, NULL, $form_element['#webform_format']);
+
+  // If the markup value has been set by a conditional, display that value.
+  $component = $form_element['#webform_component'];
+  if ($node) {
+    $sorter = webform_get_conditional_sorter($node);
+    // If the form was retrieved from the form cache, the conditionals may not
+    // have been executed yet.
+    if (!$sorter->isExecuted()) {
+      $sorter->executeConditionals(isset($submission) ? $submission->data : array());
+    }
+    $conditional_value = $sorter->componentMarkup($component['cid'], $component['page_num']);
+    if (isset($conditional_value)) {
+      // Provide original value, should conditional logic no longer set the value.
+      $form_element['#wrapper_attributes']['data-webform-markup'] = $value;
+      if (is_string($conditional_value)) {
+        $value = check_markup($conditional_value, $component['extra']['format']);
+      }
+    }
+  }
+
+  $form_element['#markup'] = $value;
+  return $form_element;
+}
+
+
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_markup($component, $value, $format = 'html') {
+function _webform_display_markup($component, $value, $format = 'html', $submission = array()) {
   $node = isset($component['nid']) ? node_load($component['nid']) : NULL;
+  $value = webform_replace_tokens($component['value'], $node, $submission, NULL, $component['extra']['format']);
+
+  // If the markup value has been set by a conditional, display that value.
+  if ($node && is_string($conditional_value = webform_get_conditional_sorter($node)->componentMarkup($component['cid'], $component['page_num']))) {
+    $value = check_markup($conditional_value, $component['extra']['format']);
+  }
 
   return array(
     '#weight' => $component['weight'],
     '#theme' => 'webform_display_markup',
     '#format' => $format,
-    '#value' => webform_replace_tokens($component['value'], $node, NULL, NULL, $component['extra']['format']),
+    '#value' => $value,
     '#translatable' => array('title'),
     '#access' => $component['extra']['display_on'] != 'form',
   );
diff --git a/profiles/wcm_base/modules/contrib/webform/components/number.inc b/profiles/wcm_base/modules/contrib/webform/components/number.inc
index 9fe0bb560668cd7cb0de9e7f6cff3288c3d3aa66..9d5830d7e619ff2cbd10c0e71d77f7c5e3da3cdd 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/number.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/number.inc
@@ -24,6 +24,7 @@ function _webform_defaults_number() {
       'unique' => 0,
       'title_display' => 0,
       'description' => '',
+      'description_above' => FALSE,
       'attributes' => array(),
       'private' => FALSE,
       'analysis' => FALSE,
@@ -377,7 +378,7 @@ function _webform_render_number($component, $value = NULL, $filter = TRUE, $subm
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_number($component, $value, $format = 'html') {
+function _webform_display_number($component, $value, $format = 'html', $submission = array()) {
   $empty = !isset($value[0]) || $value[0] === '';
   return array(
     '#title' => $component['name'],
@@ -477,7 +478,7 @@ function _webform_analysis_number($component, $sids = array(), $single = FALSE,
   if ($advanced_stats && $population_count && $sum != 0) {
     // Standard deviation.
     $stddev = 0;
-    foreach($population as $value) {
+    foreach ($population as $value) {
       // Obtain the total of squared variances.
       $stddev += pow(($value - $average), 2);
     }
@@ -522,21 +523,21 @@ function _webform_analysis_number($component, $sids = array(), $single = FALSE,
     $stddev = _webform_number_format($component, $stddev);
     $low = _webform_number_format($component, $population[0]);
     $high = _webform_number_format($component, end($population));
-    foreach($limit as $key => $value) {
+    foreach ($limit as $key => $value) {
       $limit[$key] = _webform_number_format($component, $value);
     }
 
     // Column headings (override potential theme uppercase, e.g. Seven in D7).
     $header = array(
       t('Normal Distribution'),
-      array('data' => '-4' . $sigma, 'style' => 'text-transform: lowercase;',),
-      array('data' => '-3' . $sigma, 'style' => 'text-transform: lowercase;',),
-      array('data' => '-2' . $sigma, 'style' => 'text-transform: lowercase;',),
-      array('data' => '-1' . $sigma, 'style' => 'text-transform: lowercase;',),
-      array('data' => '+1' . $sigma, 'style' => 'text-transform: lowercase;',),
-      array('data' => '+2' . $sigma, 'style' => 'text-transform: lowercase;',),
-      array('data' => '+3' . $sigma, 'style' => 'text-transform: lowercase;',),
-      array('data' => '+4' . $sigma, 'style' => 'text-transform: lowercase;',),
+      array('data' => '-4' . $sigma, 'style' => 'text-transform: lowercase;'),
+      array('data' => '-3' . $sigma, 'style' => 'text-transform: lowercase;'),
+      array('data' => '-2' . $sigma, 'style' => 'text-transform: lowercase;'),
+      array('data' => '-1' . $sigma, 'style' => 'text-transform: lowercase;'),
+      array('data' => '+1' . $sigma, 'style' => 'text-transform: lowercase;'),
+      array('data' => '+2' . $sigma, 'style' => 'text-transform: lowercase;'),
+      array('data' => '+3' . $sigma, 'style' => 'text-transform: lowercase;'),
+      array('data' => '+4' . $sigma, 'style' => 'text-transform: lowercase;'),
     );
 
     // Insert row labels.
@@ -564,6 +565,14 @@ function _webform_table_number($component, $value) {
   return isset($value[0]) ? _webform_number_format($component, $value[0]) : '';
 }
 
+/**
+ * Implements _webform_action_set_component().
+ */
+function _webform_action_set_number($component, &$element, &$form_state, $value) {
+  $element['#value'] = $value;
+  form_set_value($element, $value, $form_state);
+}
+
 /**
  * Implements _webform_csv_headers_component().
  */
diff --git a/profiles/wcm_base/modules/contrib/webform/components/pagebreak.inc b/profiles/wcm_base/modules/contrib/webform/components/pagebreak.inc
index a02367d893bece306327d4eeb317ef6c5e1531c9..d97c74fff2389835cf4c0f3644740707db53f0b3 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/pagebreak.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/pagebreak.inc
@@ -78,7 +78,7 @@ function _webform_render_pagebreak($component, $value = NULL, $filter = TRUE, $s
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_pagebreak($component, $value = NULL, $format = 'html') {
+function _webform_display_pagebreak($component, $value = NULL, $format = 'html', $submission = array()) {
   $element = array(
     '#theme' => 'webform_display_pagebreak',
     '#title' => $component['name'],
diff --git a/profiles/wcm_base/modules/contrib/webform/components/select.inc b/profiles/wcm_base/modules/contrib/webform/components/select.inc
index af6c69e91dc0be6c71579274c04bc294a0a93e31..942c1d4ed3941875008046854cbeabf02cc45a70 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/select.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/select.inc
@@ -26,6 +26,7 @@ function _webform_defaults_select() {
       'other_text' => t('Other...'),
       'title_display' => 0,
       'description' => '',
+      'description_above' => FALSE,
       'custom_keys' => FALSE,
       'options_source' => '',
       'private' => FALSE,
@@ -328,11 +329,6 @@ function _webform_render_select($component, $value = NULL, $filter = TRUE, $subm
     '#translatable' => array('title', 'description', 'options'),
   );
 
-  // Add HTML5 required attribute, if needed and possible (not working on multiple checkboxes).
-  if ($component['required'] && ($component['extra']['aslist'] || !$component['extra']['multiple'])) {
-    $element['#attributes']['required'] = 'required';
-  }
-
   // Convert the user-entered options list into an array.
   $default_value = $filter ? webform_replace_tokens($component['value'], $node) : $component['value'];
   $options = _webform_select_options($component, !$component['extra']['aslist'], $filter);
@@ -345,11 +341,19 @@ function _webform_render_select($component, $value = NULL, $filter = TRUE, $subm
     _webform_shuffle_options($options);
   }
 
+  // Add HTML5 required attribute, if needed and possible (not working on more than one checkboxes).
+  if ($component['required'] && ($component['extra']['aslist'] || !$component['extra']['multiple'] || count($options) == 1)) {
+    $element['#attributes']['required'] = 'required';
+  }
+
   // Add default options if using a select list with no default. This trigger's
   // Drupal 7's adding of the option for us. See @form_process_select().
   if ($component['extra']['aslist'] && !$component['extra']['multiple'] && $default_value === '') {
     $element['#empty_value'] = '';
-    $element['#empty_option'] = $component['extra']['empty_option'];
+    if (strlen($component['extra']['empty_option'])) {
+      $element['#empty_option'] =  $component['extra']['empty_option'];
+      $element['#translatable'][] = 'empty_option';
+    }
   }
 
   // Set the component options.
@@ -485,7 +489,7 @@ function webform_expand_select_ids($element) {
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_select($component, $value, $format = 'html') {
+function _webform_display_select($component, $value, $format = 'html', $submission = array()) {
   // Sort values by numeric key. These may be in alphabetic order from the database query,
   // which is not numeric order for keys '10' and higher.
   $value = (array) $value;
@@ -739,6 +743,24 @@ function _webform_table_select($component, $value) {
   return implode('<br />', $items);
 }
 
+/**
+ * Implements _webform_action_set_component().
+ */
+function _webform_action_set_select($component, &$element, &$form_state, $value) {
+  // Set the value as an array for multiple select or single value otherwise.
+  if ($element['#type'] == 'checkboxes') {
+    $checkbox_values = $element['#options'];
+    array_walk($checkbox_values, function(&$value, $key) use($value) {
+      $value = (int)(strval($key) === $value);
+    });
+  }
+  else {
+    $value = $component['extra']['multiple'] ? array($value) : $value;
+  }
+  $element['#value'] = $value;
+  form_set_value($element, $value, $form_state);
+}
+
 /**
  * Implements _webform_csv_headers_component().
  */
@@ -795,7 +817,9 @@ function _webform_csv_data_select($component, $export_options, $value) {
 
   if ($component['extra']['multiple']) {
     foreach ($options as $key => $item) {
-      $index = array_search($key, (array) $value);
+      // Strict search is needed to avoid a key of 0 from matching an empty
+      // value.
+      $index = array_search((string)$key, (array)$value, TRUE);
       if ($index !== FALSE) {
         if ($export_options['select_format'] == 'separate') {
           $return[] = 'X';
diff --git a/profiles/wcm_base/modules/contrib/webform/components/textarea.inc b/profiles/wcm_base/modules/contrib/webform/components/textarea.inc
index 41d0f57d3fdca7277fb00c4863ea09218a73bcff..98adbbbff6ce175224332d1818947f8f35f086bc 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/textarea.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/textarea.inc
@@ -23,6 +23,7 @@ function _webform_defaults_textarea() {
       'resizable' => 1,
       'disabled' => 0,
       'description' => '',
+      'description_above' => FALSE,
       'placeholder' => '',
       'attributes' => array(),
       'private' => FALSE,
@@ -152,7 +153,7 @@ function _webform_render_textarea($component, $value = NULL, $filter = TRUE, $su
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_textarea($component, $value, $format = 'html') {
+function _webform_display_textarea($component, $value, $format = 'html', $submission = array()) {
   return array(
     '#title' => $component['name'],
     '#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before',
@@ -225,6 +226,14 @@ function _webform_table_textarea($component, $value) {
   return empty($value[0]) ? '' : check_plain($value[0]);
 }
 
+/**
+ * Implements _webform_action_set_component().
+ */
+function _webform_action_set_textarea($component, &$element, &$form_state, $value) {
+  $element['#value'] = $value;
+  form_set_value($element, $value, $form_state);
+}
+
 /**
  * Implements _webform_csv_headers_component().
  */
diff --git a/profiles/wcm_base/modules/contrib/webform/components/textfield.inc b/profiles/wcm_base/modules/contrib/webform/components/textfield.inc
index 7ada5fcee0302e28d703d7fda9b36845abf12f5c..b9693c9db02668c4d9093637b6ae92b6e7c01a43 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/textfield.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/textfield.inc
@@ -25,6 +25,7 @@ function _webform_defaults_textfield() {
       'unique' => 0,
       'title_display' => 0,
       'description' => '',
+      'description_above' => FALSE,
       'placeholder' => '',
       'attributes' => array(),
       'private' => FALSE,
@@ -189,7 +190,7 @@ function _webform_render_textfield($component, $value = NULL, $filter = TRUE, $s
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_textfield($component, $value, $format = 'html') {
+function _webform_display_textfield($component, $value, $format = 'html', $submission = array()) {
   return array(
     '#title' => $component['name'],
     '#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before',
@@ -263,6 +264,14 @@ function _webform_table_textfield($component, $value) {
   return check_plain(empty($value[0]) ? '' : $value[0]);
 }
 
+/**
+ * Implements _webform_action_set_component().
+ */
+function _webform_action_set_textfield($component, &$element, &$form_state, $value) {
+  $element['#value'] = $value;
+  form_set_value($element, $value, $form_state);
+}
+
 /**
  * Implements _webform_csv_headers_component().
  */
diff --git a/profiles/wcm_base/modules/contrib/webform/components/time.inc b/profiles/wcm_base/modules/contrib/webform/components/time.inc
index 786dae5609a6af5c0056a4c5ec391423ae15bae3..59c8fd310d6462efdd40f6b5d70f544bc6aaeb63 100644
--- a/profiles/wcm_base/modules/contrib/webform/components/time.inc
+++ b/profiles/wcm_base/modules/contrib/webform/components/time.inc
@@ -27,6 +27,7 @@ function _webform_defaults_time() {
       'minuteincrements' => 1,
       'title_display' => 0,
       'description' => '',
+      'description_above' => FALSE,
       'private' => FALSE,
       'analysis' => FALSE,
     ),
@@ -365,7 +366,7 @@ function _webform_submit_time($component, $value) {
 /**
  * Implements _webform_display_component().
  */
-function _webform_display_time($component, $value, $format = 'html') {
+function _webform_display_time($component, $value, $format = 'html', $submission = array()) {
   $value = webform_date_array(isset($value[0]) ? $value[0] : '', 'time');
   if ($component['extra']['hourformat'] == '12-hour') {
     $value = webform_time_convert($value, '12-hour');
diff --git a/profiles/wcm_base/modules/contrib/webform/css/webform-admin.css b/profiles/wcm_base/modules/contrib/webform/css/webform-admin.css
index 520a86cf7e489c1e7e3f91630a5b2f5f2f9a5d36..297f5679fa7c4b3a5ce22faf155f0eb16b099083 100644
--- a/profiles/wcm_base/modules/contrib/webform/css/webform-admin.css
+++ b/profiles/wcm_base/modules/contrib/webform/css/webform-admin.css
@@ -147,6 +147,7 @@ html.js div.webform-position {
 tr.webform-add-form .tabledrag-changed {
   display: none;
 }
+#webform-emails tr.webform-add-form,
 #webform-components tr.webform-add-form {
   background-color: inherit;
 }
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter.inc b/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter.inc
index 3de1396f7a85276e78bfce6a89a25de6a3013e96..de356308c928cd597bbaad489faeccf29583e7fa 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter.inc
@@ -1,7 +1,10 @@
 <?php
+
 /**
+ * @file
  * Base class defining the common methods available to exporters.
  */
+
 class webform_exporter {
   public $options = array();
   public $export_wordrap;
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_delimited.inc b/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_delimited.inc
index 1f523a36ec72751ea29d7b6ffd42eb870d4aaeee..20872b7b39407225ffc5a2be9fc4fb594014fc60 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_delimited.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_delimited.inc
@@ -1,11 +1,16 @@
 <?php
+
 /**
+ * @file
  * Webform exporter for creating CSV/TSV delimited files.
  */
+
 class webform_exporter_delimited extends webform_exporter {
+  public $line_ending;
   public $delimiter;
 
   function __construct($options) {
+    $this->line_ending = webform_variable_get('webform_csv_line_ending');
     $this->delimiter = isset($options['delimiter']) ? $options['delimiter'] : ',';
     // Convert tabs.
     if ($this->delimiter == '\t') {
@@ -23,7 +28,7 @@ class webform_exporter_delimited extends webform_exporter {
       // Remove <script> tags, which mysteriously cause Excel not to import.
       $data[$key] = preg_replace('!<(/?script.*?)>!', '[$1]', $data[$key]);
     }
-    $row = implode($this->delimiter, $data) . "\n";
+    $row = implode($this->delimiter, $data) . $this->line_ending;
 
     @fwrite($file_handle, $row);
   }
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_excel_delimited.inc b/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_excel_delimited.inc
index 963076a1372c868861df9b4bc5486a6f4929ce3c..9f77b89163ea0ef74d94dc58a70319faf4d99d04 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_excel_delimited.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_excel_delimited.inc
@@ -1,7 +1,10 @@
 <?php
+
 /**
+ * @file
  * The Excel exporter currently is just a tab-delimited export.
  */
+
 class webform_exporter_excel_delimited extends webform_exporter_delimited {
   function __construct($options) {
     $options['delimiter'] = '\t';
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_excel_xlsx.inc b/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_excel_xlsx.inc
index dbdcaacc65811d506a93c333c35b00629f024c63..072a0b3c928ba2344354739740345e67732ed00e 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_excel_xlsx.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/exporters/webform_exporter_excel_xlsx.inc
@@ -1,7 +1,10 @@
 <?php
+
 /**
+ * @file
  * This exporter creates an XLSX file readable by newer versions of Excel.
  */
+
 class webform_exporter_excel_xlsx extends webform_exporter {
   /**
    * Regular expression that checks for a valid ISO 8601 date/time.
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/webform.admin.inc b/profiles/wcm_base/modules/contrib/webform/includes/webform.admin.inc
index 8306e87ee63a4348a951d77873f3aff27834df2c..e3cf95770d50a3c24b05a58704ebe2defad3c165 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/webform.admin.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/webform.admin.inc
@@ -241,7 +241,7 @@ function webform_admin_settings() {
     '#type' => 'textfield',
     '#title' => t("Select email mapping limit"),
     '#default_value' => webform_variable_get('webform_email_select_max'),
-    '#description' => t('When mapping emails addresses to a select component, limit the choice to components with less than the amount of options indicated. This is to avoid flooding the email settings form. '),
+    '#description' => t('When mapping emails addresses to a select component, limit the choice to components with less than the amount of options indicated. This is to avoid flooding the email settings form.'),
   );
 
   $form = system_settings_form($form);
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/webform.components.inc b/profiles/wcm_base/modules/contrib/webform/includes/webform.components.inc
index c2b9e7338c48a53de9d54dfa9a3826939d16857a..cd0b47d1de77fcfa78b796ecf9835902a2071e23 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/webform.components.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/webform.components.inc
@@ -386,7 +386,6 @@ function webform_component_edit_form($form, $form_state, $node, $component, $clo
   drupal_set_title(t('Edit component: @name', array('@name' => $component['name'])), PASS_THROUGH);
 
   $form['#node'] = $node;
-  $form['#attached']['library'][] = array('webform', 'admin');
   $form['#tree'] = TRUE;
 
   // Print the correct field type specification.
@@ -475,6 +474,17 @@ function webform_component_edit_form($form, $form_state, $node, $component, $clo
     $form['display']['title_display']['#parents'] = array('extra', 'title_display');
   }
 
+  if (webform_component_feature($component['type'], 'description')) {
+    $form['display']['description_above'] = array(
+      '#type' => 'checkbox',
+      '#default_value' => !empty($component['extra']['description_above']),
+      '#title' => t('Description above field'),
+      '#description' => t('Place the description above &mdash; rather than below &mdash; the field.'),
+      '#weight' => 8.5,
+      '#parents' => array('extra', 'description_above'),
+    );
+  }
+
   if (webform_component_feature($component['type'], 'private')) {
     // May user mark fields as Private?
     $form['display']['private'] = array(
@@ -590,6 +600,9 @@ function webform_component_edit_form($form, $form_state, $node, $component, $clo
     unset($form['validation']);
   }
   $form = array_merge($form, $additional_form_elements);
+  // Ensure that the webform admin library is attached, possibly in addition to
+  // component-specific attachments.
+  $form['#attached']['library'][] = array('webform', 'admin');
 
   // Add the submit button.
   $form['actions'] = array(
@@ -672,13 +685,12 @@ function webform_component_edit_form_submit($form, &$form_state) {
 
   // Since Webform components have been updated but the node itself has not
   // been saved, it is necessary to explicitly clear the cache to make sure
-  // the updated webform is visible to anonymous users.
+  // the updated webform is visible to anonymous users. This resets the page
+  // and block caches (only);
   cache_clear_all();
 
-  // Clear the entity cache if Entity Cache module is installed.
-  if (module_exists('entitycache')) {
-    entity_get_controller('node')->resetCache(array($node->nid));
-  }
+  // Refresh the entity cache, should it be cached in persistent storage.
+  entity_get_controller('node')->resetCache(array($node->nid));
 
   $form_state['redirect'] = array('node/' . $node->nid . '/webform/components', isset($cid) ? array('query' => array('cid' => $cid)) : array());
 }
@@ -727,13 +739,12 @@ function webform_component_delete_form_submit($form, &$form_state) {
 
   // Since Webform components have been updated but the node itself has not
   // been saved, it is necessary to explicitly clear the cache to make sure
-  // the updated webform is visible to anonymous users.
+  // the updated webform is visible to anonymous users. This resets the page
+  // and block caches (only);
   cache_clear_all();
 
-  // Clear the entity cache if Entity Cache module is installed.
-  if (module_exists('entitycache')) {
-    entity_get_controller('node')->resetCache(array($node->nid));
-  }
+  // Refresh the entity cache, should it be cached in persistent storage.
+  entity_get_controller('node')->resetCache(array($node->nid));
 
   $form_state['redirect'] = 'node/' . $node->nid . '/webform/components';
 }
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/webform.conditionals.inc b/profiles/wcm_base/modules/contrib/webform/includes/webform.conditionals.inc
index 7578a7bbd4712e8e1dfaeec13f7f16ccd118dfdf..f6abf7f9cc13cdd69cb00854e5da734051d3405d 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/webform.conditionals.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/webform.conditionals.inc
@@ -277,7 +277,7 @@ function theme_webform_conditional_groups($variables) {
       }
       $even_odd = ($index + 1) % 2 ? 'odd' : 'even';
       $element[$key]['weight']['#attributes']['class'] = array('webform-conditional-weight');
-      $data = '<div class="webform-conditional-new">' . $data . t('Add a new condition: ') . drupal_render($element[$key]['new']) . '</div>';
+      $data = '<div class="webform-conditional-new">' . $data . t('Add a new condition:') . ' ' . drupal_render($element[$key]['new']) . '</div>';
       $output .= '<tr class="webform-conditional-new-row ' . $even_odd . '">';
       $output .= '<td>' . $data . '</td>';
       $output .= '<td>' . drupal_render($element[$key]['weight']) . '</td>';
@@ -1426,19 +1426,11 @@ function webform_conditional_value_datetime($input_values) {
  *   +N if $a is below (>) $b
  */
 function webform_compare_select($a, $b, $options) {
-  $options_array = array_keys($options);
+  // Select keys that are integer-like strings are numberic indices in PHP.
+  // Convert the array keys to an array of strings.
+  $options_array = array_map(function($i) {return (string) $i; }, array_keys($options));
   $a_position = array_search($a, $options_array, TRUE);
   $b_position = array_search($b, $options_array, TRUE);
-  if ($a_position === FALSE && $a_position === FALSE) {
-    return NULL;
-  }
-  elseif ($a_position === FALSE) {
-    return 1;
-  }
-  elseif ($b_position === FALSE) {
-    return -1;
-  }
-  else {
-    return $a_position - $b_position;
-  }
+  return ($a_position === FALSE || $a_position === FALSE) ? NULL : $a_position - $b_position;
+
 }
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/webform.emails.inc b/profiles/wcm_base/modules/contrib/webform/includes/webform.emails.inc
index 7f24e03edd8cfcf3880c4c7eee3af88ecbef5041..b6c8d4f39f62e714c2d1d5c0d056299b236ddba4 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/webform.emails.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/webform.emails.inc
@@ -20,6 +20,10 @@ function webform_emails_form($form, $form_state, $node) {
   $form['components'] = array();
 
   foreach ($node->webform['emails'] as $eid => $email) {
+    $form['emails'][$eid]['status'] = array(
+      '#type' => 'checkbox',
+      '#default_value' => $email['status'],
+    );
     $form['emails'][$eid]['email'] = array(
       '#markup' => nl2br(check_plain(implode("\n", webform_format_email_address($email['email'], NULL, $node, NULL, FALSE, FALSE)))),
     );
@@ -36,6 +40,11 @@ function webform_emails_form($form, $form_state, $node) {
     '#tree' => FALSE,
   );
 
+  $form['add']['status'] = array(
+    '#type' => 'checkbox',
+    '#default_value' => TRUE,
+  );
+
   $form['add']['email_option'] = array(
     '#type' => 'radios',
     '#options' => array(
@@ -61,17 +70,24 @@ function webform_emails_form($form, $form_state, $node) {
     $form['add']['email_component']['#disabled'] = TRUE;
   }
 
+  $form['add']['add'] = array(
+    '#type' => 'submit',
+    '#value' => t('Add'),
+    '#validate' => array('webform_email_address_validate'),
+    '#submit' => array('webform_emails_form_submit'),
+  );
+
   $form['actions'] = array(
     '#type' => 'actions',
     '#weight' => 45,
   );
-  $form['actions']['add_button'] = array(
+  $form['actions']['save'] = array(
     '#type' => 'submit',
-    '#value' => t('Add'),
+    '#value' => t('Save'),
+    '#submit' => array('webform_emails_form_status_save'),
+    '#access' => count($node->webform['emails']) > 0,
   );
 
-  $form['#validate'] = array('webform_email_address_validate');
-
   return $form;
 }
 
@@ -87,13 +103,14 @@ function theme_webform_emails_form($variables) {
   $form = $variables['form'];
   $node = $form['#node'];
 
-  $header = array(t('E-mail to'), t('Subject'), t('From'), array('data' => t('Operations'), 'colspan' => 3));
+  $header = array(t('Send'), t('E-mail to'), t('Subject'), t('From'), array('data' => t('Operations'), 'colspan' => 3));
   $rows = array();
 
   if (!empty($form['emails'])) {
     foreach (element_children($form['emails']) as $eid) {
       // Add each component to a table row.
       $rows[] = array(
+        array('data' => drupal_render($form['emails'][$eid]['status']), 'class' => array('webform-email-status', 'checkbox')),
         drupal_render($form['emails'][$eid]['email']),
         drupal_render($form['emails'][$eid]['subject']),
         drupal_render($form['emails'][$eid]['from']),
@@ -104,13 +121,15 @@ function theme_webform_emails_form($variables) {
     }
   }
   else {
-    $rows[] = array(array('data' => t('Currently not sending e-mails, add an e-mail recipient below.'), 'colspan' => 6));
+    $rows[] = array(array('data' => t('Currently not sending e-mails, add an e-mail recipient below.'), 'colspan' => 7));
   }
 
   // Add a row containing form elements for a new item.
+  $add_button = drupal_render($form['add']['add']);
   $row_data = array(
+    array('data' => drupal_render($form['add']['status']), 'class' => array('webform-email-status', 'checkbox')),
     array('colspan' => 3, 'data' => drupal_render($form['add'])),
-    array('colspan' => 3, 'data' => drupal_render($form['add_button'])),
+    array('colspan' => 3, 'data' => $add_button),
   );
   $rows[] = array('data' => $row_data, 'class' => array('webform-add-form'));
 
@@ -152,7 +171,21 @@ function webform_emails_form_submit($form, &$form_state) {
   else {
     $email = $form_state['values']['email_component'];
   }
-  $form_state['redirect'] = array('node/' . $form['#node']->nid . '/webform/emails/new', array('query' => array('option' => $form_state['values']['email_option'], 'email' => trim($email))));
+  $form_state['redirect'] = array('node/' . $form['#node']->nid . '/webform/emails/new', array('query' => array('status' => $form_state['values']['status'], 'option' => $form_state['values']['email_option'], 'email' => trim($email))));
+}
+
+/**
+ * Submit handler for status update.
+ */
+function webform_emails_form_status_save($form, &$form_state) {
+  foreach ($form_state['values']['emails'] as $eid => $status) {
+    db_update('webform_emails')->fields(array(
+      'status' => $status['status']
+    ))
+    ->condition('eid', $eid)
+    ->condition('nid', $form['#node']->nid)
+    ->execute();
+  }
 }
 
 /**
@@ -280,6 +313,14 @@ function webform_email_edit_form($form, $form_state, $node, $email = array(), $c
     $form['from_name_component']['#access'] = FALSE;
   }
 
+  // Add the checkbox to disable the email for current recipients.
+  $form['status'] = array(
+    '#title' => t('Enable sending'),
+    '#description' => t('Uncheck to disable sending this email.'),
+    '#type' => 'checkbox',
+    '#default_value' => $email['status'],
+  );
+
   // Add the template fieldset.
   $form['template'] = array(
     '#type' => 'fieldset',
@@ -392,6 +433,7 @@ function theme_webform_email_edit_form($variables) {
   $details .= drupal_render($form['from_address_option']);
   $details .= drupal_render($form['from_address_mapping']);
   $details .= drupal_render($form['from_name_option']);
+
   $form['details'] = array(
     '#type' => 'fieldset',
     '#title' => t('E-mail header details'),
@@ -436,10 +478,10 @@ function theme_webform_email_component_mapping($variables) {
   $table = theme('table', array('header' => $header, 'rows' => $rows, 'sticky' => FALSE, 'empty' => $empty));
   $description = t('The selected component %name has multiple options. You may enter an e-mail address for each choice.', array('%name' => $element['#title']));
   if ($element['#webform_allow_empty']) {
-    $description .= ' '. t('When that choice is selected, an e-mail will be sent to the corresponding address. If a field is left blank, no e-mail will be sent for that option.');
+    $description .= ' ' . t('When that choice is selected, an e-mail will be sent to the corresponding address. If a field is left blank, no e-mail will be sent for that option.');
   }
   else {
-    $description .= ' '. t('When that choice is selected, an e-mail will be sent from the corresponding address.');
+    $description .= ' ' . t('When that choice is selected, an e-mail will be sent from the corresponding address.');
   }
 
   $wrapper_element = array(
@@ -458,7 +500,7 @@ function theme_webform_email_component_mapping($variables) {
  */
 function webform_email_address_validate($form, &$form_state) {
   if ($form_state['values']['email_option'] == 'custom') {
-    webform_email_validate($form_state['values']['email_custom'], 'email_custom', FALSE, TRUE);
+    webform_email_validate($form_state['values']['email_custom'], 'email_custom', FALSE, TRUE, TRUE);
   }
 }
 
@@ -467,7 +509,7 @@ function webform_email_address_validate($form, &$form_state) {
  */
 function webform_email_edit_form_validate($form, &$form_state) {
   if ($form_state['values']['from_address_option'] == 'custom') {
-    webform_email_validate($form_state['values']['from_address_custom'], 'from_address_custom', FALSE, FALSE);
+    webform_email_validate($form_state['values']['from_address_custom'], 'from_address_custom', FALSE, FALSE, TRUE);
   }
 
   // Validate component-based values for the TO and FROM address.
@@ -478,7 +520,7 @@ function webform_email_edit_form_validate($form, &$form_state) {
         $empty_allowed = $field_name === 'email';
         $multiple_allowed = $field_name === 'email';
         foreach ($form_state['values'][$field_name . '_mapping'][$cid] as $key => &$value) {
-          webform_email_validate($value, "{$field_name}_mapping][$cid][$key", $empty_allowed, $multiple_allowed);
+          webform_email_validate($value, "{$field_name}_mapping][$cid][$key", $empty_allowed, $multiple_allowed, TRUE);
         }
       }
     }
@@ -514,7 +556,7 @@ function webform_email_edit_form_submit($form, &$form_state) {
       // Merge the email mapping(s) into single value(s)
       $cid = $form_state['values'][$field . '_' . $option];
       if (is_numeric($cid) && isset($form_state['values'][$field . '_mapping'][$cid])) {
-        $email['extra'][$field .'_mapping'] = $form_state['values'][$field . '_mapping'][$cid];
+        $email['extra'][$field . '_mapping'] = $form_state['values'][$field . '_mapping'][$cid];
       }
     }
   }
@@ -545,6 +587,8 @@ function webform_email_edit_form_submit($form, &$form_state) {
 
   $email['exclude_empty'] = empty($form_state['values']['exclude_empty']) ? 0 : 1;
 
+  $email['status'] = empty($form_state['values']['status']) ? 0 : 1;
+
   if ($form_state['values']['clone']) {
     drupal_set_message(t('Email settings cloned.'));
     $form_state['values']['eid'] = webform_email_clone($email);
@@ -558,10 +602,8 @@ function webform_email_edit_form_submit($form, &$form_state) {
     webform_email_update($email);
   }
 
-  // Clear the entity cache if Entity Cache module is installed.
-  if (module_exists('entitycache')) {
-    entity_get_controller('node')->resetCache(array($node->nid));
-  }
+  // Refresh the entity cache, should it be cached in persistent storage.
+  entity_get_controller('node')->resetCache(array($node->nid));
 
   $form_state['redirect'] = array('node/' . $node->nid . '/webform/emails');
 }
@@ -606,10 +648,8 @@ function webform_email_delete_form_submit($form, &$form_state) {
   unset($node->webform['emails'][$email['eid']]);
   webform_check_record($node);
 
-  // Clear the entity cache if Entity Cache module is installed.
-  if (module_exists('entitycache')) {
-    entity_get_controller('node')->resetCache(array($node->nid));
-  }
+  // Refresh the entity cache, should it be cached in persistent storage.
+  entity_get_controller('node')->resetCache(array($node->nid));
 
   $form_state['redirect'] = 'node/' . $node->nid . '/webform/emails';
 }
@@ -631,11 +671,12 @@ function webform_email_load($eid, $nid) {
       'html' => webform_variable_get('webform_default_format'),
       'attachments' => 0,
       'extra' => '',
+      'status' => 1,
     );
   }
   else {
     $email = isset($node->webform['emails'][$eid]) ? $node->webform['emails'][$eid] : FALSE;
-    if (webform_variable_get('webform_format_override')) {
+    if ($email && webform_variable_get('webform_format_override')) {
       $email['html'] = webform_variable_get('webform_default_format');
     }
   }
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/webform.pages.inc b/profiles/wcm_base/modules/contrib/webform/includes/webform.pages.inc
index a4c35ec334d28943f8b5963687695a573bf030fb..782dfb94bf8dde43a406c071799dc20b241fca69 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/webform.pages.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/webform.pages.inc
@@ -14,6 +14,11 @@ function webform_configure_form($form, &$form_state, $node) {
 
   $form['#attached']['library'][] = array('webform', 'admin');
 
+  // Refresh the entity cache to get the lastest submission number.
+  $nid = $node->nid;
+  entity_get_controller('node')->resetCache(array($nid));
+  $node = node_load($nid);
+
   $form['#node'] = $node;
 
   $form['#submit'] = array(
@@ -299,7 +304,7 @@ function webform_configure_form($form, &$form_state, $node) {
     '#title' => t('Preview message'),
     '#default_value' => $node->webform['preview_message'],
     '#format' => $node->webform['preview_message_format'],
-    '#description' => t('A message to be displayed on the preview page. If left blank, the message "!default" will be used. Supports Webform token replacements.', array('!default' => $preview_default_message))  . ' ' . theme('webform_token_help', array('groups' => array('node', 'submission'))),
+    '#description' => t('A message to be displayed on the preview page. If left blank, the message "!default" will be used. Supports Webform token replacements.', array('!default' => $preview_default_message)) . ' ' . theme('webform_token_help', array('groups' => array('node', 'submission'))),
   );
   $form['preview']['settings']['preview_components'] = array(
     '#type' => 'select',
@@ -414,14 +419,6 @@ function webform_configure_form_validate($form, &$form_state) {
     }
   }
 
-  // Serial number must be a positive integer greater than any existing serial number.
-  $next_min = _webform_submission_serial_next_value_used($form['#node']->nid);
-  if ((int) $form['advanced']['next_serial']['#value'] < $next_min) {
-    form_error($form['advanced']['next_serial'],
-               t('The next submission number must be at least %min (greater than any existing serial number).',
-                 array('%min' => $next_min)));
-  }
-
   // Prohibit the combination of confidential + per-user limit + ip-only
   // submission tracking for anonymous users as it would not be enforceable.
   if (webform_variable_get('webform_tracking_mode') == 'ip_address' &&
@@ -517,8 +514,17 @@ function webform_configure_form_submit($form, &$form_state) {
   // Set submit button text.
   $node->webform['submit_text'] = $form_state['values']['submit_text'];
 
-  // Set next serial number.
-  $node->webform['next_serial'] = (int) $form_state['values']['next_serial'];
+  // Set next serial number. It must be a positive integer greater than any
+  // existing serial number, which could have increased while this form was
+  // being edited.
+  $next_min = _webform_submission_serial_next_value_used($node->nid);
+  $next_serial = (int)$form_state['values']['next_serial'];
+  if ($next_serial < $next_min) {
+    drupal_set_message(t('The next submission number was increased to @min to make it higher than existing submissions.',
+                         array('@min' => $next_min)));
+    $next_serial = $next_min;
+  }
+  $node->webform['next_serial'] = $next_serial;
 }
 
 /**
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/webform.report.inc b/profiles/wcm_base/modules/contrib/webform/includes/webform.report.inc
index d2c81110ea0384659c6360684d2785e5b3c09b55..71fb469ab43a9129dc932e60eb694dd071caa668 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/webform.report.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/webform.report.inc
@@ -351,9 +351,8 @@ function webform_results_clear_form_submit($form, &$form_state) {
   webform_results_clear($form_state['values']['nid']);
   $node = node_load($form_state['values']['nid']);
   $title = $node->title;
-  $message = t('Webform %title entries cleared.', array('%title' => $title));
-  drupal_set_message($message);
-  watchdog('webform', $message);
+  drupal_set_message(t('Webform %title entries cleared.', array('%title' => $title)));
+  watchdog('webform', 'Webform %title entries cleared.', array('%title' => $title));
   $form_state['redirect'] = 'node/' . $form_state['values']['nid'] . '/webform-results';
 }
 
@@ -635,7 +634,7 @@ function webform_results_download_range_validate($element, $form_state) {
     'batch_size' => 1,
     'batch_number' => 0,
   );
-  if (!webform_download_sids_count($form_state['values']['node']->nid, $range_options)) {
+  if (!form_get_errors() && !webform_download_sids_count($form_state['values']['node']->nid, $range_options)) {
     form_error($element['range_type'], t('The specified range will not return any results.'));
   }
 
@@ -854,8 +853,10 @@ function webform_results_export($node, $format = 'delimited', $options = array()
     $col_count = count($row) > $col_count ? count($row) : $col_count;
   }
 
-  // Write data from submissions.
-  $rows = webform_results_download_rows($node, $options);
+  // Write data from submissions. $last_is is non_NULL to trigger returning it
+  // by reference.
+  $last_sid = TRUE;
+  $rows = webform_results_download_rows($node, $options, 0, $last_sid);
   foreach ($rows as $row) {
     $exporter->add_row($handle, $row, $row_count);
     $row_count++;
@@ -872,7 +873,7 @@ function webform_results_export($node, $format = 'delimited', $options = array()
   $export_info['file_name'] = $file_name;
   $export_info['row_count'] = $row_count;
   $export_info['col_count'] = $col_count;
-  $export_info['last_sid'] = end($submissions) ? key($submissions) : NULL;
+  $export_info['last_sid'] = $last_sid;
   $export_info['exporter'] = $exporter;
 
   return $export_info;
@@ -983,16 +984,18 @@ function webform_results_download_headers($node, $options) {
  *   through from the GUI interface.
  * @param $serial_start
  *   The starting position for the Serial column in the output.
+ * @param $last_sid
+ *   If set to a non-NULL value, the last sid will be returned.
  *
  * @return $rows
  *   An array of rows built according to the provided $serial_start and
  *   $pager_count variables. Note that the current page number is determined
  *   by the super-global $_GET['page'] variable.
  */
-function webform_results_download_rows($node, $options, $serial_start = 0) {
+function webform_results_download_rows($node, $options, $serial_start = 0, $last_sid = NULL) {
   // Get all the required submissions for the download.
   $filters['nid'] = $node->nid;
-  if (isset($options['sids'])){
+  if (isset($options['sids'])) {
     $filters['sid'] = $options['sids'];
   }
   elseif (!empty($options['completion_type']) && $options['completion_type'] !== 'all') {
@@ -1001,6 +1004,10 @@ function webform_results_download_rows($node, $options, $serial_start = 0) {
 
   $submissions = webform_get_submissions($filters, NULL);
 
+  if (isset($last_sid)) {
+    $last_sid = end($submissions) ? key($submissions) : NULL;
+  }
+
   return webform_results_download_rows_process($node, $options, $serial_start, $submissions);
 }
 
@@ -1796,7 +1803,7 @@ function webform_download_sids_query($nid, $range_options, $uid = NULL) {
     case 'range':
       // Submissions Start-End.
       $query->condition('ws.sid', $range_options['start'], '>=');
-      if ($range_options['end']){
+      if ($range_options['end']) {
         $query->condition('ws.sid', $range_options['end'], '<=');
       }
       $query->orderBy('ws.sid', 'ASC');
@@ -1804,7 +1811,7 @@ function webform_download_sids_query($nid, $range_options, $uid = NULL) {
     case 'range_serial':
       // Submissions Start-End, using serial numbers.
       $query->condition('ws.serial', $range_options['start'], '>=');
-      if ($range_options['end']){
+      if ($range_options['end']) {
         $query->condition('ws.serial', $range_options['end'], '<=');
       }
       $query->orderBy('ws.serial', 'ASC');
@@ -1894,5 +1901,5 @@ function webform_download_latest_start_sid($nid, $latest_count, $completion_type
   }
 
   $latest_sids = $query->execute()->fetchCol();
-  return min($latest_sids);
+  return $latest_sids ? min($latest_sids) : 1;
 }
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/webform.submissions.inc b/profiles/wcm_base/modules/contrib/webform/includes/webform.submissions.inc
index 3c0fb59c8b9c65b234b030bbbb945f91dc3439e3..3d2fcee675a6820a1f7b0c3f521561e62fdb213e 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/webform.submissions.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/webform.submissions.inc
@@ -232,6 +232,10 @@ function webform_submission_send_mail($node, $submission, $emails = NULL) {
   // Create a themed message for mailing.
   $send_count = 0;
   foreach ($emails as $eid => $email) {
+    // Continue with next email recipients array if disabled for current.
+    if (!$email['status'])
+      continue;
+
     // Set the HTML property based on availablity of MIME Mail.
     $email['html'] = ($email['html'] && webform_variable_get('webform_email_html_capable'));
 
@@ -316,7 +320,8 @@ function webform_submission_send_mail($node, $submission, $emails = NULL) {
     // Verify that this submission is not attempting to send any spam hacks.
     foreach ($addresses_final as $address) {
       if (_webform_submission_spam_check($address, $email['subject'], $email['from'], $email['headers'])) {
-        watchdog('webform', 'Possible spam attempt from @remote_addr' . "<br />\n" . nl2br(htmlentities($email['message'])), array('@remote_add' => ip_address()));
+        watchdog('webform', 'Possible spam attempt from @remote !message',
+                 array('@remote' => ip_address(), '!message'=> "<br />\n" . nl2br(htmlentities($email['message']))));
         drupal_set_message(t('Illegal information. Data not submitted.'), 'error');
         return FALSE;
       }
@@ -519,8 +524,8 @@ function webform_submission_resend($form, $form_state, $node, $submission) {
     
     $form['resend'][$eid] = array(
       '#type' => 'checkbox',
-      '#default_value' => $valid_email ? TRUE : FALSE,
-      '#disabled' => $valid_email ? FALSE : TRUE,
+      '#default_value' => $valid_email && $email['status'],
+      '#disabled' => !$valid_email,
     );
     $form['emails'][$eid]['email'] = array(
       '#markup' => nl2br(check_plain(implode("\n", $addresses))),
@@ -591,7 +596,7 @@ function webform_submission_resend_submit($form, &$form_state) {
 function theme_webform_submission_resend($variables) {
   $form = $variables['form'];
 
-  $header = array('', t('E-mail to'), t('Subject'));
+  $header = array(t('Send'), t('E-mail to'), t('Subject'));
   $rows = array();
   if (!empty($form['emails'])) {
     foreach (element_children($form['emails']) as $eid) {
@@ -638,7 +643,7 @@ function webform_submission_render($node, $submission, $email, $format, $exclude
       unset($components[$cid]);
     }
     if ($email && $email['exclude_empty']) {
-      foreach($submission->data as $cid => $data) {
+      foreach ($submission->data as $cid => $data) {
         if (!isset($data[0]) || $data[0] == '') {
           unset($components[$cid]);
         }
diff --git a/profiles/wcm_base/modules/contrib/webform/includes/webform.webformconditionals.inc b/profiles/wcm_base/modules/contrib/webform/includes/webform.webformconditionals.inc
index d406838c6f306552c9cd6c38f1a78afe6ab72ea5..92d5dca6cee98b478b9feee87ac8585e33b74e75 100644
--- a/profiles/wcm_base/modules/contrib/webform/includes/webform.webformconditionals.inc
+++ b/profiles/wcm_base/modules/contrib/webform/includes/webform.webformconditionals.inc
@@ -28,6 +28,8 @@ class WebformConditionals {
   protected $childrenMap;
   protected $visibilityMap;
   protected $requiredMap;
+  protected $setMap;
+  protected $markupMap;
 
   public $errors;
 
@@ -64,7 +66,7 @@ class WebformConditionals {
     $conditionals = $this->node->webform['conditionals'];
     $errors = array();
 
-    // Generate a component to condional map for conditional targets.
+    // Generate a component to conditional map for conditional targets.
     $cid_to_target_rgid = array();
     $cid_hidden = array();
     foreach ($conditionals as $rgid => $conditional) {
@@ -315,14 +317,19 @@ class WebformConditionals {
       array_walk_recursive($this->visibilityMap, function (&$status) {
         $status = WebformConditionals::componentShown;
       });
-      // Create an empty required map
+      // Create empty required, set, and markup maps.
       $this->requiredMap = array_fill(1, count($this->pageMap), array());
+      $this->setMap = $this->requiredMap;
+      $this->markupMap = $this->requiredMap;
 
-    } else {
+    } 
+    else {
       array_walk($this->visibilityMap[$page_num], function (&$status) {
         $status = WebformConditionals::componentShown;
       });
       $this->requiredMap[$page_num] = array();
+      $this->setMap[$page_num] = array();
+      $this->markupMap[$page_num] = array();
     }
 
     module_load_include('inc', 'webform', 'includes/webform.conditionals');
@@ -370,6 +377,10 @@ class WebformConditionals {
 
           // Perform the comparison callback and build the results for this group.
           $comparison_callback = $operator_info[$rule['operator']]['comparison callback'];
+          // Contrib caching, such as entitycache, may have loaded the node
+          // without building it. It is possible that the component include file
+          // hasn't been included yet. See #2529246.
+          webform_component_include($source_component['type']);
           $conditional_results[] = $comparison_callback($source_values, $rule['value'], $source_component);
 
           // Record page number to later determine any intra-page dependency on this source.
@@ -398,8 +409,19 @@ class WebformConditionals {
               $this->requiredMap[$page_num][$target] = $action_result;
               break;
             case 'set':
-              if ($action_result && empty($targetLocked[$target]) && $components[$target]['type'] != 'markup') {
-                $input_values[$target] = $action['argument'];
+              if ($components[$target]['type'] == 'markup') {
+                $this->markupMap[$page_num][$target] = FALSE;
+              }
+              if ($action_result && empty($targetLocked[$target])) {
+                if ($components[$target]['type'] == 'markup') {
+                  $this->markupMap[$page_num][$target] = $action['argument'];
+                } 
+                else {
+                  $input_values[$target] = isset($input_values[$target]) && is_array($input_values[$target])
+                                              ? array($action['argument'])
+                                              : $action['argument'];
+                  $this->setMap[$page_num][$target] = TRUE;
+                }
               }
               break;
           }
@@ -412,6 +434,13 @@ class WebformConditionals {
     return $input_values;
   }
 
+  /**
+   * Returns whether the conditionals have been executed yet.
+   */
+  function isExecuted() {
+    return (boolean)($this->visibilityMap);
+  }
+
   /**
    * Returns whether a given component is always hidden, always shown, or might
    * be shown depending upon other sources on the same page.
@@ -429,7 +458,7 @@ class WebformConditionals {
     if (!$this->visibilityMap) {
       // The conditionals have not yet been executed on a submission.
       $this->executeConditionals(array(), 0);
-      watchdog('webform', 'WebformConditionals::componentVisibility called prior to evaluating a submission.', 'error');
+      watchdog('webform', 'WebformConditionals::componentVisibility called prior to evaluating a submission.', array(), WATCHDOG_ERROR);
     }
     return isset($this->visibilityMap[$page_num][$cid]) ? $this->visibilityMap[$page_num][$cid] : self::componentShown;
   }
@@ -449,7 +478,8 @@ class WebformConditionals {
     $result = self::componentHidden;
     if ($page_num == 1 || empty($this->visibilityMap[$page_num])) {
       $result = self::componentShown;
-    } elseif (($page_map = $this->pageMap[$page_num]) && $this->componentVisibility(reset($page_map), $page_num)) {
+    } 
+    elseif (($page_map = $this->pageMap[$page_num]) && $this->componentVisibility(reset($page_map), $page_num)) {
       while ($cid = next($page_map)) {
         if ($this->componentVisibility($cid, $page_num) != self::componentHidden) {
           $result = self::componentShown;
@@ -461,13 +491,13 @@ class WebformConditionals {
   }
 
   /**
-   * Returns whether a given component is always required, always opption, or
+   * Returns whether a given component is always required, always optional, or
    * unchanged by conditional logic.
    *
    * Assumes that the conditionals have already been executed on the given page.
    *
    * @param integer $cid
-   *   The component id of the component whose required state is being sought
+   *   The component id of the component whose required state is being sought.
    * @param integer $page_num
    *   The page number that the component is on.
    * @return boolean
@@ -477,9 +507,51 @@ class WebformConditionals {
     if (!$this->requiredMap) {
       // The conditionals have not yet been executed on a submission.
       $this->executeConditionals(array(), 0);
-      watchdog('webform', 'WebformConditionals::componentRequired called prior to evaluating a submission.', 'error');
+      watchdog('webform', 'WebformConditionals::componentRequired called prior to evaluating a submission.', array(), WATCHDOG_ERROR);
     }
     return isset($this->requiredMap[$page_num][$cid]) ? $this->requiredMap[$page_num][$cid] : NULL;
   }
 
+    /**
+   * Returns whether a given component has been set by conditional logic.
+   *
+   * Assumes that the conditionals have already been executed on the given page.
+   *
+   * @param integer $cid
+   *   The component id of the component whose set state is being sought.
+   * @param integer $page_num
+   *   The page number that the component is on.
+   * @return boolean
+   *   Whether the component was set based on conditionals.
+   */
+  function componentSet($cid, $page_num) {
+    if (!$this->setMap) {
+      // The conditionals have not yet been executed on a submission.
+      $this->executeConditionals(array(), 0);
+      watchdog('webform', 'WebformConditionals::componentSet called prior to evaluating a submission.', array(), WATCHDOG_ERROR);
+    }
+    return isset($this->setMap[$page_num][$cid]) ? $this->setMap[$page_num][$cid] : NULL;
+  }
+
+    /**
+   * Returns the calculated markup as set by conditional logic.
+   *
+   * Assumes that the conditionals have already been executed on the given page.
+   *
+   * @param integer $cid
+   *   The component id of the component whose set state is being sought.
+   * @param integer $page_num
+   *   The page number that the component is on.
+   * @return string
+   *   The conditional markup, or NULL if none.
+   */
+  function componentMarkup($cid, $page_num) {
+    if (!$this->markupMap) {
+      // The conditionals have not yet been executed on a submission.
+      $this->executeConditionals(array(), 0);
+      watchdog('webform', 'WebformConditionals::componentMarkup called prior to evaluating a submission.', array(), WATCHDOG_ERROR);
+    }
+    return isset($this->markupMap[$page_num][$cid]) ? $this->markupMap[$page_num][$cid] : NULL;
+  }
+
 }
diff --git a/profiles/wcm_base/modules/contrib/webform/js/node-type-form.js b/profiles/wcm_base/modules/contrib/webform/js/node-type-form.js
index 9310bb7ef21da838768c3345fff9c265555d1087..d2547e172fc4f4b816c38c13edf4f9dd7ab98503 100644
--- a/profiles/wcm_base/modules/contrib/webform/js/node-type-form.js
+++ b/profiles/wcm_base/modules/contrib/webform/js/node-type-form.js
@@ -1,10 +1,18 @@
+/**
+ * @file
+ * Enhancements for webform node type forms.
+ */
+
 (function ($) {
+
+  "use strict";
+
   Drupal.behaviors.webformContentTypes = {
     attach: function (context) {
       // Provide the vertical tab summaries.
-      $('fieldset#edit-webform', context).drupalSetSummary(function(context) {
+      $('fieldset#edit-webform', context).drupalSetSummary(function (context) {
         var vals = [];
-        $('input[type=checkbox]', context).each(function() {
+        $('input[type=checkbox]', context).each(function () {
           if (this.checked && this.attributes['data-enabled-description']) {
             vals.push(this.attributes['data-enabled-description'].value);
           }
diff --git a/profiles/wcm_base/modules/contrib/webform/js/select-admin.js b/profiles/wcm_base/modules/contrib/webform/js/select-admin.js
index f6cfcdd4ebd7383d4fbaa67f2aaa938dfb1d6c85..919b5d17b85df96e0eab8a27c24a347793fdebe1 100644
--- a/profiles/wcm_base/modules/contrib/webform/js/select-admin.js
+++ b/profiles/wcm_base/modules/contrib/webform/js/select-admin.js
@@ -1,4 +1,3 @@
-
 /**
  * @file
  * Enhancements for select list configuration options.
@@ -6,53 +5,63 @@
 
 (function ($) {
 
-Drupal.behaviors.webformSelectLoadOptions = {};
-Drupal.behaviors.webformSelectLoadOptions.attach = function(context) {
-  settings = Drupal.settings;
+  "use strict";
+
+  Drupal.behaviors.webformSelectLoadOptions = {};
+  Drupal.behaviors.webformSelectLoadOptions.attach = function (context) {
 
-  $('#edit-extra-options-source', context).change(function() {
-    var url = settings.webform.selectOptionsUrl + '/' + this.value;
-    $.ajax({
-      url: url,
-      success: Drupal.webform.selectOptionsLoad,
-      dataType: 'json'
+    $('#edit-extra-options-source', context).change(function () {
+      var url = Drupal.settings.webform.selectOptionsUrl + '/' + this.value;
+      $.ajax({
+        url: url,
+        success: Drupal.webform.selectOptionsLoad,
+        dataType: 'json'
+      });
     });
-  });
-}
-
-Drupal.webform = Drupal.webform || {};
-
-Drupal.webform.selectOptionsOriginal = false;
-Drupal.webform.selectOptionsLoad = function(result) {
-  if (Drupal.optionsElement) {
-    if (result.options) {
-      // Save the current select options the first time a new list is chosen.
-      if (Drupal.webform.selectOptionsOriginal === false) {
-        Drupal.webform.selectOptionsOriginal = $(Drupal.optionElements[result.elementId].manualOptionsElement).val();
+  };
+
+  Drupal.webform = Drupal.webform || {};
+
+  Drupal.webform.selectOptionsOriginal = false;
+  Drupal.webform.selectOptionsLoad = function (result) {
+    if (Drupal.optionsElement) {
+      if (result.options) {
+        // Save the current select options the first time a new list is chosen.
+        if (Drupal.webform.selectOptionsOriginal === false) {
+          Drupal.webform.selectOptionsOriginal = $(Drupal.optionElements[result.elementId].manualOptionsElement).val();
+        }
+        $(Drupal.optionElements[result.elementId].manualOptionsElement).val(result.options);
+        Drupal.optionElements[result.elementId].disable();
+        Drupal.optionElements[result.elementId].updateWidgetElements();
+      }
+      else {
+        Drupal.optionElements[result.elementId].enable();
+        if (Drupal.webform.selectOptionsOriginal) {
+          $(Drupal.optionElements[result.elementId].manualOptionsElement).val(Drupal.webform.selectOptionsOriginal);
+          Drupal.optionElements[result.elementId].updateWidgetElements();
+          Drupal.webform.selectOptionsOriginal = false;
+        }
       }
-      $(Drupal.optionElements[result.elementId].manualOptionsElement).val(result.options);
-      Drupal.optionElements[result.elementId].disable();
-      Drupal.optionElements[result.elementId].updateWidgetElements();
     }
     else {
-      Drupal.optionElements[result.elementId].enable();
-      if (Drupal.webform.selectOptionsOriginal) {
-        $(Drupal.optionElements[result.elementId].manualOptionsElement).val(Drupal.webform.selectOptionsOriginal);
-        Drupal.optionElements[result.elementId].updateWidgetElements();
-        Drupal.webform.selectOptionsOriginal = false;
+      var $element = $('#' + result.elementId);
+      $element.webformProp('readonly', result.options);
+      if (result.options) {
+        $element.val(result.options);
       }
     }
   }
-  else {
-    var $element = $('#' + result.elementId);
-    if (result.options) {
-      $element.val(result.options);
-      $.fn.prop ? $element.prop('readonly', true) : $element.attr('readonly', 'readonly');
+
+  /**
+   * Make a prop shim for jQuery < 1.9.
+   */
+  $.fn.webformProp = $.fn.webformProp || function (name, value) {
+    if (value) {
+      return $.fn.prop ? this.prop(name, true) : this.attr(name, true);
     }
     else {
-      $.fn.prop ? $element.prop('readonly', false) : $element.removeAttr('readonly');
+      return $.fn.prop ? this.prop(name, false) : this.removeAttr(name);
     }
-  }
-}
+  };
 
 })(jQuery);
diff --git a/profiles/wcm_base/modules/contrib/webform/js/webform-admin.js b/profiles/wcm_base/modules/contrib/webform/js/webform-admin.js
index 2050649abda73198b4d9209f1e0940924e896855..3fd774c8ae6a213036b84b7ae71136913937cb94 100644
--- a/profiles/wcm_base/modules/contrib/webform/js/webform-admin.js
+++ b/profiles/wcm_base/modules/contrib/webform/js/webform-admin.js
@@ -1,345 +1,354 @@
-(function ($) {
-
 /**
+ * @file
  * Webform node form interface enhancments.
  */
 
-Drupal.behaviors.webformAdmin = {};
-Drupal.behaviors.webformAdmin.attach = function(context) {
-  // On click or change, make a parent radio button selected.
-  Drupal.webform.setActive(context);
-  Drupal.webform.updateTemplate(context);
-  // Update the template select list upon changing a template.
-  // Select all link for file extensions.
-  Drupal.webform.selectCheckboxesLink(context);
-  // Enhance the normal tableselect.js file to support indentations.
-  Drupal.webform.tableSelectIndentation(context);
-  // Automatically download exports if available.
-  Drupal.webform.downloadExport(context);
-  // Enhancements for the conditionals administrative page.
-  Drupal.webform.conditionalAdmin(context);
-  // Trigger radio/checkbox change when label click automatically selected by
-  // browser.
-  Drupal.webform.radioLabelAutoClick(context);
-}
-
-Drupal.webform = Drupal.webform || {};
-
-Drupal.webform.setActive = function(context) {
-  var setActiveOnChange = function(e) {
-    if ($(this).val()) {
-      var $checkbox = $(this).closest('.form-type-radio').find('input[type=radio]');
-      $.fn.prop ? $checkbox.prop('checked', true) : $checkbox.attr('checked', true);
-    }
-    e.preventDefault();
-  };
-  var setActiveOnClick = function(e) {
-    var $checkbox = $(this).closest('.form-type-radio').find('input[type=radio]');
-    $.fn.prop ? $checkbox.prop('checked', true) : $checkbox.attr('checked', true);
+(function ($) {
+
+  "use strict";
+
+  Drupal.behaviors.webformAdmin = {};
+  Drupal.behaviors.webformAdmin.attach = function (context) {
+    // On click or change, make a parent radio button selected.
+    Drupal.webform.setActive(context);
+    Drupal.webform.updateTemplate(context);
+    // Update the template select list upon changing a template.
+    // Select all link for file extensions.
+    Drupal.webform.selectCheckboxesLink(context);
+    // Enhance the normal tableselect.js file to support indentations.
+    Drupal.webform.tableSelectIndentation(context);
+    // Automatically download exports if available.
+    Drupal.webform.downloadExport(context);
+    // Enhancements for the conditionals administrative page.
+    Drupal.webform.conditionalAdmin(context);
+    // Trigger radio/checkbox change when label click automatically selected by
+    // browser.
+    Drupal.webform.radioLabelAutoClick(context);
   };
-  $('.webform-inline-radio', context).click(setActiveOnClick);
-  $('.webform-set-active', context).change(setActiveOnChange);
-
-  // Firefox improperly selects the parent radio button when clicking inside
-  // a label that contains an input field. The only way of preventing this
-  // currently is to remove the "for" attribute on the label.
-  // See https://bugzilla.mozilla.org/show_bug.cgi?id=213519.
-  if (navigator.userAgent.match(/Firefox/)) {
-    $('.webform-inline-radio', context).removeAttr('for');
-  }
-};
-
-// Upldate e-mail templates between default and custom.
-Drupal.webform.updateTemplate = function(context) {
-  var defaultTemplate = $('#edit-templates-default').val();
-  var $templateSelect = $('#webform-template-fieldset select#edit-template-option', context);
-  var $templateTextarea = $('#webform-template-fieldset textarea:visible', context);
-
-  var updateTemplateSelect = function() {
-    if ($(this).val() == defaultTemplate) {
-      $templateSelect.val('default');
-    }
-    else {
-      $templateSelect.val('custom');
+
+  Drupal.webform = Drupal.webform || {};
+
+  Drupal.webform.setActive = function (context) {
+    $('.webform-inline-radio', context).click(function (e) {
+      $(this).closest('.form-type-radio').find('input[type=radio]').webformProp('checked', true);
+    });
+    $('.webform-set-active', context).change(function (e) {
+      if ($(this).val()) {
+        $(this).closest('.form-type-radio').find('input[type=radio]').webformProp('checked', true);
+      }
+      e.preventDefault();
+    });
+
+    // Firefox improperly selects the parent radio button when clicking inside
+    // a label that contains an input field. The only way of preventing this
+    // currently is to remove the "for" attribute on the label.
+    // See https://bugzilla.mozilla.org/show_bug.cgi?id=213519.
+    if (navigator.userAgent.match(/Firefox/)) {
+      $('.webform-inline-radio', context).removeAttr('for');
     }
-  }
+  };
 
-  var updateTemplateText = function() {
-    if ($(this).val() == 'default' && $templateTextarea.val() != defaultTemplate) {
-      if (confirm(Drupal.settings.webform.revertConfirm)) {
-        $templateTextarea.val(defaultTemplate);
+  // Update e-mail templates between default and custom.
+  Drupal.webform.updateTemplate = function (context) {
+    var defaultTemplate = $('#edit-templates-default').val();
+    var $templateSelect = $('#webform-template-fieldset select#edit-template-option', context);
+    var $templateTextarea = $('#webform-template-fieldset textarea:visible', context);
+
+    var updateTemplateSelect = function () {
+      if ($(this).val() == defaultTemplate) {
+        $templateSelect.val('default');
       }
       else {
-        $(this).val('custom');
+        $templateSelect.val('custom');
       }
-    }
-  }
-
-  $templateTextarea.keyup(updateTemplateSelect);
-  $templateSelect.change(updateTemplateText);
-}
-
-Drupal.webform.selectCheckboxesLink = function(context) {
-  function selectCheckboxes() {
-    var group = this.className.replace(/.*?webform-select-link-([^ ]*).*/, '$1');
-    var $checkboxes = $('.webform-select-group-' + group + ' input[type=checkbox]');
-    var reverseCheck = !$checkboxes[0].checked;
-    $checkboxes.each(function() {
-      this.checked = reverseCheck;
-    });
-    $checkboxes.trigger('change');
-    return false;
-  }
-  $('a.webform-select-link', context).click(selectCheckboxes);
-}
-
-Drupal.webform.tableSelectIndentation = function(context) {
-  var $tables = $('th.select-all', context).parents('table');
-  $tables.find('input.form-checkbox').change(function() {
-    var $rows = $(this).parents('table:first').find('tr');
-    var $checkbox;
-    var row = $(this).parents('tr:first').get(0);
-    var rowNumber = $rows.index(row);
-    var rowTotal = $rows.size();
-    var indentLevel = $(row).find('div.indentation').size();
-    for (var n = rowNumber + 1; n < rowTotal; n++) {
-      if ($rows.eq(n).find('div.indentation').size() <= indentLevel) {
-        break;
+    };
+
+    var updateTemplateText = function () {
+      if ($(this).val() == 'default' && $templateTextarea.val() != defaultTemplate) {
+        if (confirm(Drupal.settings.webform.revertConfirm)) {
+          $templateTextarea.val(defaultTemplate);
+        }
+        else {
+          $(this).val('custom');
+        }
       }
-      $checkbox = $rows.eq(n).find('input.form-checkbox');
-      $.fn.prop ? $checkbox.prop('checked', this.checked) : $checkbox.attr('checked', this.checked);
+    };
+
+    $templateTextarea.keyup(updateTemplateSelect);
+    $templateSelect.change(updateTemplateText);
+  };
+
+  Drupal.webform.selectCheckboxesLink = function (context) {
+    function selectCheckboxes() {
+      var group = this.className.replace(/.*?webform-select-link-([^ ]*).*/, '$1');
+      var $checkboxes = $('.webform-select-group-' + group + ' input[type=checkbox]');
+      var reverseCheck = !$checkboxes[0].checked;
+      $checkboxes.each(function () {
+        this.checked = reverseCheck;
+      });
+      $checkboxes.trigger('change');
+      return false;
     }
-  });
-}
+    $('a.webform-select-link', context).click(selectCheckboxes);
+  };
 
-/**
- * Attach behaviors for Webform results download page.
- */
-Drupal.webform.downloadExport = function(context) {
-  if (context === document && Drupal.settings && Drupal.settings.webformExport && document.cookie.match(/webform_export_info=1/)) {
-    window.location = Drupal.settings.webformExport;
-    delete Drupal.settings.webformExport;
-  }
-}
+  Drupal.webform.tableSelectIndentation = function (context) {
+    var $tables = $('th.select-all', context).parents('table');
+    $tables.find('input.form-checkbox').change(function () {
+      var $rows = $(this).parents('table:first').find('tr');
+      var row = $(this).parents('tr:first').get(0);
+      var rowNumber = $rows.index(row);
+      var rowTotal = $rows.size();
+      var indentLevel = $(row).find('div.indentation').size();
+      for (var n = rowNumber + 1; n < rowTotal; n++) {
+        if ($rows.eq(n).find('div.indentation').size() <= indentLevel) {
+          break;
+        }
+        $rows.eq(n).find('input.form-checkbox').webformProp('checked', this.checked);
+      }
+    });
+  };
 
-/**
- * Attach behaviors for Webform conditional administration.
- */
-Drupal.webform.conditionalAdmin = function(context) {
-  var $context = $(context);
-  // Bind to the entire form and allow events to bubble-up from elements. This
-  // saves a lot of processing when new conditions are added/removed.
-  $context.find('#webform-conditionals-ajax:not(.webform-conditional-processed)')
+  /**
+   * Attach behaviors for Webform results download page.
+   */
+  Drupal.webform.downloadExport = function (context) {
+    if (context === document && Drupal.settings && Drupal.settings.webformExport && document.cookie.match(/webform_export_info=1/)) {
+      window.location = Drupal.settings.webformExport;
+      delete Drupal.settings.webformExport;
+    }
+  };
+
+  /**
+   * Attach behaviors for Webform conditional administration.
+   */
+  Drupal.webform.conditionalAdmin = function (context) {
+    var $context = $(context);
+    // Bind to the entire form and allow events to bubble-up from elements. This
+    // saves a lot of processing when new conditions are added/removed.
+    $context.find('#webform-conditionals-ajax:not(.webform-conditional-processed)')
       .addClass('webform-conditional-processed')
-      .bind('change', function(e) {
+      .bind('change', function (e) {
+
+        var $target = $(e.target);
+        if ($target.is('.webform-conditional-source select')) {
+          Drupal.webform.conditionalSourceChange.apply(e.target);
+        }
+
+        if ($target.is('.webform-conditional-operator select')) {
+          Drupal.webform.conditionalOperatorChange.apply(e.target);
+        }
+
+        if ($target.is('.webform-conditional-andor select')) {
+          Drupal.webform.conditionalAndOrChange.apply(e.target);
+        }
+
+        if ($target.is('.webform-conditional-action select')) {
+          Drupal.webform.conditionalActionChange.apply(e.target);
+        }
+      });
+
+    // Add event handlers to delete the entire row if the last rule or action is removed.
+    $context.find('.webform-conditional-rule-remove:not(.webform-conditional-processed)').bind('click', function () {
+      this.webformRemoveClass = '.webform-conditional-rule-remove';
+      window.setTimeout($.proxy(Drupal.webform.conditionalRemove, this), 100);
+    }).addClass('webform-conditional-processed');
+    $context.find('.webform-conditional-action-remove:not(.webform-conditional-processed)').bind('click', function () {
+      this.webformRemoveClass = '.webform-conditional-action-remove';
+      window.setTimeout($.proxy(Drupal.webform.conditionalRemove, this), 100);
+    }).addClass('webform-conditional-processed');
+
+    // Trigger default handlers on the source element, this in turn will trigger
+    // the operator handlers.
+    $context.find('.webform-conditional-source select').trigger('change');
+
+    // Trigger defaults handlers on the action element.
+    $context.find('.webform-conditional-action select').trigger('change');
+
+    // When adding a new table row, make it draggable and hide the weight column.
+    if ($context.is('tr.ajax-new-content') && $context.find('.webform-conditional').length === 1) {
+      Drupal.tableDrag['webform-conditionals-table'].makeDraggable($context[0]);
+      $context.find('.webform-conditional-weight').closest('td').addClass('tabledrag-hide');
+      if ($.cookie('Drupal.tableDrag.showWeight') !== '1') {
+        Drupal.tableDrag['webform-conditionals-table'].hideColumns();
+      }
+      $context.removeClass('ajax-new-content');
+    }
+  };
 
-    var $target = $(e.target);
-    if ($target.is('.webform-conditional-source select')) {
-      Drupal.webform.conditionalSourceChange.apply(e.target);
+  /**
+   * Event callback for the remove button next to an individual rule.
+   */
+  Drupal.webform.conditionalRemove = function () {
+    // See if there are any remaining rules in this element.
+    var rowCount = $(this).parents('.webform-conditional:first').find(this.webformRemoveClass).length;
+    if (rowCount <= 1) {
+      var $tableRow = $(this).parents('tr:first');
+      var $table = $('#webform-conditionals-table');
+      if ($tableRow.length && $table.length) {
+        $tableRow.remove();
+        Drupal.webform.restripeTable($table[0]);
+      }
     }
+  };
 
-    if ($target.is('.webform-conditional-operator select')) {
-      Drupal.webform.conditionalOperatorChange.apply(e.target);
+  /**
+   * Event callback to update the list of operators after a source change.
+   */
+  Drupal.webform.conditionalSourceChange = function () {
+    var source = $(this).val();
+    var dataType = Drupal.settings.webform.conditionalValues.sources[source]['data_type'];
+    var $operator = $(this).parents('.webform-conditional-rule:first').find('.webform-conditional-operator select');
+
+    // Store a the original list of all operators for all data types in the select
+    // list DOM element.
+    if (!$operator[0]['webformConditionalOriginal']) {
+      $operator[0]['webformConditionalOriginal'] = $operator[0].innerHTML;
     }
 
-    if ($target.is('.webform-conditional-andor select')) {
-      Drupal.webform.conditionalAndOrChange.apply(e.target);
+    // Reference the original list to create a new list matching the data type.
+    var $originalList = $($operator[0]['webformConditionalOriginal']);
+    var $newList = $originalList.filter('optgroup[label=' + dataType + ']');
+    var newHTML = $newList[0].innerHTML;
+
+    // Update the options and fire the change event handler on the list to update
+    // the value field, only if the options have changed. This avoids resetting
+    // existing selections.
+    if (newHTML != $operator.html()) {
+      $operator.html(newHTML);
     }
+    // Trigger the change in case the source component changed from one select
+    // component to another.
+    $operator.trigger('change');
 
-    if ($target.is('.webform-conditional-action select')) {
-      Drupal.webform.conditionalActionChange.apply(e.target);
+  };
+
+  /**
+   * Event callback to update the value field after an operator change.
+   */
+  Drupal.webform.conditionalOperatorChange = function () {
+    var source = $(this).parents('.webform-conditional-rule:first').find('.webform-conditional-source select').val();
+    var dataType = Drupal.settings.webform.conditionalValues.sources[source]['data_type'];
+    var operator = $(this).val();
+    var $value = $(this).parents('.webform-conditional-rule:first').find('.webform-conditional-value');
+    var name = $value.find('input, select, textarea').attr('name');
+    var originalValue = false;
+
+    // Given the dataType and operator, we can determine the form key.
+    var formKey = Drupal.settings.webform.conditionalValues.operators[dataType][operator]['form'];
+    var formSource = typeof Drupal.settings.webform.conditionalValues.forms[formKey] == 'undefined' ? false : source;
+
+    // On initial request, save the default field as printed on the original page.
+    if (!$value[0]['webformConditionalOriginal']) {
+      $value[0]['webformConditionalOriginal'] = $value[0].innerHTML;
+      originalValue = $value.find('input:first').val();
     }
-  });
-
-  // Add event handlers to delete the entire row if the last rule or action is removed.
-  $context.find('.webform-conditional-rule-remove:not(.webform-conditional-processed)').bind('click', function() {
-    this.webformRemoveClass = '.webform-conditional-rule-remove';
-    window.setTimeout($.proxy(Drupal.webform.conditionalRemove, this), 100);
-  }).addClass('webform-conditional-processed');
-  $context.find('.webform-conditional-action-remove:not(.webform-conditional-processed)').bind('click', function() {
-    this.webformRemoveClass = '.webform-conditional-action-remove';
-    window.setTimeout($.proxy(Drupal.webform.conditionalRemove, this), 100);
-  }).addClass('webform-conditional-processed');
-
-  // Trigger default handlers on the source element, this in turn will trigger
-  // the operator handlers.
-  $context.find('.webform-conditional-source select').trigger('change');
-
-  // Trigger defaults handlers on the action element.
-  $context.find('.webform-conditional-action select').trigger('change');
-
-  // When adding a new table row, make it draggable and hide the weight column.
-  if ($context.is('tr.ajax-new-content') && $context.find('.webform-conditional').length === 1) {
-    Drupal.tableDrag['webform-conditionals-table'].makeDraggable($context[0]);
-    $context.find('.webform-conditional-weight').closest('td').addClass('tabledrag-hide');
-    if ($.cookie('Drupal.tableDrag.showWeight') !== '1') {
-      Drupal.tableDrag['webform-conditionals-table'].hideColumns();
+    // On changes to an existing operator, check if the form key is different
+    // (and any per-source form, such as a select option list) before replacing
+    // the form with an identical version.
+    else if ($value[0]['webformConditionalFormKey'] == formKey && $value[0]['webformConditionalFormSource'] == formSource) {
+      return;
     }
-    $context.removeClass('ajax-new-content');
-  }
-}
 
-/**
- * Event callback for the remove button next to an individual rule.
- */
-Drupal.webform.conditionalRemove = function() {
-  // See if there are any remaining rules in this element.
-  var rowCount = $(this).parents('.webform-conditional:first').find(this.webformRemoveClass).length;
-  if (rowCount <= 1) {
-    var $tableRow = $(this).parents('tr:first');
-    var $table = $('#webform-conditionals-table');
-    if ($tableRow.length && $table.length) {
-      $tableRow.remove();
-      Drupal.webform.restripeTable($table[0]);
+    // Store the current form key for checking the next time the operator changes.
+    $value[0]['webformConditionalFormKey'] = formKey;
+    $value[0]['webformConditionalFormSource'] = formSource;
+
+    // If using the default (a textfield), restore the original field.
+    if (formKey === 'default') {
+      $value[0].innerHTML = $value[0]['webformConditionalOriginal'];
+    }
+    // If the operator does not need a source value (i.e. is empty), hide it.
+    else if (formKey === false) {
+      $value[0].innerHTML = '&nbsp;';
+    }
+    // If there is a per-source form for this operator (e.g. option lists), use
+    // the specialized value form.
+    else if (typeof Drupal.settings.webform.conditionalValues.forms[formKey] == 'object') {
+      $value[0].innerHTML = Drupal.settings.webform.conditionalValues.forms[formKey][source];
+    }
+    // Otherwise all the sources use a generic field (e.g. a text field).
+    else {
+      $value[0].innerHTML = Drupal.settings.webform.conditionalValues.forms[formKey];
     }
-  }
-}
 
-/**
- * Event callback to update the list of operators after a source change.
- */
-Drupal.webform.conditionalSourceChange = function() {
-  var source = $(this).val();
-  var dataType = Drupal.settings.webform.conditionalValues.sources[source]['data_type'];
-  var $operator = $(this).parents('.webform-conditional-rule:first').find('.webform-conditional-operator select');
-
-  // Store a the original list of all operators for all data types in the select
-  // list DOM element.
-  if (!$operator[0]['webformConditionalOriginal']) {
-    $operator[0]['webformConditionalOriginal'] = $operator[0].innerHTML;
-  }
-
-  // Reference the original list to create a new list matching the data type.
-  var $originalList = $($operator[0]['webformConditionalOriginal']);
-  var $newList = $originalList.filter('optgroup[label=' + dataType + ']');
-  var newHTML = $newList[0].innerHTML;
-
-  // Update the options and fire the change event handler on the list to update
-  // the value field, only if the options have changed. This avoids resetting
-  // existing selections.
-  if (newHTML != $operator.html()) {
-    $operator.html(newHTML);
-  }
-  // Trigger the change in case the source component changed from one select
-  // component to another.
-  $operator.trigger('change');
-
-}
+    // Set the name attribute to match the original placeholder field.
+    var $firstElement = $value.find('input, select, textarea').filter(':first');
+    $firstElement.attr('name', name);
 
-/**
- * Event callback to update the value field after an operator change.
- */
-Drupal.webform.conditionalOperatorChange = function() {
-  var source = $(this).parents('.webform-conditional-rule:first').find('.webform-conditional-source select').val();
-  var dataType = Drupal.settings.webform.conditionalValues.sources[source]['data_type'];
-  var operator = $(this).val();
-  var $value = $(this).parents('.webform-conditional-rule:first').find('.webform-conditional-value');
-  var name = $value.find('input, select, textarea').attr('name');
-  var originalValue = false;
-
-  // Given the dataType and operator, we can determine the form key.
-  var formKey = Drupal.settings.webform.conditionalValues.operators[dataType][operator]['form'];
-  var formSource = typeof Drupal.settings.webform.conditionalValues.forms[formKey] == 'undefined' ? false : source;
-
-  // On initial request, save the default field as printed on the original page.
-  if (!$value[0]['webformConditionalOriginal']) {
-    $value[0]['webformConditionalOriginal'] = $value[0].innerHTML;
-    originalValue = $value.find('input:first').val();
-  }
-  // On changes to an existing operator, check if the form key is different
-  // (and any per-source form, such as a select option list) before replacing
-  // the form with an identical version.
-  else if ($value[0]['webformConditionalFormKey'] == formKey && $value[0]['webformConditionalFormSource'] == formSource) {
-    return;
-  }
-
-  // Store the current form key for checking the next time the operator changes.
-  $value[0]['webformConditionalFormKey'] = formKey;
-  $value[0]['webformConditionalFormSource'] = formSource;
-
-  // If using the default (a textfield), restore the original field.
-  if (formKey === 'default') {
-    $value[0].innerHTML = $value[0]['webformConditionalOriginal'];
-  }
-  // If the operator does not need a source value (i.e. is empty), hide it.
-  else if (formKey === false) {
-    $value[0].innerHTML = '&nbsp;';
-  }
-  // If there is a per-source form for this operator (e.g. option lists), use
-  // the specialized value form.
-  else if (typeof Drupal.settings.webform.conditionalValues.forms[formKey] == 'object') {
-    $value[0].innerHTML = Drupal.settings.webform.conditionalValues.forms[formKey][source];
-  }
-  // Otherwise all the sources use a generic field (e.g. a text field).
-  else {
-    $value[0].innerHTML = Drupal.settings.webform.conditionalValues.forms[formKey];
-  }
-
-  // Set the name attribute to match the original placeholder field.
-  var $firstElement = $value.find('input, select, textarea').filter(':first');
-  $firstElement.attr('name', name);
-
-  if (originalValue) {
-    $firstElement.val(originalValue);
-  }
-}
+    if (originalValue) {
+      $firstElement.val(originalValue);
+    }
+  };
 
-/**
- * Event callback to make sure all group and/or operators match.
- */
-Drupal.webform.conditionalAndOrChange = function() {
-  $(this).parents('.webform-conditional:first').find('.webform-conditional-andor select').val(this.value);
-}
+  /**
+   * Event callback to make sure all group and/or operators match.
+   */
+  Drupal.webform.conditionalAndOrChange = function () {
+    $(this).parents('.webform-conditional:first').find('.webform-conditional-andor select').val(this.value);
+  };
 
-/**
- * Event callback to show argument only for appropriate actions.
- */
-Drupal.webform.conditionalActionChange = function() {
-  var action = $(this).val();
-  var $argument = $(this).parents('.webform-conditional:first').find('.webform-conditional-argument input');
-  var isShown = $argument.is(':visible');
-  switch (action) {
-    case 'show':
-    case 'require':
-      if (isShown) {
-        $argument.hide();
-      }
-      break;
-    case 'set':
-      if (!isShown) {
-        $argument.show();
-      }
-      break;
-  }
-}
+  /**
+   * Event callback to show argument only for appropriate actions.
+   */
+  Drupal.webform.conditionalActionChange = function () {
+    var action = $(this).val();
+    var $argument = $(this).parents('.webform-conditional:first').find('.webform-conditional-argument input');
+    var isShown = $argument.is(':visible');
+    switch (action) {
+      case 'show':
+      case 'require':
+        if (isShown) {
+          $argument.hide();
+        }
+        break;
+      case 'set':
+        if (!isShown) {
+          $argument.show();
+        }
+        break;
+    }
+  };
 
-/**
- * Given a table's DOM element, restripe the odd/even classes.
- */
-Drupal.webform.restripeTable = function(table) {
-  // :even and :odd are reversed because jQuery counts from 0 and
-  // we count from 1, so we're out of sync.
-  // Match immediate children of the parent element to allow nesting.
-  $('> tbody > tr, > tr', table)
-    .filter(':odd').filter('.odd')
-      .removeClass('odd').addClass('even')
-    .end().end()
-    .filter(':even').filter('.even')
-      .removeClass('even').addClass('odd');
-};
+  /**
+   * Given a table's DOM element, restripe the odd/even classes.
+   */
+  Drupal.webform.restripeTable = function (table) {
+    // :even and :odd are reversed because jQuery counts from 0 and
+    // we count from 1, so we're out of sync.
+    // Match immediate children of the parent element to allow nesting.
+    $('> tbody > tr, > tr', table)
+      .filter(':odd').filter('.odd')
+        .removeClass('odd').addClass('even')
+      .end().end()
+      .filter(':even').filter('.even')
+        .removeClass('even').addClass('odd');
+  };
 
-/**
- * Triggers a change event when a label receives a click.
- *
- * When the browser automatically selects a radio button when it's label is
- * clicked, the FAPI states jQuery code doesn't receive an event. This function
- * ensures that automatically-selected radio buttons keep in sync with the
- * FAPI states.
- */
-Drupal.webform.radioLabelAutoClick = function(context) {
-  $('label').once('webform-label').click(function(){
-    $(this).prev('input:radio').change();
-  });
-}
+  /**
+   * Triggers a change event when a label receives a click.
+   *
+   * When the browser automatically selects a radio button when it's label is
+   * clicked, the FAPI states jQuery code doesn't receive an event. This function
+   * ensures that automatically-selected radio buttons keep in sync with the
+   * FAPI states.
+   */
+  Drupal.webform.radioLabelAutoClick = function (context) {
+    $('label').once('webform-label').click(function () {
+      $(this).prev('input:radio').change();
+    });
+  };
+
+  /**
+   * Make a prop shim for jQuery < 1.9.
+   */
+  $.fn.webformProp = $.fn.webformProp || function (name, value) {
+    if (value) {
+      return $.fn.prop ? this.prop(name, true) : this.attr(name, true);
+    }
+    else {
+      return $.fn.prop ? this.prop(name, false) : this.removeAttr(name);
+    }
+  };
 
 })(jQuery);
diff --git a/profiles/wcm_base/modules/contrib/webform/js/webform.js b/profiles/wcm_base/modules/contrib/webform/js/webform.js
index 887c8213f034b1dbfccd34a82e2fee7ed77ef149..240c1c501228c906a6b99dcdf9c7a0aefb4f10dc 100644
--- a/profiles/wcm_base/modules/contrib/webform/js/webform.js
+++ b/profiles/wcm_base/modules/contrib/webform/js/webform.js
@@ -1,630 +1,632 @@
-
 /**
+ * @file
  * JavaScript behaviors for the front-end display of webforms.
  */
 
 (function ($) {
 
-Drupal.behaviors.webform = Drupal.behaviors.webform || {};
-
-Drupal.behaviors.webform.attach = function(context) {
-  // Calendar datepicker behavior.
-  Drupal.webform.datepicker(context);
+  "use strict";
 
-  // Conditional logic.
-  if (Drupal.settings.webform && Drupal.settings.webform.conditionals) {
-    Drupal.webform.conditional(context);
-  }
-};
+  Drupal.behaviors.webform = Drupal.behaviors.webform || {};
 
-Drupal.webform = Drupal.webform || {};
+  Drupal.behaviors.webform.attach = function (context) {
+    // Calendar datepicker behavior.
+    Drupal.webform.datepicker(context);
 
-Drupal.webform.datepicker = function(context) {
-  $('div.webform-datepicker').each(function() {
-    var $webformDatepicker = $(this);
-    var $calendar = $webformDatepicker.find('input.webform-calendar');
-
-    // Ensure the page we're on actually contains a datepicker.
-    if ($calendar.length == 0) {
-      return;
+    // Conditional logic.
+    if (Drupal.settings.webform && Drupal.settings.webform.conditionals) {
+      Drupal.webform.conditional(context);
     }
+  };
 
-    var startDate = $calendar[0].className.replace(/.*webform-calendar-start-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-');
-    var endDate = $calendar[0].className.replace(/.*webform-calendar-end-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-');
-    var firstDay = $calendar[0].className.replace(/.*webform-calendar-day-(\d).*/, '$1');
-    // Convert date strings into actual Date objects.
-    startDate = new Date(startDate[0], startDate[1] - 1, startDate[2]);
-    endDate = new Date(endDate[0], endDate[1] - 1, endDate[2]);
-
-    // Ensure that start comes before end for datepicker.
-    if (startDate > endDate) {
-      var laterDate = startDate;
-      startDate = endDate;
-      endDate = laterDate;
-    }
+  Drupal.webform = Drupal.webform || {};
 
-    var startYear = startDate.getFullYear();
-    var endYear = endDate.getFullYear();
-
-    // Set up the jQuery datepicker element.
-    $calendar.datepicker({
-      dateFormat: 'yy-mm-dd',
-      yearRange: startYear + ':' + endYear,
-      firstDay: parseInt(firstDay),
-      minDate: startDate,
-      maxDate: endDate,
-      onSelect: function(dateText, inst) {
-        var date = dateText.split('-');
-        $webformDatepicker.find('select.year, input.year').val(+date[0]).trigger('change');
-        $webformDatepicker.find('select.month').val(+date[1]).trigger('change');
-        $webformDatepicker.find('select.day').val(+date[2]).trigger('change');
-      },
-      beforeShow: function(input, inst) {
-        // Get the select list values.
-        var year = $webformDatepicker.find('select.year, input.year').val();
-        var month = $webformDatepicker.find('select.month').val();
-        var day = $webformDatepicker.find('select.day').val();
-
-        // If empty, default to the current year/month/day in the popup.
-        var today = new Date();
-        year = year ? year : today.getFullYear();
-        month = month ? month : today.getMonth() + 1;
-        day = day ? day : today.getDate();
-
-        // Make sure that the default year fits in the available options.
-        year = (year < startYear || year > endYear) ? startYear : year;
-
-        // jQuery UI Datepicker will read the input field and base its date off
-        // of that, even though in our case the input field is a button.
-        $(input).val(year + '-' + month + '-' + day);
+  Drupal.webform.datepicker = function (context) {
+    $('div.webform-datepicker').each(function () {
+      var $webformDatepicker = $(this);
+      var $calendar = $webformDatepicker.find('input.webform-calendar');
+
+      // Ensure the page we're on actually contains a datepicker.
+      if ($calendar.length == 0) {
+        return;
       }
-    });
 
-    // Prevent the calendar button from submitting the form.
-    $calendar.click(function(event) {
-      $(this).focus();
-      event.preventDefault();
-    });
-  });
-};
-
-Drupal.webform.conditional = function(context) {
-  // Add the bindings to each webform on the page.
-  $.each(Drupal.settings.webform.conditionals, function(formKey, settings) {
-    var $form = $('.' + formKey + ':not(.webform-conditional-processed)');
-    $form.each(function(index, currentForm) {
-      var $currentForm = $(currentForm);
-      $currentForm.addClass('webform-conditional-processed');
-      $currentForm.bind('change', { 'settings': settings }, Drupal.webform.conditionalCheck);
-
-      // Trigger all the elements that cause conditionals on this form.
-      Drupal.webform.doConditions($form, settings);
-    })
-  });
-};
+      var startDate = $calendar[0].className.replace(/.*webform-calendar-start-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-');
+      var endDate = $calendar[0].className.replace(/.*webform-calendar-end-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-');
+      var firstDay = $calendar[0].className.replace(/.*webform-calendar-day-(\d).*/, '$1');
+      // Convert date strings into actual Date objects.
+      startDate = new Date(startDate[0], startDate[1] - 1, startDate[2]);
+      endDate = new Date(endDate[0], endDate[1] - 1, endDate[2]);
+
+      // Ensure that start comes before end for datepicker.
+      if (startDate > endDate) {
+        var laterDate = startDate;
+        startDate = endDate;
+        endDate = laterDate;
+      }
 
-/**
- * Event handler to respond to field changes in a form.
- *
- * This event is bound to the entire form, not individual fields.
- */
-Drupal.webform.conditionalCheck = function(e) {
-  var $triggerElement = $(e.target).closest('.webform-component');
-  var $form = $triggerElement.closest('form');
-  var triggerElementKey = $triggerElement.attr('class').match(/webform-component--[^ ]+/)[0];
-  var settings = e.data.settings;
-  if (settings.sourceMap[triggerElementKey]) {
-    Drupal.webform.doConditions($form, settings);
-  }
-};
+      var startYear = startDate.getFullYear();
+      var endYear = endDate.getFullYear();
+
+      // Set up the jQuery datepicker element.
+      $calendar.datepicker({
+        dateFormat: 'yy-mm-dd',
+        yearRange: startYear + ':' + endYear,
+        firstDay: parseInt(firstDay),
+        minDate: startDate,
+        maxDate: endDate,
+        onSelect: function (dateText, inst) {
+          var date = dateText.split('-');
+          $webformDatepicker.find('select.year, input.year').val(+date[0]).trigger('change');
+          $webformDatepicker.find('select.month').val(+date[1]).trigger('change');
+          $webformDatepicker.find('select.day').val(+date[2]).trigger('change');
+        },
+        beforeShow: function (input, inst) {
+          // Get the select list values.
+          var year = $webformDatepicker.find('select.year, input.year').val();
+          var month = $webformDatepicker.find('select.month').val();
+          var day = $webformDatepicker.find('select.day').val();
+
+          // If empty, default to the current year/month/day in the popup.
+          var today = new Date();
+          year = year ? year : today.getFullYear();
+          month = month ? month : today.getMonth() + 1;
+          day = day ? day : today.getDate();
+
+          // Make sure that the default year fits in the available options.
+          year = (year < startYear || year > endYear) ? startYear : year;
+
+          // jQuery UI Datepicker will read the input field and base its date off
+          // of that, even though in our case the input field is a button.
+          $(input).val(year + '-' + month + '-' + day);
+        }
+      });
 
-/**
- * Processes all conditional.
- */
-Drupal.webform.doConditions = function($form, settings) {
-  // Track what has be set/shown for each target component.
-  var targetLocked = [];
-
-  $.each(settings.ruleGroups, function(rgid_key, rule_group) {
-    var ruleGroup = settings.ruleGroups[rgid_key];
-
-    // Perform the comparison callback and build the results for this group.
-    var conditionalResult = true;
-    var conditionalResults = [];
-    $.each(ruleGroup['rules'], function(m, rule) {
-      var elementKey = rule['source'];
-      var element = $form.find('.' + elementKey)[0];
-      var existingValue = settings.values[elementKey] ? settings.values[elementKey] : null;
-      conditionalResults.push(window['Drupal']['webform'][rule.callback](element, existingValue, rule['value'] ));
+      // Prevent the calendar button from submitting the form.
+      $calendar.click(function (event) {
+        $(this).focus();
+        event.preventDefault();
+      });
+    });
+  };
+
+  Drupal.webform.conditional = function (context) {
+    // Add the bindings to each webform on the page.
+    $.each(Drupal.settings.webform.conditionals, function (formKey, settings) {
+      var $form = $('.' + formKey + ':not(.webform-conditional-processed)');
+      $form.each(function (index, currentForm) {
+        var $currentForm = $(currentForm);
+        $currentForm.addClass('webform-conditional-processed');
+        $currentForm.bind('change', {'settings': settings}, Drupal.webform.conditionalCheck);
+
+        // Trigger all the elements that cause conditionals on this form.
+        Drupal.webform.doConditions($form, settings);
+      });
     });
+  };
+
+  /**
+   * Event handler to respond to field changes in a form.
+   *
+   * This event is bound to the entire form, not individual fields.
+   */
+  Drupal.webform.conditionalCheck = function (e) {
+    var $triggerElement = $(e.target).closest('.webform-component');
+    var $form = $triggerElement.closest('form');
+    var triggerElementKey = $triggerElement.attr('class').match(/webform-component--[^ ]+/)[0];
+    var settings = e.data.settings;
+    if (settings.sourceMap[triggerElementKey]) {
+      Drupal.webform.doConditions($form, settings);
+    }
+  };
+
+  /**
+   * Processes all conditional.
+   */
+  Drupal.webform.doConditions = function ($form, settings) {
+    // Track what has be set/shown for each target component.
+    var targetLocked = [];
+
+    $.each(settings.ruleGroups, function (rgid_key, rule_group) {
+      var ruleGroup = settings.ruleGroups[rgid_key];
+
+      // Perform the comparison callback and build the results for this group.
+      var conditionalResult = true;
+      var conditionalResults = [];
+      $.each(ruleGroup['rules'], function (m, rule) {
+        var elementKey = rule['source'];
+        var element = $form.find('.' + elementKey)[0];
+        var existingValue = settings.values[elementKey] ? settings.values[elementKey] : null;
+        conditionalResults.push(window['Drupal']['webform'][rule.callback](element, existingValue, rule['value']));
+      });
 
-    // Filter out false values.
-    var filteredResults = [];
-    for (var i = 0; i < conditionalResults.length; i++) {
-      if (conditionalResults[i]) {
-        filteredResults.push(conditionalResults[i]);
+      // Filter out false values.
+      var filteredResults = [];
+      for (var i = 0; i < conditionalResults.length; i++) {
+        if (conditionalResults[i]) {
+          filteredResults.push(conditionalResults[i]);
+        }
       }
-    }
 
-    // Calculate the and/or result.
-    if (ruleGroup['andor'] === 'or') {
-      conditionalResult = filteredResults.length > 0;
-    }
-    else {
-      conditionalResult = filteredResults.length === conditionalResults.length;
-    }
+      // Calculate the and/or result.
+      if (ruleGroup['andor'] === 'or') {
+        conditionalResult = filteredResults.length > 0;
+      }
+      else {
+        conditionalResult = filteredResults.length === conditionalResults.length;
+      }
 
-    $.each(ruleGroup['actions'], function(aid, action) {
-      var $target = $form.find('.' + action['target']);
-      var actionResult = action['invert'] ? !conditionalResult : conditionalResult;
-      switch (action['action']) {
-        case 'show':
-          if (actionResult != Drupal.webform.isVisible($target)) {
-            var $targetElements = actionResult
-                                    ? $target.find('.webform-conditional-disabled').removeClass('webform-conditional-disabled')
-                                    : $target.find(':input').addClass('webform-conditional-disabled');
-            $targetElements.webformProp('disabled', !actionResult);
-            $target.toggleClass('webform-conditional-hidden', !actionResult);
+      $.each(ruleGroup['actions'], function (aid, action) {
+        var $target = $form.find('.' + action['target']);
+        var actionResult = action['invert'] ? !conditionalResult : conditionalResult;
+        switch (action['action']) {
+          case 'show':
+            if (actionResult != Drupal.webform.isVisible($target)) {
+              var $targetElements = actionResult
+                                      ? $target.find('.webform-conditional-disabled').removeClass('webform-conditional-disabled')
+                                      : $target.find(':input').addClass('webform-conditional-disabled');
+              $targetElements.webformProp('disabled', !actionResult);
+              $target.toggleClass('webform-conditional-hidden', !actionResult);
+              if (actionResult) {
+                $target.show();
+              }
+              else {
+                $target.hide();
+                // Record that the target was hidden.
+                targetLocked[action['target']] = 'hide';
+              }
+            }
+            break;
+          case 'require':
+            var $requiredSpan = $target.find('.form-required, .form-optional').first();
+            if (actionResult != $requiredSpan.hasClass('form-required')) {
+              var $targetInputElements = $target.find("input:text,textarea,input[type='email'],select,input:radio,input:file");
+              // Rather than hide the required tag, remove it so that other jQuery can respond via Drupal behaviors.
+              Drupal.detachBehaviors($requiredSpan);
+              $targetInputElements
+                .webformProp('required', actionResult)
+                .toggleClass('required', actionResult);
+              if (actionResult) {
+                $requiredSpan.replaceWith('<span class="form-required" title="' + Drupal.t('This field is required.') + '">*</span>');
+              }
+              else {
+                $requiredSpan.replaceWith('<span class="form-optional"></span>');
+              }
+              Drupal.attachBehaviors($requiredSpan);
+            }
+            break;
+          case 'set':
+            var isLocked = targetLocked[action['target']];
+            var $texts = $target.find("input:text,textarea,input[type='email']");
+            var $selects = $target.find('select,select option,input:radio,input:checkbox');
+            var $markups = $target.filter('.webform-component-markup');
             if (actionResult) {
-              $target.show();
+              var multiple = $.map(action['argument'].split(','), $.trim);
+              $selects.webformVal(multiple);
+              $texts.val([action['argument']]);
+              // A special case is made for markup. It is sanitized with filter_xss_admin on the server.
+              // otherwise text() should be used to avoid an XSS vulnerability. text() however would
+              // preclude the use of tags like <strong> or <a>
+              $markups.html(action['argument']);
             }
             else {
-              $target.hide();
-              // Record that the target was hidden.
-              targetLocked[action['target']] = 'hide';
+              // Markup not set? Then restore original markup as provided in
+              // the attribute data-webform-markup.
+              $markups.each(function() {
+                var $this = $(this);
+                var original = $this.data('webform-markup');
+                if (original !== undefined) {
+                  $this.html(original);
+                }
+              });
             }
-          }
-          break;
-        case 'require':
-          var $requiredSpan = $target.find('.form-required, .form-optional').first();
-          if (actionResult != $requiredSpan.hasClass('form-required')) {
-            var $targetInputElements = $target.find("input:text,textarea,input[type='email'],select,input:radio,input:file");
-            // Rather than hide the required tag, remove it so that other jQuery can respond via Drupal behaviors.
-            Drupal.detachBehaviors($requiredSpan);
-            $targetInputElements
-              .webformProp('required', actionResult)
-              .toggleClass('required', actionResult);
-            if (actionResult) {
-              $requiredSpan.replaceWith('<span class="form-required" title="' + Drupal.t('This field is required.') + '">*</span>');
+            if (!isLocked) {
+              // If not previously hidden or set, disable the element readonly or readonly-like behavior.
+              $selects.webformProp('disabled', actionResult);
+              $texts.webformProp('readonly', actionResult);
+              targetLocked[action['target']] = actionResult ? 'set' : false;
+            }
+            break;
+        }
+      }); // End look on each action for one conditional
+    }); // End loop on each conditional
+  };
+
+  /**
+   * Event handler to prevent propogation of events, typically click for disabling
+   * radio and checkboxes.
+   */
+  Drupal.webform.stopEvent = function () {
+    return false;
+  };
+
+  Drupal.webform.conditionalOperatorStringEqual = function (element, existingValue, ruleValue) {
+    var returnValue = false;
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    $.each(currentValue, function (n, value) {
+      if (value.toLowerCase() === ruleValue.toLowerCase()) {
+        returnValue = true;
+        return false; // break.
+      }
+    });
+    return returnValue;
+  };
+
+  Drupal.webform.conditionalOperatorStringNotEqual = function (element, existingValue, ruleValue) {
+    var found = false;
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    $.each(currentValue, function (n, value) {
+      if (value.toLowerCase() === ruleValue.toLowerCase()) {
+        found = true;
+      }
+    });
+    return !found;
+  };
+
+  Drupal.webform.conditionalOperatorStringContains = function (element, existingValue, ruleValue) {
+    var returnValue = false;
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    $.each(currentValue, function (n, value) {
+      if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) {
+        returnValue = true;
+        return false; // break.
+      }
+    });
+    return returnValue;
+  };
+
+  Drupal.webform.conditionalOperatorStringDoesNotContain = function (element, existingValue, ruleValue) {
+    var found = false;
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    $.each(currentValue, function (n, value) {
+      if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) {
+        found = true;
+      }
+    });
+    return !found;
+  };
+
+  Drupal.webform.conditionalOperatorStringBeginsWith = function (element, existingValue, ruleValue) {
+    var returnValue = false;
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    $.each(currentValue, function (n, value) {
+      if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) === 0) {
+        returnValue = true;
+        return false; // break.
+      }
+    });
+    return returnValue;
+  };
+
+  Drupal.webform.conditionalOperatorStringEndsWith = function (element, existingValue, ruleValue) {
+    var returnValue = false;
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    $.each(currentValue, function (n, value) {
+      if (value.toLowerCase().lastIndexOf(ruleValue.toLowerCase()) === value.length - ruleValue.length) {
+        returnValue = true;
+        return false; // break.
+      }
+    });
+    return returnValue;
+  };
+
+  Drupal.webform.conditionalOperatorStringEmpty = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    var returnValue = true;
+    $.each(currentValue, function (n, value) {
+      if (value !== '') {
+        returnValue = false;
+        return false; // break.
+      }
+    });
+    return returnValue;
+  };
+
+  Drupal.webform.conditionalOperatorStringNotEmpty = function (element, existingValue, ruleValue) {
+    return !Drupal.webform.conditionalOperatorStringEmpty(element, existingValue, ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorSelectGreaterThan = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    return Drupal.webform.compare_select(currentValue[0], ruleValue, element) > 0;
+  };
+
+  Drupal.webform.conditionalOperatorSelectGreaterThanEqual = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element);
+    return comparison > 0 || comparison === 0;
+  };
+
+  Drupal.webform.conditionalOperatorSelectLessThan = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    return Drupal.webform.compare_select(currentValue[0], ruleValue, element) < 0;
+  };
+
+  Drupal.webform.conditionalOperatorSelectLessThanEqual = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element);
+    return comparison < 0 || comparison === 0;
+  };
+
+  Drupal.webform.conditionalOperatorNumericEqual = function (element, existingValue, ruleValue) {
+    // See float comparison: http://php.net/manual/en/language.types.float.php
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    var epsilon = 0.000001;
+    // An empty string does not match any number.
+    return currentValue[0] === '' ? false : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) < epsilon);
+  };
+
+  Drupal.webform.conditionalOperatorNumericNotEqual = function (element, existingValue, ruleValue) {
+    // See float comparison: http://php.net/manual/en/language.types.float.php
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    var epsilon = 0.000001;
+    // An empty string does not match any number.
+    return currentValue[0] === '' ? true : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) >= epsilon);
+  };
+
+  Drupal.webform.conditionalOperatorNumericGreaterThan = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    return parseFloat(currentValue[0]) > parseFloat(ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorNumericGreaterThanEqual = function (element, existingValue, ruleValue) {
+    return Drupal.webform.conditionalOperatorNumericGreaterThan(element, existingValue, ruleValue) ||
+           Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorNumericLessThan = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.stringValue(element, existingValue);
+    return parseFloat(currentValue[0]) < parseFloat(ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorNumericLessThanEqual = function (element, existingValue, ruleValue) {
+    return Drupal.webform.conditionalOperatorNumericLessThan(element, existingValue, ruleValue) ||
+           Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorDateEqual = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.dateValue(element, existingValue);
+    return currentValue === ruleValue;
+  };
+
+  Drupal.webform.conditionalOperatorDateNotEqual = function (element, existingValue, ruleValue) {
+    return !Drupal.webform.conditionalOperatorDateEqual(element, existingValue, ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorDateBefore = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.dateValue(element, existingValue);
+    return (currentValue !== false) && currentValue < ruleValue;
+  };
+
+  Drupal.webform.conditionalOperatorDateBeforeEqual = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.dateValue(element, existingValue);
+    return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorDateAfter = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.dateValue(element, existingValue);
+    return (currentValue !== false) && currentValue > ruleValue;
+  };
+
+  Drupal.webform.conditionalOperatorDateAfterEqual = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.dateValue(element, existingValue);
+    return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorTimeEqual = function (element, existingValue, ruleValue) {
+    var currentValue = Drupal.webform.timeValue(element, existingValue);
+    return currentValue === ruleValue;
+  };
+
+  Drupal.webform.conditionalOperatorTimeNotEqual = function (element, existingValue, ruleValue) {
+    return !Drupal.webform.conditionalOperatorTimeEqual(element, existingValue, ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorTimeBefore = function (element, existingValue, ruleValue) {
+    // Date and time operators intentionally exclusive for "before".
+    var currentValue = Drupal.webform.timeValue(element, existingValue);
+    return (currentValue !== false) && (currentValue < ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorTimeBeforeEqual = function (element, existingValue, ruleValue) {
+    // Date and time operators intentionally exclusive for "before".
+    var currentValue = Drupal.webform.timeValue(element, existingValue);
+    return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorTimeAfter = function (element, existingValue, ruleValue) {
+    // Date and time operators intentionally inclusive for "after".
+    var currentValue = Drupal.webform.timeValue(element, existingValue);
+    return (currentValue !== false) && (currentValue > ruleValue);
+  };
+
+  Drupal.webform.conditionalOperatorTimeAfterEqual = function (element, existingValue, ruleValue) {
+    // Date and time operators intentionally inclusive for "after".
+    var currentValue = Drupal.webform.timeValue(element, existingValue);
+    return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue);
+  };
+
+  /**
+   * Utility function to compare values of a select component.
+   * @param string a
+   *   First select option key to compare
+   * @param string b
+   *   Second select option key to compare
+   * @param array options
+   *   Associative array where the a and b are within the keys
+   * @return integer based upon position of $a and $b in $options
+   *   -N if $a above (<) $b
+   *   0 if $a = $b
+   *   +N if $a is below (>) $b
+   */
+  Drupal.webform.compare_select = function (a, b, element) {
+    var optionList = [];
+    $('option,input:radio,input:checkbox', element).each(function () {
+      optionList.push($(this).val());
+    });
+    var a_position = optionList.indexOf(a);
+    var b_position = optionList.indexOf(b);
+    return (a_position < 0 || b_position < 0) ? null : a_position - b_position;
+  };
+
+  /**
+   * Utility to return current visibility. Uses actual visibility, except for
+   * hidden components which use the applied disabled class.
+   */
+  Drupal.webform.isVisible = function ($element) {
+    return $element.hasClass('webform-component-hidden')
+              ? !$element.find('input').first().hasClass('webform-conditional-disabled')
+              : $element.closest('.webform-conditional-hidden').length == 0;
+  };
+
+  /**
+   * Utility function to get a string value from a select/radios/text/etc. field.
+   */
+  Drupal.webform.stringValue = function (element, existingValue) {
+    var value = [];
+    if (element) {
+      var $element = $(element);
+      if (Drupal.webform.isVisible($element)) {
+        // Checkboxes and radios.
+        $element.find('input[type=checkbox]:checked,input[type=radio]:checked').each(function () {
+          value.push(this.value);
+        });
+        // Select lists.
+        if (!value.length) {
+          var selectValue = $element.find('select').val();
+          if (selectValue) {
+            if ($.isArray(selectValue)) {
+              value = selectValue;
             }
             else {
-              $requiredSpan.replaceWith('<span class="form-optional"></span>');
+              value.push(selectValue);
             }
-            Drupal.attachBehaviors($requiredSpan);
           }
+        }
+        // Simple text fields. This check is done last so that the select list in
+        // select-or-other fields comes before the "other" text field.
+        if (!value.length) {
+          $element.find('input:not([type=checkbox],[type=radio]),textarea').each(function () {
+            value.push(this.value);
+          });
+        }
+      }
+    }
+    else {
+      switch ($.type(existingValue)) {
+        case 'array':
+          value = existingValue;
           break;
-        case 'set':
-          var isLocked = targetLocked[action['target']];
-          var $texts = $target.find("input:text,textarea,input[type='email']");
-          var $selects = $target.find('select,select option,input:radio,input:checkbox');
-          if (actionResult) {
-            var multiple = $.map(action['argument'].split(','), $.trim);
-            $selects.webformVal(multiple);
-            $texts.val([action['argument']]);
-            // A special case is made for markup. It is sanitized with filter_xss_admin on the server.
-            // otherwise text() should be used to avoid an XSS vulnerability. text() however would
-            // preclude the use of tags like <strong> or <a>
-            $target.filter('.webform-component-markup').html(action['argument']);
-          }
-          if (!isLocked) {
-            // If not previously hidden or set, disable the element readonly or readonly-like behavior.
-            $selects.webformProp('disabled', actionResult);
-            $texts.webformProp('readonly', actionResult);
-            targetLocked[action['target']] = actionResult ? 'set' : false;
-          }
+        case 'string':
+          value.push(existingValue);
           break;
       }
-    }); // End look on each action for one conditional
-  }); // End loop on each conditional
-}
-
-/**
- * Event handler to prevent propogation of events, typically click for disabling
- * radio and checkboxes.
- */
-Drupal.webform.stopEvent = function() {
-  return false;
-}
-
-Drupal.webform.conditionalOperatorStringEqual = function(element, existingValue, ruleValue) {
-  var returnValue = false;
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  $.each(currentValue, function(n, value) {
-    if (value.toLowerCase() === ruleValue.toLowerCase()) {
-      returnValue = true;
-      return false; // break.
-    }
-  });
-  return returnValue;
-};
-
-Drupal.webform.conditionalOperatorStringNotEqual = function(element, existingValue, ruleValue) {
-  var found = false;
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  $.each(currentValue, function(n, value) {
-    if (value.toLowerCase() === ruleValue.toLowerCase()) {
-      found = true;
     }
-  });
-  return !found;
-};
-
-Drupal.webform.conditionalOperatorStringContains = function(element, existingValue, ruleValue) {
-  var returnValue = false;
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  $.each(currentValue, function(n, value) {
-    if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) {
-      returnValue = true;
-      return false; // break.
-    }
-  });
-  return returnValue;
-};
-
-Drupal.webform.conditionalOperatorStringDoesNotContain = function(element, existingValue, ruleValue) {
-  var found = false;
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  $.each(currentValue, function(n, value) {
-    if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) {
-      found = true;
-    }
-  });
-  return !found;
-};
-
-Drupal.webform.conditionalOperatorStringBeginsWith = function(element, existingValue, ruleValue) {
-  var returnValue = false;
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  $.each(currentValue, function(n, value) {
-    if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) === 0) {
-      returnValue = true;
-      return false; // break.
-    }
-  });
-  return returnValue;
-};
-
-Drupal.webform.conditionalOperatorStringEndsWith = function(element, existingValue, ruleValue) {
-  var returnValue = false;
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  $.each(currentValue, function(n, value) {
-    if (value.toLowerCase().lastIndexOf(ruleValue.toLowerCase()) === value.length - ruleValue.length) {
-      returnValue = true;
-      return false; // break.
-    }
-  });
-  return returnValue;
-};
-
-Drupal.webform.conditionalOperatorStringEmpty = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  var returnValue = true;
-  $.each(currentValue, function(n, value) {
-    if (value !== '') {
-      returnValue = false;
-      return false; // break.
-    }
-  });
-  return returnValue;
-};
-
-Drupal.webform.conditionalOperatorStringNotEmpty = function(element, existingValue, ruleValue) {
-  return !Drupal.webform.conditionalOperatorStringEmpty(element, existingValue, ruleValue);
-};
-
-Drupal.webform.conditionalOperatorSelectGreaterThan = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  return Drupal.webform.compare_select(currentValue[0], ruleValue, element) > 0;
-};
-
-Drupal.webform.conditionalOperatorSelectGreaterThanEqual = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element);
-  return comparison > 0 || comparison === 0;
-};
-
-Drupal.webform.conditionalOperatorSelectLessThan = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  return Drupal.webform.compare_select(currentValue[0], ruleValue, element) < 0;
-};
-
-Drupal.webform.conditionalOperatorSelectLessThanEqual = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element);
-  return comparison < 0 || comparison === 0;
-};
-
-Drupal.webform.conditionalOperatorNumericEqual = function(element, existingValue, ruleValue) {
-  // See float comparison: http://php.net/manual/en/language.types.float.php
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  var epsilon = 0.000001;
-  // An empty string does not match any number.
-  return currentValue[0] === '' ? false : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) < epsilon);
-};
-
-Drupal.webform.conditionalOperatorNumericNotEqual = function(element, existingValue, ruleValue) {
-  // See float comparison: http://php.net/manual/en/language.types.float.php
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  var epsilon = 0.000001;
-  // An empty string does not match any number.
-  return currentValue[0] === '' ? true : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) >= epsilon);
-};
-
-Drupal.webform.conditionalOperatorNumericGreaterThan = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  return parseFloat(currentValue[0]) > parseFloat(ruleValue);
-};
-
-Drupal.webform.conditionalOperatorNumericGreaterThanEqual = function(element, existingValue, ruleValue) {
-  return Drupal.webform.conditionalOperatorNumericGreaterThan(element, existingValue, ruleValue) ||
-         Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue);
-};
-
-Drupal.webform.conditionalOperatorNumericLessThan = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.stringValue(element, existingValue);
-  return parseFloat(currentValue[0]) < parseFloat(ruleValue);
-};
-
-Drupal.webform.conditionalOperatorNumericLessThanEqual = function(element, existingValue, ruleValue) {
-  return Drupal.webform.conditionalOperatorNumericLessThan(element, existingValue, ruleValue) ||
-         Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue);
-};
-
-Drupal.webform.conditionalOperatorDateEqual = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.dateValue(element, existingValue);
-  return currentValue === ruleValue;
-};
-
-Drupal.webform.conditionalOperatorDateNotEqual = function(element, existingValue, ruleValue) {
-  return !Drupal.webform.conditionalOperatorDateEqual(element, existingValue, ruleValue);
-};
-
-Drupal.webform.conditionalOperatorDateBefore = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.dateValue(element, existingValue);
-  return (currentValue !== false) && currentValue < ruleValue;
-};
-
-Drupal.webform.conditionalOperatorDateBeforeEqual = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.dateValue(element, existingValue);
-  return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue);
-};
-
-Drupal.webform.conditionalOperatorDateAfter = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.dateValue(element, existingValue);
-  return (currentValue !== false) && currentValue > ruleValue;
-};
-
-Drupal.webform.conditionalOperatorDateAfterEqual = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.dateValue(element, existingValue);
-  return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue);
-};
-
-Drupal.webform.conditionalOperatorTimeEqual = function(element, existingValue, ruleValue) {
-  var currentValue = Drupal.webform.timeValue(element, existingValue);
-  return currentValue === ruleValue;
-};
-
-Drupal.webform.conditionalOperatorTimeNotEqual = function(element, existingValue, ruleValue) {
-  return !Drupal.webform.conditionalOperatorTimeEqual(element, existingValue, ruleValue);
-};
-
-Drupal.webform.conditionalOperatorTimeBefore = function(element, existingValue, ruleValue) {
-  // Date and time operators intentionally exclusive for "before".
-  var currentValue = Drupal.webform.timeValue(element, existingValue);
-  return (currentValue !== false) && (currentValue < ruleValue);
-};
-
-Drupal.webform.conditionalOperatorTimeBeforeEqual = function(element, existingValue, ruleValue) {
-  // Date and time operators intentionally exclusive for "before".
-  var currentValue = Drupal.webform.timeValue(element, existingValue);
-  return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue);
-};
-
-Drupal.webform.conditionalOperatorTimeAfter = function(element, existingValue, ruleValue) {
-  // Date and time operators intentionally inclusive for "after".
-  var currentValue = Drupal.webform.timeValue(element, existingValue);
-  return (currentValue !== false) && (currentValue > ruleValue);
-};
-
-Drupal.webform.conditionalOperatorTimeAfterEqual = function(element, existingValue, ruleValue) {
-  // Date and time operators intentionally inclusive for "after".
-  var currentValue = Drupal.webform.timeValue(element, existingValue);
-  return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue);
-};
-
-/**
- * Utility function to compare values of a select component.
- * @param string a
- *   First select option key to compare
- * @param string b
- *   Second select option key to compare
- * @param array options
- *   Associative array where the a and b are within the keys
- * @return integer based upon position of $a and $b in $options
- *   -N if $a above (<) $b
- *   0 if $a = $b
- *   +N if $a is below (>) $b
- */
-Drupal.webform.compare_select = function(a, b, element) {
-  var optionList = [];
-  $('option,input:radio,input:checkbox', element).each(function() {
-    optionList.push($(this).val());
-  })
-  var a_position = optionList.indexOf(a);
-  var b_position = optionList.indexOf(b);
-  if (a_position < 0 && b_position < 0) {
-    return null;
-  }
-  else if (a_position < 0) {
-    return 1;
-  }
-  else if (b_position < 0) {
-    return -1;
-  }
-  else {
-    return a_position - b_position;
-  }
-}
-
-/**
- * Utility to return current visibility. Uses actual visibility, except for
- * hidden components which use the applied disabled class.
- */
-Drupal.webform.isVisible = function($element) {
-  return $element.hasClass('webform-component-hidden')
-            ? !$element.find('input').first().hasClass('webform-conditional-disabled')
-            : $element.closest('.webform-conditional-hidden').length == 0;
-}
-
-/**
- * Utility function to get a string value from a select/radios/text/etc. field.
- */
-Drupal.webform.stringValue = function(element, existingValue) {
-  var value = [];
-  if (element) {
-    var $element = $(element);
-    if (Drupal.webform.isVisible($element)) {
-      // Checkboxes and radios.
-      $element.find('input[type=checkbox]:checked,input[type=radio]:checked').each(function() {
-        value.push(this.value);
-      });
-      // Select lists.
-      if (!value.length) {
-        var selectValue = $element.find('select').val();
-        if (selectValue) {
-          if ($.isArray(selectValue)) {
-            value = selectValue;
-          }
-          else {
-            value.push(selectValue);
-          }
+    return value;
+  };
+
+  /**
+   * Utility function to calculate a second-based timestamp from a time field.
+   */
+  Drupal.webform.dateValue = function (element, existingValue) {
+    var value = false;
+    if (element) {
+      var $element = $(element);
+      if (Drupal.webform.isVisible($element)) {
+        var day = $element.find('[name*=day]').val();
+        var month = $element.find('[name*=month]').val();
+        var year = $element.find('[name*=year]').val();
+        // Months are 0 indexed in JavaScript.
+        if (month) {
+          month--;
+        }
+        if (year !== '' && month !== '' && day !== '') {
+          value = Date.UTC(year, month, day) / 1000;
         }
-      }
-      // Simple text fields. This check is done last so that the select list in
-      // select-or-other fields comes before the "other" text field.
-      if (!value.length) {
-        $element.find('input:not([type=checkbox],[type=radio]),textarea').each(function() {
-          value.push(this.value);
-        });
       }
     }
-  }
-  else {
-    switch ($.type(existingValue)) {
-      case 'array':
-        value = existingValue;
-        break;
-      case 'string':
-        value.push(existingValue);
-        break;
-    }
-  }
-  return value;
-};
-
-/**
- * Utility function to calculate a millisecond timestamp from a time field.
- */
-Drupal.webform.dateValue = function(element, existingValue) {
-  var value = false;
-  if (element) {
-    var $element = $(element);
-    if (Drupal.webform.isVisible($element)) {
-      var day = $element.find('[name*=day]').val();
-      var month = $element.find('[name*=month]').val();
-      var year = $element.find('[name*=year]').val();
-      // Months are 0 indexed in JavaScript.
-      if (month) {
-        month--;
+    else {
+      if ($.type(existingValue) === 'array' && existingValue.length) {
+        existingValue = existingValue[0];
       }
-      if (year !== '' && month !== '' && day !== '') {
-        value = Date.UTC(year, month, day) / 1000;
+      if ($.type(existingValue) === 'string') {
+        existingValue = existingValue.split('-');
+      }
+      if (existingValue.length === 3) {
+        value = Date.UTC(existingValue[0], existingValue[1], existingValue[2]) / 1000;
       }
     }
-  }
-  else {
-    if ($.type(existingValue) === 'array' && existingValue.length) {
-      existingValue = existingValue[0];
-    }
-    if ($.type(existingValue) === 'string') {
-      existingValue = existingValue.split('-');
-    }
-    if (existingValue.length === 3) {
-      value = Date.UTC(existingValue[0], existingValue[1], existingValue[2]) / 1000;
+    return value;
+  };
+
+  /**
+   * Utility function to calculate a millisecond timestamp from a time field.
+   */
+  Drupal.webform.timeValue = function (element, existingValue) {
+    var value = false;
+    if (element) {
+      var $element = $(element);
+      if (Drupal.webform.isVisible($element)) {
+        var hour = $element.find('[name*=hour]').val();
+        var minute = $element.find('[name*=minute]').val();
+        var ampm = $element.find('[name*=ampm]:checked').val();
+
+        // Convert to integers if set.
+        hour = (hour === '') ? hour : parseInt(hour);
+        minute = (minute === '') ? minute : parseInt(minute);
+
+        if (hour !== '') {
+          hour = (hour < 12 && ampm == 'pm') ? hour + 12 : hour;
+          hour = (hour === 12 && ampm == 'am') ? 0 : hour;
+        }
+        if (hour !== '' && minute !== '') {
+          value = Date.UTC(1970, 0, 1, hour, minute) / 1000;
+        }
+      }
     }
-  }
-  return value;
-};
-
-/**
- * Utility function to calculate a millisecond timestamp from a time field.
- */
-Drupal.webform.timeValue = function(element, existingValue) {
-  var value = false;
-  if (element) {
-    var $element = $(element);
-    if (Drupal.webform.isVisible($element)) {
-      var hour = $element.find('[name*=hour]').val();
-      var minute = $element.find('[name*=minute]').val();
-      var ampm = $element.find('[name*=ampm]:checked').val();
-
-      // Convert to integers if set.
-      hour = (hour === '') ? hour : parseInt(hour);
-      minute = (minute === '') ? minute : parseInt(minute);
-
-      if (hour !== '') {
-        hour = (hour < 12 && ampm == 'pm') ? hour + 12 : hour;
-        hour = (hour === 12 && ampm == 'am') ? 0 : hour;
+    else {
+      if ($.type(existingValue) === 'array' && existingValue.length) {
+        existingValue = existingValue[0];
       }
-      if (hour !== '' && minute !== '') {
-        value = Date.UTC(1970, 0, 1, hour, minute) / 1000;
+      if ($.type(existingValue) === 'string') {
+        existingValue = existingValue.split(':');
+      }
+      if (existingValue.length >= 2) {
+        value = Date.UTC(1970, 0, 1, existingValue[0], existingValue[1]) / 1000;
       }
     }
-  }
-  else {
-    if ($.type(existingValue) === 'array' && existingValue.length) {
-      existingValue = existingValue[0];
-    }
-    if ($.type(existingValue) === 'string') {
-      existingValue = existingValue.split(':');
-    }
-    if (existingValue.length >= 2) {
-      value = Date.UTC(1970, 0, 1, existingValue[0], existingValue[1]) / 1000;
-    }
-  }
-  return value;
-};
-
-/**
- * Make a prop shim for jQuery < 1.9.
- */
-$.fn.webformProp = function(name, value) {
-  if (value) {
-    $.fn.prop ? this.prop(name, true) : this.attr(name, true);
-  }
-  else {
-    $.fn.prop ? this.prop(name, false) : this.removeAttr(name);
-  }
-  return this;
-}
-
-/**
- * Make a multi-valued val() function for setting checkboxes, radios, and select
- * elements.
- */
-$.fn.webformVal = function(values) {
-  this.each(function() {
-    var $this = $(this);
-    var value = $this.val();
-    var on = $.inArray($this.val(), values) != -1;
-    if (this.nodeName == 'OPTION') {
-      $this.webformProp('selected', on ? value : false);
+    return value;
+  };
+
+  /**
+   * Make a prop shim for jQuery < 1.9.
+   */
+  $.fn.webformProp = $.fn.webformProp || function (name, value) {
+    if (value) {
+      return $.fn.prop ? this.prop(name, true) : this.attr(name, true);
     }
     else {
-      $this.val(on ? [value] : false);
+      return $.fn.prop ? this.prop(name, false) : this.removeAttr(name);
     }
-  });
-  return this;
-}
+  };
+
+  /**
+   * Make a multi-valued val() function for setting checkboxes, radios, and select
+   * elements.
+   */
+  $.fn.webformVal = function (values) {
+    this.each(function () {
+      var $this = $(this);
+      var value = $this.val();
+      var on = $.inArray($this.val(), values) != -1;
+      if (this.nodeName == 'OPTION') {
+        $this.webformProp('selected', on ? value : false);
+      }
+      else {
+        $this.val(on ? [value] : false);
+      }
+    });
+    return this;
+  };
 
 })(jQuery);
diff --git a/profiles/wcm_base/modules/contrib/webform/tests/conditionals.test b/profiles/wcm_base/modules/contrib/webform/tests/conditionals.test
index 3f16049e3a3c424e44a7245dc88d483be99e8b6a..a13b77aeda80d3348fcf47c31095f9b6b7860010 100644
--- a/profiles/wcm_base/modules/contrib/webform/tests/conditionals.test
+++ b/profiles/wcm_base/modules/contrib/webform/tests/conditionals.test
@@ -89,7 +89,7 @@ class WebformConditionalsTestCase extends WebformTestCase {
     $match_string = (is_array($conditional_values) ? print_r($conditional_values, 1) : $conditional_values);
     $conditional_string = $should_match ? 'should' : 'should not';
     $settings = array(
-      'title' => 'Test conditional webform: ' . $component['type'] . ' "' . $input_string .'"' . $conditional_string . ' be ' . $operator . ' "' . $match_string . '"',
+      'title' => 'Test conditional webform: ' . $component['type'] . ' "' . $input_string . '"' . $conditional_string . ' be ' . $operator . ' "' . $match_string . '"',
       'type' => 'webform',
       'webform' => webform_node_defaults(),
     );
diff --git a/profiles/wcm_base/modules/contrib/webform/views/webform.views.inc b/profiles/wcm_base/modules/contrib/webform/views/webform.views.inc
index 9590ae54a1b2326874376b2853f5a3034be58177..79ac3968facd24eb56ea09d7426927f1f021a974 100644
--- a/profiles/wcm_base/modules/contrib/webform/views/webform.views.inc
+++ b/profiles/wcm_base/modules/contrib/webform/views/webform.views.inc
@@ -574,7 +574,7 @@ function webform_views_pre_view($view, $display_id, $args) {
         if (webform_component_implements($component['type'], 'view_field')) {
           $new_fields = webform_component_invoke($component['type'], 'view_field', $component, $new_fields);
         }
-        foreach($new_fields as $sub_id => $new_field) {
+        foreach ($new_fields as $sub_id => $new_field) {
           $field_id = $new_id . ($sub_id ? '_' . $sub_id : '');
           $fields[$field_id] = $new_field;
           $new_columns[$field_id] = $field_id;
diff --git a/profiles/wcm_base/modules/contrib/webform/views/webform_handler_field_node_link_edit.inc b/profiles/wcm_base/modules/contrib/webform/views/webform_handler_field_node_link_edit.inc
index 2528b9a16dbe13d3e4b7a5071f56e3775acdbbe5..92f777b12280b0d91df7a1e9390091295bb37041 100644
--- a/profiles/wcm_base/modules/contrib/webform/views/webform_handler_field_node_link_edit.inc
+++ b/profiles/wcm_base/modules/contrib/webform/views/webform_handler_field_node_link_edit.inc
@@ -30,8 +30,8 @@ class webform_handler_field_node_link_edit extends views_handler_field_node_link
    * Renders the link.
    */
   function render_link($node, $values) {
-    // Ensure user has access to edit this node.
-    if (!node_access('update', $node)) {
+    // Ensure node is webform-enabled and user has access to edit this node.
+    if (!in_array($node->type, webform_node_types()) || !node_access('update', $node)) {
       return;
     }
 
diff --git a/profiles/wcm_base/modules/contrib/webform/views/webform_handler_field_node_link_results.inc b/profiles/wcm_base/modules/contrib/webform/views/webform_handler_field_node_link_results.inc
index 0102cc5fae866f1f90e9554db1d672306e87aa34..c41bdb0f909b7bd2ce3b4ff17a8942866c78d9b2 100644
--- a/profiles/wcm_base/modules/contrib/webform/views/webform_handler_field_node_link_results.inc
+++ b/profiles/wcm_base/modules/contrib/webform/views/webform_handler_field_node_link_results.inc
@@ -30,8 +30,8 @@ class webform_handler_field_node_link_results extends views_handler_field_node_l
    * Renders the link.
    */
   function render_link($node, $values) {
-    // Ensure user has access to edit this node.
-    if (!webform_results_access($node)) {
+    // Ensure node is webform-enabled and user has access node's webform results.
+    if (!in_array($node->type, webform_node_types()) || !webform_results_access($node)) {
       return;
     }
 
@@ -41,7 +41,7 @@ class webform_handler_field_node_link_results extends views_handler_field_node_l
     }
 
     $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['path'] = "node/$node->nid/webform-results".
+    $this->options['alter']['path'] = "node/$node->nid/webform-results" .
                                       (strlen($this->options['subpath']) ? '/' . $this->options['subpath'] : '');
 
     $text = !empty($this->options['text']) ? $this->options['text'] : t('results');
diff --git a/profiles/wcm_base/modules/contrib/webform/webform.api.php b/profiles/wcm_base/modules/contrib/webform/webform.api.php
index 88e0a634108f1209c69fbf81edf6dfb9afbdf5d7..131f4ed09560900bc150040e5b56777e7dabeafb 100644
--- a/profiles/wcm_base/modules/contrib/webform/webform.api.php
+++ b/profiles/wcm_base/modules/contrib/webform/webform.api.php
@@ -121,7 +121,7 @@ function hook_webform_submission_load(&$submissions) {
  *
  * @see webform_submission_create()
  */
-function hook_webform_submission_create($submission, $node, $account, $form_state) {
+function hook_webform_submission_create_alter(&$submission, &$node, &$account, &$form_state) {
   $submission->new_property = TRUE;
 }
 
@@ -835,6 +835,7 @@ function _webform_defaults_component() {
       'optrand' => 0,
       'qrand' => 0,
       'description' => '',
+      'description_above' => FALSE,
       'private' => FALSE,
       'analysis' => TRUE,
     ),
@@ -948,6 +949,8 @@ function hook_webform_component_render_alter(&$element, &$component) {
  *   Either 'html' or 'text'. Defines the format that the content should be
  *   returned as. Make sure that returned content is run through check_plain()
  *   or other filtering functions when returning HTML.
+ * @param $submission
+ *   The submission. Used to generate tokens.
  * @return
  *   A renderable element containing at the very least these properties:
  *    - #title
@@ -959,7 +962,7 @@ function hook_webform_component_render_alter(&$element, &$component) {
  *   which will properly format the label and content for use within an e-mail
  *   (such as wrapping the text) or as HTML (ensuring consistent output).
  */
-function _webform_display_component($component, $value, $format = 'html') {
+function _webform_display_component($component, $value, $format = 'html', $submission = array()) {
   return array(
     '#title' => $component['name'],
     '#weight' => $component['weight'],
@@ -991,6 +994,27 @@ function hook_webform_component_display_alter(&$element, &$component) {
   }
 }
 
+/**
+ * Performs the conditional action set on an implemented component.
+ *
+ * Setting the form element allows form validation functions to see the value
+ * that webform has set for the given component.
+ *
+ * @param array $component
+ *   The webform component array whose value is being set for the currently-
+ *   edited submission.
+ * @param array $element
+ *   The form element currently being set.
+ * @param array $form_state
+ *   The form's state.
+ * @param string $value
+ *   The value to be set, as defined in the conditional action.
+ */
+function _webform_action_set_component($component, &$element, &$form_state, $value) {
+  $element['#value'] = $value;
+  form_set_value($element, $value, $form_state);
+}
+
 /**
  * A hook for changing the input values before saving to the database.
  *
@@ -1333,6 +1357,39 @@ function hook_webform_html_capable_mail_systems_alter(&$systems) {
   }
 }
 
+/**
+ * Define a list of webform exporters.
+ *
+ * @return array
+ *   A list of the available exporters provided by the module.
+ *
+ * @see webform_webform_exporters()
+ */
+function hook_webform_exporters() {
+  $exporters = array(
+    'webform_exporter_custom' => array(
+      'title' => t('Webform exporter name'),
+      'description' => t('The description for this exporter.'),
+      'handler' => 'webform_exporter_custom',
+      'file' => drupal_get_path('module', 'yourmodule') . '/includes/webform_exporter_custom.inc',
+      'weight' => 10,
+    ),
+  );
+
+  return $exporters;
+}
+
+/**
+ * Modify the list of webform exporters definitions.
+ *
+ * @param  array &$exporters
+ *   A list of all available webform exporters.
+ */
+function hook_webform_exporters_alter(&$exporters) {
+  $exporters['excel']['handler'] = 'customized_excel_exporter';
+  $exporters['excel']['file'] = drupal_get_path('module', 'yourmodule') . '/includes/customized_excel_exporter.inc';
+}
+
 /**
  * @}
  */
diff --git a/profiles/wcm_base/modules/contrib/webform/webform.drush.inc b/profiles/wcm_base/modules/contrib/webform/webform.drush.inc
index 23f0ae5bdb5a15bc589a544719a9ee11405c546a..057ac45176dcd8d5946bc19fb89ace83042e9f86 100644
--- a/profiles/wcm_base/modules/contrib/webform/webform.drush.inc
+++ b/profiles/wcm_base/modules/contrib/webform/webform.drush.inc
@@ -1,8 +1,10 @@
 <?php
 
 /**
+ * @file
  * Implementation of hook_drush_command().
  */
+
 function webform_drush_command() {
   $items = array();
 
@@ -15,8 +17,8 @@ function webform_drush_command() {
       'file' => 'The file path to export to (defaults to print to stdout)',
       'format' => 'The exporter format to use. Out-of-the-box this may be "delimited" or "excel".',
       'delimiter' => 'Delimiter between columns (defaults to site-wide setting). This option may need to be wrapped in quotes. i.e. --delimter="\t".',
-      'components' => 'Comma-separated list of components IDs to include.' . "\n" .
-                      'May also include "serial", "sid", "time", "complete_time", "modified_time", "draft", "ip_address", "uid", and "username".',
+      'components' => 'Comma-separated list of component IDs or form keys to include.' . "\n" .
+                      'May also include "webform_serial", "webform_sid", "webform_time", "webform_complete_time", "webform_modified_time", "webform_draft", "webform_ip_address", "webform_uid", and "webform_username".',
       'header-keys' => 'Integer -1 for none, 0 for label (default) or 1 for field key.',
       'select-keys' => 'Integer 0 or 1 value. Set to 1 to print select list values by their field keys instead of labels.',
       'select-format' => 'Set to "separate" (default) or "compact" to determine how select list values are exported.',
@@ -63,6 +65,18 @@ function drush_webform_export($nid = FALSE) {
   }
   $options['components'] = is_array($options['components']) ? $options['components'] : explode(',', $options['components']);
 
+  // Map form keys to cids.
+  $form_keys = array();
+  foreach ($node->webform['components'] as $cid => $component) {
+    $form_keys[$component['form_key']] = $cid;
+  }
+  foreach ($options['components'] as $key => &$component) {
+    if (isset($form_keys[$component])) {
+      $component = $form_keys[$component];
+    }
+  }
+  unset($component); // Drop PHP reference.
+
   // Get the range options.
   unset($options['range']['range_type']);
   foreach (drush_get_merged_prefixed_options('range-') as $option_name => $option_value) {
diff --git a/profiles/wcm_base/modules/contrib/webform/webform.info b/profiles/wcm_base/modules/contrib/webform/webform.info
index 4676e9cdc9ba7c3548896d588cd18109c3d865a1..a0a36e2b26e60191ca1f365af27582af5c207884 100644
--- a/profiles/wcm_base/modules/contrib/webform/webform.info
+++ b/profiles/wcm_base/modules/contrib/webform/webform.info
@@ -40,9 +40,9 @@ files[] = tests/permissions.test
 files[] = tests/submission.test
 files[] = tests/webform.test
 
-; Information added by Drupal.org packaging script on 2015-04-29
-version = "7.x-4.8"
+; Information added by Drupal.org packaging script on 2015-09-22
+version = "7.x-4.11"
 core = "7.x"
 project = "webform"
-datestamp = "1430334485"
+datestamp = "1442953145"
 
diff --git a/profiles/wcm_base/modules/contrib/webform/webform.install b/profiles/wcm_base/modules/contrib/webform/webform.install
index 86f07614c675638104a7367aed0279c0176258e8..27a1c84613566ea9ad901f310d34e82b595d1f8e 100644
--- a/profiles/wcm_base/modules/contrib/webform/webform.install
+++ b/profiles/wcm_base/modules/contrib/webform/webform.install
@@ -491,6 +491,14 @@ function webform_schema() {
         'type' => 'text',
         'not null' => TRUE,
       ),
+      'status' => array(
+        'description' => 'Whether this email is enabled.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 1,
+      ),
     ),
     'primary key' => array('nid', 'eid'),
   );
@@ -734,14 +742,21 @@ function webform_install() {
     );
     $webform_type = node_type_set_defaults($webform_type);
     node_type_save($webform_type);
+    // Enable webform components by default on Webform nodes.
+    variable_set('webform_node_webform', TRUE);
+    // Now that a webform node type has been created, reset the cache of the
+    // node types that support webforms. This is needed for tests which will
+    // create nodes in the same execution.
+    drupal_static_reset('webform_node_types');
     if (variable_get('webform_install_add_body_field', FALSE)) {
       node_add_body_field($webform_type);
     }
-    // Enable webform components by default on Webform nodes.
-    variable_set('webform_node_webform', TRUE);
     // Disable comments by default on Webform nodes.
     variable_set('comment_webform', '0');
   }
+  else {
+    variable_set('webform_node_types_primary', array());
+  }
 
   // Note: MS SQL Server does not support size-limited indexes and the column
   // type (text) is too big to fit inside index size limits.
@@ -772,6 +787,7 @@ function webform_uninstall() {
   variable_del('webform_date_type');
   variable_del('webform_export_format');
   variable_del('webform_csv_delimiter');
+  variable_del('webform_csv_line_ending');
   variable_del('webform_export_wordwrap');
   variable_del('webform_excel_legacy_exporter');
   variable_del('webform_progressbar_style');
@@ -804,7 +820,7 @@ function webform_uninstall() {
   $query = new EntityFieldQuery();
   $results = $query->entityCondition('entity_type', 'node')
     ->entityCondition('bundle', 'webform')
-    ->range(0,1)
+    ->range(0, 1)
     ->execute();
   $instances = field_info_instances('node', 'webform');
   unset($instances['body']);
@@ -1053,7 +1069,7 @@ function webform_update_7314() {
  */
 function webform_update_7315() {
   if (!db_field_exists('webform_last_download', 'requested')) {
-    db_add_field('webform_last_download', 'requested', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0,));
+    db_add_field('webform_last_download', 'requested', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
   }
 }
 
@@ -1948,7 +1964,7 @@ function webform_update_7416() {
       ->execute();
   }
   // Commit the transaction
-  unset ($txn);
+  unset($txn);
 
   // Now that every submission has a serial number, make serial numbers required.
   $spec['not null'] = TRUE;
@@ -2023,7 +2039,7 @@ function webform_update_7421() {
                           FALSE);
   variable_set('webform_email_html_capable', $capable);
   return $capable
-            ? t('An HTML-capable module is installed. The option to send HTML e-mail is enabled. ')
+            ? t('An HTML-capable module is installed. The option to send HTML e-mail is enabled.')
             : t('No commonly-known HTML capable module is installed. The option to send HTML e-mail is disabled.');
 }
 
@@ -2126,7 +2142,7 @@ function webform_update_7423() {
 
   // Rebuild the registry because this point release contains a new class: WebformConditionals.
   registry_rebuild();
-  
+
   return t('Webform database tables were successfully adjusted to allow more than one action for each conditional.');
 }
 
@@ -2260,3 +2276,22 @@ function webform_update_7429() {
   return t('Webforms will now resume draft submissions on the page where the submitter left off.');
 }
 
+/**
+ * Add a column to the emails table to allow disabling.
+ */
+function webform_update_7430() {
+  // Add status column to webform_emails.
+  if (!db_field_exists('webform_emails', 'status')) {
+    $spec = array(
+      'description' => 'Whether this email is enabled.',
+      'type' => 'int',
+      'unsigned' => TRUE,
+      'size' => 'tiny',
+      'not null' => TRUE,
+      'default' => 1,
+    );
+    db_add_field('webform_emails', 'status', $spec);
+  }
+
+  return t('Webform emails may now be disabled.');
+}
diff --git a/profiles/wcm_base/modules/contrib/webform/webform.module b/profiles/wcm_base/modules/contrib/webform/webform.module
index 5936c26138b6365c72da5f7f6f6c34c9f83c2dc8..08c6a6196f965b6b455da5541e9bcd5d85645e20 100644
--- a/profiles/wcm_base/modules/contrib/webform/webform.module
+++ b/profiles/wcm_base/modules/contrib/webform/webform.module
@@ -514,6 +514,9 @@ function webform_menu_email_load($eid, $nid) {
         $email['email'] = $_GET['email'];
       }
     }
+    if (isset($_GET['status'])) {
+      $email['status'] = $_GET['status'];
+    }
   }
 
   return $email;
@@ -613,6 +616,12 @@ function webform_submission_access($node, $submission, $op = 'view', $account =
 
   $token_access = $submission && isset($_GET['token']) && $_GET['token'] == webform_get_submission_access_token($submission);
 
+  // If access is granted via a token, then allow subsequent submission access
+  // for anonymous users.
+  if (!$user->uid && $token_access) {
+    $_SESSION['webform_submission'][$submission->sid] = $node->nid;
+  }
+
   $general_access = $access_all || $access_own_submission || $access_node_submissions || $token_access;
 
   // Disable the page cache for anonymous users in this access callback,
@@ -1085,6 +1094,9 @@ function webform_webform_component_info() {
       ),
       'file' => 'components/number.inc',
       'conditional_type' => 'numeric',
+      'features' => array(
+        'conditional_action_set' => TRUE,
+      ),
     ),
     'pagebreak' => array(
       'label' => t('Page break'),
@@ -1392,10 +1404,13 @@ function webform_file_download($uri) {
  *   An array of node type names.
  */
 function webform_node_types() {
-  $types = array();
-  foreach (node_type_get_names() as $type => $name) {
-    if (variable_get('webform_node_' . $type, FALSE)) {
-      $types[] = $type;
+  $types = &drupal_static(__FUNCTION__, NULL);
+  if (!isset($types)) {
+    $types = array();
+    foreach (node_type_get_names() as $type => $name) {
+      if (variable_get('webform_node_' . $type, FALSE)) {
+        $types[] = $type;
+      }
     }
   }
   return $types;
@@ -2084,7 +2099,7 @@ function theme_webform_view_messages($variables) {
     $message = t('Submissions for this form are closed.');
   }
   elseif ($node->webform['confidential'] && user_is_logged_in()) {
-    $message = t('This form is confidential. You much <a href="!url">Log out</a> to submit it.',
+    $message = t('This form is confidential. You must <a href="!url">Log out</a> to submit it.',
                  array('!url' => url('/user/logout', array('query' => array('destination' => request_uri())))));
   }
   // If open and not allowed to submit the form, give an explanation.
@@ -2250,7 +2265,8 @@ function webform_block_view($delta = '') {
         '#node' => $node,
         '#sid' => $_SESSION['webform_confirmation'][$nid]['sid'],
       );
-    } elseif (strlen(trim(strip_tags($node->webform['confirmation'])))) {
+    } 
+    elseif (strlen(trim(strip_tags($node->webform['confirmation'])))) {
       // Display confirmation link drupal status messages, but in the block.
       $message = webform_replace_tokens($node->webform['confirmation'],
                                         $node,
@@ -2398,6 +2414,12 @@ function webform_client_form($form, &$form_state, $node, $submission = FALSE, $r
   form_load_include($form_state, 'inc', 'webform', 'includes/webform.components');
   form_load_include($form_state, 'inc', 'webform', 'includes/webform.submissions');
 
+  // For ajax requests, $form_state['values']['details'] is missing. Restore
+  // from storage, if available, for multi-page forms.
+  if (empty($form_state['values']['details']) && !empty($form_state['storage']['details'])) {
+    $form_state['values']['details'] = $form_state['storage']['details'];
+  }
+
   // If in a multi-step form, a submission ID may be specified in form state.
   // Load this submission. This allows anonymous users to use auto-save.
   if (empty($submission) && !empty($form_state['values']['details']['sid'])) {
@@ -2504,6 +2526,9 @@ function webform_client_form($form, &$form_state, $node, $submission = FALSE, $r
     // Allow values from other pages to be sent to browser for conditionals.
     $form['#conditional_values'] = $input_values;
 
+    // Allow components access to most up-to-date values.
+    $form_state['#conditional_values'] = $input_values;
+
     // For resuming a previous draft, find the next page after the last
     // validated page.
     if (!isset($form_state['storage']['page_num']) && $submission && $submission->is_draft && $submission->highest_valid_page) {
@@ -2520,11 +2545,11 @@ function webform_client_form($form, &$form_state, $node, $submission = FALSE, $r
         // Force a preview to avert an unintended submission via Next.
         $form_state['webform']['preview'] = TRUE;
         $form_state['webform']['page_count']++;
-        // The form hasn't been submitted (ever) and the preview code will
-        // expect $form_state['values']['submitted'] to be set from a previous
-        // submission, so provide these values here.
-        $form_state['values']['submitted'] = $input_values;
       }
+      // The form hasn't been submitted (ever) and the preview code will
+      // expect $form_state['values']['submitted'] to be set from a previous
+      // submission, so provide these values here.
+      $form_state['values']['submitted'] = $input_values;
       $form_state['storage']['submitted'] = $input_values;
     }
 
@@ -2739,7 +2764,7 @@ function _webform_client_form_add_component($node, $component, $component_value,
   if ($format != 'form') {
     // This component is display only.
     $data = empty($input_values[$cid]) ? NULL : $input_values[$cid];
-    if ($display_element = webform_component_invoke($component['type'], 'display', $component, $data, $format)) {
+    if ($display_element = webform_component_invoke($component['type'], 'display', $component, $data, $format, $form['#submission'])) {
       // Set access based on the private property.
       $display_element += array('#access' => TRUE);
       $display_element['#access'] = $display_element['#access'] && $component_access;
@@ -2923,16 +2948,35 @@ function _webform_client_form_validate(&$elements, &$form_state, $form_id = NULL
     $sorter = webform_get_conditional_sorter($form_state['complete form']['#node']);
     $cid = $elements['#webform_component']['cid'];
     $page_num = $form_state['values']['details']['page_num'];
-    // Webform-specific enhancement, only validate the field if it was used in this submission.
-    // This both skips validation on the field and sets the value of the field to NULL, preventing any dangerous input.
-    // Short-circuit validation for a hidden component (hidden by rules dependent upon component on previous pages),
-    // or a component this is dependent upon values on the current page, but is hidden based upon their current values.
+    // Webform-specific enhancements:
+    // 1) Only validate the field if it was used in this submission.
+    //    This both skips validation on the field and sets the value of the
+    //    field to NULL, preventing any dangerous input. Short-circuit
+    //    validation for a hidden component (hidden by rules dependent upon
+    //    component on previous pages), or a component this is dependent upon
+    //    values on the current page, but is hidden based upon their current
+    //    values.
+    // 2) Only valididate if the field has not been set by conditionals.
+    //    The user will be unable to fix the validation without surmising the
+    //    logic and changing the trigger for the conditional. Also, it isn't
+    //    possible to set $element['#value'] without component-specific
+    //    knowledge of how the data is stored because $input_values is already
+    //    webform-normalized to contain values in arrays.
     if ($sorter->componentVisibility($cid, $page_num) != WebformConditionals::componentShown) {
       form_set_value($elements, NULL, $form_state);
       return;
     }
+    if ($sorter->componentSet($cid, $page_num)) {
+      $component = $elements['#webform_component'];
+      $value = $input_values[$cid];
+      $value = is_array($value) ? $value[0] : $value;
+      // webform_component_invoke cannot be called with reference arguments. Call directly.
+      // webform_component_invoke($component['type'], 'action_set', $component, $elements, $form_state, $value);
+      $function = '_webform_action_set_' . $component['type'];
+      $function($component, $elements, $form_state, $value);
+    }
 
-    // Check for changes in requires status made by conditionals.
+    // Check for changes in required status made by conditionals.
     $required = $sorter->componentRequired($cid, $page_num);
     if (isset($required)) {
       $elements['#required'] = $required;
@@ -3210,6 +3254,9 @@ function webform_client_form_submit($form, &$form_state) {
   // exist, but webform_get_submission() will not find the draft. So, make a new
   // submission.
   if ($sid && $submission = webform_get_submission($node->webform['nid'], $sid)) {
+    // Store original data on object for use in update hook.
+    $submission->original = clone $submission;
+
     // Merge with new submission data. The + operator maintains numeric keys.
     // This maintains existing data with just-submitted data when a user resumes
     // a submission previously saved as a draft.
@@ -3251,6 +3298,11 @@ function webform_client_form_submit($form, &$form_state) {
     $form_state['values']['details']['sid'] = $sid = webform_submission_insert($node, $submission);
     $form_state['values']['details']['is_new'] = TRUE;
 
+    // Save the new details in storage. When ajax calls for file upload/remove,
+    // $form_state['values']['details'] is missing. This allows the proper
+    // submission to be retrieved in webform_client_form. See #2562703.
+    $form_state['storage']['details'] = $form_state['values']['details'];
+
     // Set a cookie including the server's submission time. The cookie expires
     // in the length of the interval plus a day to compensate for timezones.
     $tracking_mode = webform_variable_get('webform_tracking_mode');
@@ -3264,7 +3316,7 @@ function webform_client_form_submit($form, &$form_state) {
     // Save session information about this submission for anonymous users,
     // allowing them to access or edit their submissions.
     if (!$user->uid && user_access('access own webform submissions')) {
-      $_SESSION['webform_submission'][$form_state['values']['details']['sid']] = $node->nid;
+      $_SESSION['webform_submission'][$sid] = $node->nid;
     }
   }
   else {
@@ -3436,7 +3488,7 @@ function template_preprocess_webform_confirmation(&$vars) {
 
   // URL back to form (or same page for in-block confirmations).
   $vars['url'] = empty($node->webform_block)
-                    ? url('node/'. $node->nid)
+                    ? url('node/' . $node->nid)
                     : url(current_path(), array('query' => drupal_get_query_parameters()));
 
   // Progress bar.
@@ -3519,9 +3571,10 @@ function template_preprocess_webform_element(&$variables) {
   // Ensure defaults.
   $element += array(
     '#title_display' => 'before',
-    '#wrapper_attributes' => array(
-      'class' => array(),
-    ),
+    '#wrapper_attributes' => array(),
+  );
+  $element['#wrapper_attributes'] += array(
+    'class' => array(),
   );
 
   // All elements using this for display only are given the "display" type.
@@ -3574,37 +3627,37 @@ function theme_webform_element($variables) {
   $prefix = isset($element['#field_prefix']) ? '<span class="field-prefix">' . webform_filter_xss($element['#field_prefix']) . '</span> ' : '';
   $suffix = isset($element['#field_suffix']) ? ' <span class="field-suffix">' . webform_filter_xss($element['#field_suffix']) . '</span>' : '';
 
-  // managed_file uses a different id, make sure the label points to the correct id.
-  if (isset($element['#type']) && $element['#type'] === 'managed_file') {
-    if (!empty($variables['element']['#id'])) {
-      $variables['element']['#id'] .= '-upload';
-    }
-  }
+  // Generate description for above or below the field.
+  $above = !empty($element['#webform_component']['extra']['description_above']);
+  $description = array(
+    FALSE => '',
+    TRUE => !empty($element['#description']) ? ' <div class="description">' . $element['#description'] . "</div>\n" : '',
+  );
 
   switch ($element['#title_display']) {
     case 'inline':
+      $output .= $description[$above];
+      $description[$above] = '';
+      // FALL THRU.
     case 'before':
     case 'invisible':
       $output .= ' ' . theme('form_element_label', $variables);
-      $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
+      $output .= ' ' . $prefix . $description[$above] . $element['#children'] . $suffix . "\n";
       break;
 
     case 'after':
-      $output .= ' ' . $prefix . $element['#children'] . $suffix;
+      $output .= ' ' . $prefix . $description[$above] . $element['#children'] . $suffix;
       $output .= ' ' . theme('form_element_label', $variables) . "\n";
       break;
 
     case 'none':
     case 'attribute':
       // Output no label and no required marker, only the children.
-      $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
+      $output .= ' ' . $prefix . $description[$above] . $element['#children'] . $suffix . "\n";
       break;
   }
 
-  if (!empty($element['#description'])) {
-    $output .= ' <div class="description">' . $element['#description'] . "</div>\n";
-  }
-
+  $output .= $description[!$above];
   $output .= "</div>\n";
 
   return $output;
@@ -3869,7 +3922,7 @@ function webform_replace_tokens($string, $node = NULL, $submission = NULL, $emai
   $clear = is_bool($sanitize);
   $string = token_replace($string, $token_data, array('clear' => $clear, 'sanitize' => $sanitize === TRUE));
   if (!$clear) {
-    $string = webform_clear_tokens(check_markup($string, $sanitize));
+    $string = webform_replace_tokens_clear(check_markup($string, $sanitize));
   }
   return $string;
 }
@@ -3887,11 +3940,14 @@ function webform_replace_tokens($string, $node = NULL, $submission = NULL, $emai
  * there is no value provided. These tokens i.e. [current-page:query:*] needs to
  * be removed to not show up in the output.
  *
+ * Note: This function was previously named webform_clear_tokens, which
+ * conflicted with the webform_clear module, being called as hook_tokens.
+ *
  * @param string $text
  *   The text to have its tokens removed.
  * @see token_replace()
  */
-function webform_clear_tokens($text) {
+function webform_replace_tokens_clear($text) {
   if (empty($text)) {
     return $text;
   }
@@ -4142,6 +4198,9 @@ function webform_variable_get($variable) {
     case 'webform_csv_delimiter':
       $result = variable_get('webform_csv_delimiter', '\t');
       break;
+    case 'webform_csv_line_ending':
+      $result = variable_get('webform_csv_line_ending', "\n");
+      break;
     case 'webform_export_wordwrap':
       $result = variable_get('webform_export_wordwrap', 0);
       break;
@@ -4290,7 +4349,7 @@ function webform_format_email_address($address, $name, $node = NULL, $submission
       if (webform_component_implements($component['type'], 'options')) {
         $options = webform_component_invoke($component['type'], 'options', $component);
         foreach ($name as &$one_name) {
-          $name = isset($options[$one_name]) ? $options[$one_name] : $name;
+          $one_name = isset($options[$one_name]) ? $options[$one_name] : $one_name;
         }
         unset($one_name); // Drop PHP reference.
       }
@@ -4362,14 +4421,16 @@ function webform_format_email_address($address, $name, $node = NULL, $submission
  *   TRUE if optional. FALSE if required.
  * @param boolean $allow_multiple
  *   TRUE if a list of emails is allowed. FALSE if only one.
+ * @param boolean $allow_tokens
+ *   TRUE if any token should be assumed to contain a valid e-mail address.
  * @param string $format
  *   'short', 'long', or NULL (for default) format. Long format has a name and
  *   the address in angle brackets.
  * @return integer|boolean
  *   The number of valid addresses found, or FALSE for an invalid email found.
  */
-function webform_email_validate(&$emails, $form_name, $allow_empty, $allow_multiple, $format = NULL) {
-  $nr_valid = webform_valid_email_address($emails, $format);
+function webform_email_validate(&$emails, $form_name, $allow_empty, $allow_multiple, $allow_tokens, $format = NULL) {
+  $nr_valid = webform_valid_email_address($emails, $allow_tokens, $format);
   if ($nr_valid === FALSE) {
     form_set_error($form_name, t('The entered e-mail address "@email" does not appear valid.', array('@email' => $emails)));
   }
@@ -4389,6 +4450,8 @@ function webform_email_validate(&$emails, $form_name, $allow_empty, $allow_multi
  *   An email address, a list of comma-separated email addresses. If all the
  *   addresses are valid, the list of trimmed, non-empty emails is returned by
  *   reference.
+ * @param boolean $allow_tokens
+ *   TRUE if any token should be assumed to contain a valid e-mail address.
  * @param string $format
  *   'short', 'long', or NULL (for default) format. Long format has a name and
  *   the address in angle brackets.
@@ -4396,10 +4459,17 @@ function webform_email_validate(&$emails, $form_name, $allow_empty, $allow_multi
  *   Returns FALSE if an invalid e-mail address was found, 0 if no email
  *   address(es) were found, or the number of valid e-mail addresses found.
  */
-function webform_valid_email_address(&$emails, $format = NULL) {
+function webform_valid_email_address(&$emails, $allow_tokens = FALSE, $format = NULL) {
   $email_array = array_filter(array_map('trim', explode(',', $emails)));
   $count = 0;
   foreach ($email_array as $email) {
+    if ($allow_tokens) {
+      foreach (token_scan($email) as $tokens) {
+        foreach ($tokens as $token) {
+          $email = str_replace($token, 'admin@example.com', $email);
+        }
+      }
+    }
     $matches = webform_parse_email_address($email, $format);
     if (!valid_email_address($matches['address'])) {
       return FALSE;
diff --git a/profiles/wcm_base/modules/contrib/webform/webform.tokens.inc b/profiles/wcm_base/modules/contrib/webform/webform.tokens.inc
index 658177b75607cf2d3045e4a897b8474eb5da3fa9..5e49bfb8f2a847791c9edb7820333292f7d7f169 100644
--- a/profiles/wcm_base/modules/contrib/webform/webform.tokens.inc
+++ b/profiles/wcm_base/modules/contrib/webform/webform.tokens.inc
@@ -64,13 +64,15 @@ function webform_token_info() {
   );
   $info['tokens']['submission']['values'] = array(
     'name' => t('Webform submission values'),
-    'description' => t('<div>Webform tokens from submitted data. Replace the "?" with the "field key", including any parent field keys separated by colons. You can append:</div><ul>' .
-                       '<li>the question key for just that one question (grid components).</li>' .
-                       '<li>the option key for just that one option (grid and select components).' .
-                       '<li>":nolabel" for the value without the label (the default)</li>' .
-                       '<li>":label" for just the label.</li>' .
-                       '<li>":withlabel" for both the label and value together.</li>' .
-                       '<li>":key" for just the key in a key|label pair (grid and select components).</li></ul>'),
+    'description' => '<div>' . t('Webform tokens from submitted data. Replace the "?" with the "field key", including any parent field keys separated by colons. You can append:') . '</div>' .
+                     '<ul>' .
+                     '<li>' . t('the question key for just that one question (grid components).') . '</li>' .
+                     '<li>' . t('the option key for just that one option (grid and select components).') . '</li>' .
+                     '<li>' . t('<code>@token</code> for the value without the label (the default).', array('@token' => ':nolabel')) . '</li>' .
+                     '<li>' . t('<code>@token</code> for just the label.', array('@token' => ':label')) . '</li>' .
+                     '<li>' . t('<code>@token</code> for both the label and value together.', array('@token' => ':withlabel')) . '</li>' .
+                     '<li>' . t('<code>@token</code> for just the key in a key|label pair (grid and select components).', array('@token' => ':key')) . '</li>' .
+                     '</ul>',
     'dynamic' => TRUE,
   );
 
@@ -81,192 +83,204 @@ function webform_token_info() {
  * Implements hook_tokens().
  */
 function webform_tokens($type, $tokens, array $data = array(), array $options = array()) {
-  $replacements = array();
+  static $recursion_level = 0;
 
-  $url_options = array('absolute' => TRUE);
-  if (isset($options['language'])) {
-    $url_options['language'] = $options['language'];
-    $language_code = $options['language']->language;
-  }
-  else {
-    $language_code = NULL;
+  // Return early unless submission tokens are needed and there is a submission.
+  if ($type != 'submission' || empty($data['webform-submission'])) {
+    return array();
   }
 
+  // Generate Webform tokens.
+  $replacements = array();
+
+  // Prepare all the data that we will likely need more than once.
+  $submission = $data['webform-submission'];
+  $node = isset($data['node']) ? $data['node'] : node_load($submission->nid);
+  $email = isset($data['webform-email']) ? $data['webform-email'] : NULL;
   $sanitize = !empty($options['sanitize']);
+  $format = $sanitize ? 'html' : 'text';
+  $url_options = isset($options['language']) ? $options['language'] : array('absolute' => TRUE);
+  $language_code = isset($options['language']) ? $options['language']->language : NULL;
+  $markup_components = array();
 
-  // Webform tokens (caching globally).
-  if ($type == 'submission' && !empty($data['webform-submission'])) {
-    // Prepare all the submission data that we will likely need more than once.
-    $submission = $data['webform-submission'];
-    $node = isset($data['node']) ? $data['node'] : node_load($submission->nid);
-    $email = isset($data['webform-email']) ? $data['webform-email'] : NULL;
-    $excluded_components = isset($email['excluded_components']) ? $email['excluded_components'] : array();
-    $format = $sanitize ? 'html' : 'text';
+  // Markup components may use tokens when displayed. Displaying the tokens
+  // requires rendering the components. Rendering a markup component can then
+  // cause infinite recursion. To prevent this, markup components are omitted
+  // from the rendered submission if recursion has been detected.
+  if ($recursion_level) {
+    $markup_components = array_keys(array_filter($node->webform['components'],
+                                                 function ($component) { return $component['type'] == 'markup'; }));
+  }
 
-    // Replace individual tokens that have an exact replacement.
-    foreach ($tokens as $name => $original) {
-      switch ($name) {
-        case 'serial':
-          $replacements[$original] = $submission->serial ? $submission->serial : '';
-          break;
-        case 'sid':
-          $replacements[$original] = $submission->sid ? $submission->sid : '';
-          break;
-        case 'access-token':
-          $replacements[$original] = webform_get_submission_access_token($submission);
-          break;
-        case 'date':
-          $replacements[$original] = format_date($submission->submitted, webform_variable_get('webform_date_type'), '', NULL, $language_code);
-          break;
-        case 'completed_date':
-          if ($submission->completed) {
-            $replacements[$original] = format_date($submission->completed, webform_variable_get('webform_date_type'), '', NULL, $language_code);
-          }
-          break;
-        case 'modified_date':
-          $replacements[$original] = format_date($submission->modified, webform_variable_get('webform_date_type'), '', NULL, $language_code);
-          break;
-        case 'ip-address':
-          $replacements[$original] = $sanitize ? check_plain($submission->remote_addr) : $submission->remote_addr;
-          break;
-        case 'user':
-          $account = user_load($submission->uid);
-          $name = format_username($account);
-          $replacements[$original] = $sanitize ? check_plain($name) : $name;
-          break;
-        case 'url':
-          $replacements[$original] = $submission->sid ? url("node/{$node->nid}/submission/{$submission->sid}", $url_options) : '';
-          break;
-        case 'edit-url':
-          $replacements[$original] = $submission->sid ? url("node/{$node->nid}/submission/{$submission->sid}/edit", $url_options) : '';
-          break;
-        case 'values':
-          $submission_renderable = webform_submission_render($node, $submission, $email, $format, $excluded_components);
-          $replacements[$original] = drupal_render($submission_renderable);
-          break;
-      }
+  $recursion_level++;
+
+  // Replace individual tokens that have an exact replacement.
+  foreach ($tokens as $name => $original) {
+    switch ($name) {
+      case 'serial':
+        $replacements[$original] = $submission->serial ? $submission->serial : '';
+        break;
+      case 'sid':
+        $replacements[$original] = $submission->sid ? $submission->sid : '';
+        break;
+      case 'access-token':
+        $replacements[$original] = webform_get_submission_access_token($submission);
+        break;
+      case 'date':
+        $replacements[$original] = format_date($submission->submitted, webform_variable_get('webform_date_type'), '', NULL, $language_code);
+        break;
+      case 'completed_date':
+        if ($submission->completed) {
+          $replacements[$original] = format_date($submission->completed, webform_variable_get('webform_date_type'), '', NULL, $language_code);
+        }
+        break;
+      case 'modified_date':
+        $replacements[$original] = format_date($submission->modified, webform_variable_get('webform_date_type'), '', NULL, $language_code);
+        break;
+      case 'ip-address':
+        $replacements[$original] = $sanitize ? check_plain($submission->remote_addr) : $submission->remote_addr;
+        break;
+      case 'user':
+        $account = user_load($submission->uid);
+        $name = format_username($account);
+        $replacements[$original] = $sanitize ? check_plain($name) : $name;
+        break;
+      case 'url':
+        $replacements[$original] = $submission->sid ? url("node/{$node->nid}/submission/{$submission->sid}", $url_options) : '';
+        break;
+      case 'edit-url':
+        $replacements[$original] = $submission->sid ? url("node/{$node->nid}/submission/{$submission->sid}/edit", $url_options) : '';
+        break;
+      case 'values':
+        $excluded_components = isset($email['excluded_components']) ? $email['excluded_components'] : array();
+        $excluded_components = array_merge($excluded_components, $markup_components);
+        $submission_renderable = webform_submission_render($node, $submission, $email, $format, $excluded_components);
+        $replacements[$original] = drupal_render($submission_renderable);
+        break;
     }
+  }
 
-    // Webform submission tokens for individual components.
-    if ($value_tokens = token_find_with_prefix($tokens, 'values')) {
-      // Get the full submission renderable without $excluded_components so that
-      // individually referenced values are available.
-      $submission_renderable = webform_submission_render($node, $submission, $email, $format);
-      $available_modifiers = array(
-        'label',
-        'withlabel',
-        'nolabel',
-        'key',
-      );
+  // Webform submission tokens for individual components.
+  if ($value_tokens = token_find_with_prefix($tokens, 'values')) {
+    // Get the full submission renderable without $excluded_components so that
+    // individually referenced values are available.
+    $submission_renderable = webform_submission_render($node, $submission, $email, $format, $markup_components);
+    $available_modifiers = array(
+      'label',
+      'withlabel',
+      'nolabel',
+      'key',
+    );
 
-      foreach ($node->webform['components'] as $cid => $component) {
-        // Build the list of parents for this component.
-        $parents = ($component['pid'] == 0) ? array($component['form_key']) : webform_component_parent_keys($node, $component);
-        $parent_token = implode(':', $parents);
-        foreach ($value_tokens as $name => $original) {
-          if (strpos($name, $parent_token) !== 0) {
-            // Token not found as a prefix or exact match for this component.
-            continue;   // Token loop continue.
-          }
-          // Drill down into the renderable to find the element.
-          $display_element = $submission_renderable;
-          foreach ($parents as $parent) {
-            if (!isset($display_element[$parent])) {
-              // Sometimes an element won't exist in the submission renderable
-              // due to conditional logic. If not found, skip that element.
-              continue 2;   // Token loop continue.
-            }
-            $display_element = $display_element[$parent];
+    foreach ($node->webform['components'] as $cid => $component) {
+      // Build the list of parents for this component.
+      $parents = ($component['pid'] == 0) ? array($component['form_key']) : webform_component_parent_keys($node, $component);
+      $parent_token = implode(':', $parents);
+      foreach ($value_tokens as $name => $original) {
+        if (strpos($name, $parent_token) !== 0) {
+          // Token not found as a prefix or exact match for this component.
+          continue;   // Token loop continue.
+        }
+        // Drill down into the renderable to find the element.
+        $display_element = $submission_renderable;
+        foreach ($parents as $parent) {
+          if (!isset($display_element[$parent])) {
+            // Sometimes an element won't exist in the submission renderable
+            // due to conditional logic. If not found, skip that element.
+            continue 2;   // Token loop continue.
           }
-          // Individual tokens always have access granted even if they're
-          // not displayed when printing the whole renderable.
-          $display_element['#access'] = TRUE;
+          $display_element = $display_element[$parent];
+        }
+        // Individual tokens always have access granted even if they're
+        // not displayed when printing the whole renderable.
+        $display_element['#access'] = TRUE;
 
-          // For grid components, see if optional question key is present.
-          $matched_token = $parent_token;
-          if ($display_element['#webform_component']['type'] === 'grid') {
-            list($question_key) = explode(':', substr($name, strlen($matched_token) + 1));
-            if (strlen($question_key) && isset($display_element[$question_key]['#value'])) {
-              // Generate a faux select component for this grid question.
-              $select_component = _webform_defaults_select();
-              $select_component['type'] = 'select';
-              $select_component['nid'] = $display_element['#webform_component']['nid'];
-              $select_component['name'] = $display_element['#grid_questions'][$question_key];
-              $select_component['extra']['items'] = $display_element['#webform_component']['extra']['options'];
-              $display_element = _webform_display_select($select_component, $display_element[$question_key]['#value'], $format);
-              $display_element['#webform_component'] = $select_component;
-              $matched_token .= ':' . $question_key;
-            }
+        // For grid components, see if optional question key is present.
+        $matched_token = $parent_token;
+        if ($display_element['#webform_component']['type'] === 'grid') {
+          list($question_key) = explode(':', substr($name, strlen($matched_token) + 1));
+          if (strlen($question_key) && isset($display_element[$question_key]['#value'])) {
+            // Generate a faux select component for this grid question.
+            $select_component = _webform_defaults_select();
+            $select_component['type'] = 'select';
+            $select_component['nid'] = $display_element['#webform_component']['nid'];
+            $select_component['name'] = $display_element['#grid_questions'][$question_key];
+            $select_component['extra']['items'] = $display_element['#webform_component']['extra']['options'];
+            $display_element = _webform_display_select($select_component, $display_element[$question_key]['#value'], $format);
+            $display_element['#webform_component'] = $select_component;
+            $matched_token .= ':' . $question_key;
           }
+        }
 
-          // For select components, see if the optional option key is present.
-          if ($display_element['#webform_component']['type'] === 'select') {
-            list($option_key) = explode(':', substr($name, strlen($matched_token) + 1));
-            if (strlen($option_key) && strpos("\n" . $display_element['#webform_component']['extra']['items'], "\n" . $option_key . '|') !== FALSE) {
-              // Return only this specified option and no other values.
-              $display_element['#value'] = array_intersect($display_element['#value'], array($option_key));
-              $matched_token .= ':' . $option_key;
-            }
+        // For select components, see if the optional option key is present.
+        if ($display_element['#webform_component']['type'] === 'select') {
+          list($option_key) = explode(':', substr($name, strlen($matched_token) + 1));
+          if (strlen($option_key) && strpos("\n" . $display_element['#webform_component']['extra']['items'], "\n" . $option_key . '|') !== FALSE) {
+            // Return only this specified option and no other values.
+            $display_element['#value'] = array_intersect($display_element['#value'], array($option_key));
+            $matched_token .= ':' . $option_key;
           }
+        }
 
-          // Assume no modifier (implied 'nolabel').
-          $modifier = NULL;
-          if (strcmp($name, $matched_token) !== 0) {
-            // Check if this matches the key plus a modifier.
-            $modifier = substr($name, strrpos($name, ':') + 1);
-            // TODO: Allow components to provide additional modifiers per
-            // type, i.e. key, day, hour, minute, etc.
-            if (strcmp($name, $matched_token . ':' . $modifier) !== 0 || !in_array($modifier, $available_modifiers)) {
-              // No match.
-              continue;   // Token loop continue.
-            }
+        // Assume no modifier (implied 'nolabel').
+        $modifier = NULL;
+        if (strcmp($name, $matched_token) !== 0) {
+          // Check if this matches the key plus a modifier.
+          $modifier = substr($name, strrpos($name, ':') + 1);
+          // TODO: Allow components to provide additional modifiers per
+          // type, i.e. key, day, hour, minute, etc.
+          if (strcmp($name, $matched_token . ':' . $modifier) !== 0 || !in_array($modifier, $available_modifiers)) {
+            // No match.
+            continue;   // Token loop continue.
           }
+        }
 
-          if ($modifier === 'label') {
-            $replacements[$original] = webform_filter_xss($display_element['#title']);
-          }
-          elseif ($modifier === 'key' && $display_element['#webform_component']['type'] === 'select') {
-            $values = array();
-            foreach ($display_element['#value'] as $value) {
-              $values[] = webform_filter_xss($value);
-            }
-            $replacements[$original] = implode(' ', $values);
+        if ($modifier === 'label') {
+          $replacements[$original] = webform_filter_xss($display_element['#title']);
+        }
+        elseif ($modifier === 'key' && $display_element['#webform_component']['type'] === 'select') {
+          $values = array();
+          foreach ($display_element['#value'] as $value) {
+            $values[] = webform_filter_xss($value);
           }
-          else {
-            // Remove theme wrappers for the nolabel modifier.
-            if ($modifier === 'nolabel' || empty($modifier)) {
-              $display_element['#theme_wrappers'] = array();
-            }
-            $replacements[$original] = render($display_element);
+          $replacements[$original] = implode(' ', $values);
+        }
+        else {
+          // Remove theme wrappers for the nolabel modifier.
+          if ($modifier === 'nolabel' || empty($modifier)) {
+            $display_element['#theme_wrappers'] = array();
           }
-          // Continue processing tokens in case another modifier is used.
+          $replacements[$original] = render($display_element);
         }
+        // Continue processing tokens in case another modifier is used.
       }
-
     }
 
-    // Chained token relationships.
-    if ($date_tokens = token_find_with_prefix($tokens, 'date')) {
-      $replacements += token_generate('date', $date_tokens, array('date' => $submission->submitted), $options);
-    }
-    if ($submission->completed && ($date_tokens = token_find_with_prefix($tokens, 'completed_date'))) {
-      $replacements += token_generate('date', $date_tokens, array('date' => $submission->completed), $options);
-    }
-    if ($date_tokens = token_find_with_prefix($tokens, 'modified_date')) {
-      $replacements += token_generate('date', $date_tokens, array('date' => $submission->modified), $options);
-    }
-    if (($user_tokens = token_find_with_prefix($tokens, 'user')) && $account = user_load($submission->uid)) {
-      $replacements += token_generate('user', $user_tokens, array('user' => $account), $options);
+  }
+
+  // Chained token relationships.
+  if ($date_tokens = token_find_with_prefix($tokens, 'date')) {
+    $replacements += token_generate('date', $date_tokens, array('date' => $submission->submitted), $options);
+  }
+  if ($submission->completed && ($date_tokens = token_find_with_prefix($tokens, 'completed_date'))) {
+    $replacements += token_generate('date', $date_tokens, array('date' => $submission->completed), $options);
+  }
+  if ($date_tokens = token_find_with_prefix($tokens, 'modified_date')) {
+    $replacements += token_generate('date', $date_tokens, array('date' => $submission->modified), $options);
+  }
+  if (($user_tokens = token_find_with_prefix($tokens, 'user')) && $account = user_load($submission->uid)) {
+    $replacements += token_generate('user', $user_tokens, array('user' => $account), $options);
+  }
+  if ($submission->sid) {
+    if ($url_tokens = token_find_with_prefix($tokens, 'url')) {
+      $replacements += token_generate('url', $url_tokens, array('path' => "node/{$node->nid}/submission/{$submission->sid}"), $options);
     }
-    if ($submission->sid) {
-      if ($url_tokens = token_find_with_prefix($tokens, 'url')) {
-        $replacements += token_generate('url', $url_tokens, array('path' => "node/{$node->nid}/submission/{$submission->sid}"), $options);
-      }
-      if ($url_tokens = token_find_with_prefix($tokens, 'edit-url')) {
-        $replacements += token_generate('url', $url_tokens, array('path' => "node/{$node->nid}/submission/{$submission->sid}/edit"), $options);
-      }
+    if ($url_tokens = token_find_with_prefix($tokens, 'edit-url')) {
+      $replacements += token_generate('url', $url_tokens, array('path' => "node/{$node->nid}/submission/{$submission->sid}/edit"), $options);
     }
   }
 
+  $recursion_level--;
+
   return $replacements;
 }
diff --git a/profiles/wcm_base/modules/custom/ocio_landing_page/ocio_landing_page.module b/profiles/wcm_base/modules/custom/ocio_landing_page/ocio_landing_page.module
index 54838eef196b92fe0029ac6d92cdeb745f971c85..abcf93e3bd7ea5b65e819e0f25e2e3b5da28a5d3 100644
--- a/profiles/wcm_base/modules/custom/ocio_landing_page/ocio_landing_page.module
+++ b/profiles/wcm_base/modules/custom/ocio_landing_page/ocio_landing_page.module
@@ -6,6 +6,47 @@
 
 include_once 'ocio_landing_page.features.inc';
 
+/**
+ * Implements hook_permission().
+ */
+function ocio_landing_page_permission() {
+  $type_name = 'Landing Page';
+
+  return array(
+    'create landing page pane' => array(
+      'title' => t('Create %type_name panes', array('%type_name' => $type_name)),
+    ),
+    'delete landing page pane' => array(
+      'title' => t('Delete %type_name panes', array('%type_name' => $type_name)),
+    ),
+    'move landing page pane' => array(
+      'title' => t('Move %type_name panes', array('%type_name' => $type_name)),
+    ),
+  );
+}
+
+/**
+ * Implements template_preprocess_panels_ipe_pane_wrapper().
+ */
+function ocio_landing_page_preprocess_panels_ipe_pane_wrapper(&$vars) {
+  if (!user_access('delete landing page pane')) {
+    unset($vars['links']['delete']);
+  }
+
+  if (!user_access('move landing page pane')) {
+    $vars['pane']->locks = array('type' => 'immovable');
+  }
+}
+
+/**
+ * Implements template_preprocess_panels_ipe_add_pane_button().
+ */
+function ocio_landing_page_preprocess_panels_ipe_add_pane_button(&$vars) {
+  if (!user_access('create landing page pane')) {
+    unset($vars['links']['add-pane']);
+  }
+}
+
 /**
  * Implements hook_form_FORM_ID_alter().
  */
diff --git a/profiles/wcm_base/modules/custom/ocio_permissions/ocio_permissions.features.user_permission.inc b/profiles/wcm_base/modules/custom/ocio_permissions/ocio_permissions.features.user_permission.inc
index c37ed733d634ff7a0d9f79f5fd367b45e5ea209b..6066bc8c91ef17daf6145e952f77d76efcd2a5a6 100644
--- a/profiles/wcm_base/modules/custom/ocio_permissions/ocio_permissions.features.user_permission.inc
+++ b/profiles/wcm_base/modules/custom/ocio_permissions/ocio_permissions.features.user_permission.inc
@@ -469,6 +469,15 @@ function ocio_permissions_user_default_permissions() {
     'module' => 'conditional_fields',
   );
 
+  // Exported permission: 'administer facets'.
+  $permissions['administer facets'] = array(
+    'name' => 'administer facets',
+    'roles' => array(
+      'administrator' => 'administrator',
+    ),
+    'module' => 'facetapi',
+  );
+
   // Exported permission: 'administer features'.
   $permissions['administer features'] = array(
     'name' => 'administer features',
@@ -692,6 +701,7 @@ function ocio_permissions_user_default_permissions() {
     'name' => 'administer panelizer node ocio_landing_page content',
     'roles' => array(
       'administrator' => 'administrator',
+      'editor' => 'editor',
       'site builder' => 'site builder',
       'site manager' => 'site manager',
     ),
@@ -1384,6 +1394,16 @@ function ocio_permissions_user_default_permissions() {
     'module' => 'file_entity',
   );
 
+  // Exported permission: 'create landing page pane'.
+  $permissions['create landing page pane'] = array(
+    'name' => 'create landing page pane',
+    'roles' => array(
+      'administrator' => 'administrator',
+      'site builder' => 'site builder',
+    ),
+    'module' => 'ocio_landing_page',
+  );
+
   // Exported permission: 'create new books'.
   $permissions['create new books'] = array(
     'name' => 'create new books',
@@ -1712,6 +1732,16 @@ function ocio_permissions_user_default_permissions() {
     'module' => 'fieldable_panels_panes',
   );
 
+  // Exported permission: 'delete landing page pane'.
+  $permissions['delete landing page pane'] = array(
+    'name' => 'delete landing page pane',
+    'roles' => array(
+      'administrator' => 'administrator',
+      'site builder' => 'site builder',
+    ),
+    'module' => 'ocio_landing_page',
+  );
+
   // Exported permission: 'delete own article content'.
   $permissions['delete own article content'] = array(
     'name' => 'delete own article content',
@@ -2727,6 +2757,16 @@ function ocio_permissions_user_default_permissions() {
     'module' => 'ocio_omega_settings',
   );
 
+  // Exported permission: 'move landing page pane'.
+  $permissions['move landing page pane'] = array(
+    'name' => 'move landing page pane',
+    'roles' => array(
+      'administrator' => 'administrator',
+      'site builder' => 'site builder',
+    ),
+    'module' => 'ocio_landing_page',
+  );
+
   // Exported permission: 'notify of path changes'.
   $permissions['notify of path changes'] = array(
     'name' => 'notify of path changes',
@@ -3386,6 +3426,7 @@ function ocio_permissions_user_default_permissions() {
     'name' => 'use panels in place editing',
     'roles' => array(
       'administrator' => 'administrator',
+      'editor' => 'editor',
       'site builder' => 'site builder',
       'site manager' => 'site manager',
     ),
diff --git a/profiles/wcm_base/modules/custom/ocio_permissions/ocio_permissions.info b/profiles/wcm_base/modules/custom/ocio_permissions/ocio_permissions.info
index f93ab808f8390b0cc624c7f6dc1420ed22fa6b8f..963638de34df525f3080e39bff9177260fd1a0fa 100644
--- a/profiles/wcm_base/modules/custom/ocio_permissions/ocio_permissions.info
+++ b/profiles/wcm_base/modules/custom/ocio_permissions/ocio_permissions.info
@@ -18,6 +18,7 @@ dependencies[] = draggableviews
 dependencies[] = ds
 dependencies[] = ds_extras
 dependencies[] = ds_ui
+dependencies[] = facetapi
 dependencies[] = features
 dependencies[] = field_group
 dependencies[] = fieldable_panels_panes
@@ -38,6 +39,7 @@ dependencies[] = node
 dependencies[] = oauth_common
 dependencies[] = ocio_admin_menu
 dependencies[] = ocio_field_bases
+dependencies[] = ocio_landing_page
 dependencies[] = ocio_main_menu
 dependencies[] = ocio_omega_settings
 dependencies[] = ocio_siteinfo
@@ -116,6 +118,7 @@ features[user_permission][] = administer contexts
 features[user_permission][] = administer custom breadcrumbs
 features[user_permission][] = administer default config
 features[user_permission][] = administer dependencies
+features[user_permission][] = administer facets
 features[user_permission][] = administer features
 features[user_permission][] = administer fieldable panels panes
 features[user_permission][] = administer fieldgroups
@@ -211,6 +214,7 @@ features[user_permission][] = create fieldable tile_pane
 features[user_permission][] = create fieldable tile_pane_plus_text_area
 features[user_permission][] = create fieldable video
 features[user_permission][] = create files
+features[user_permission][] = create landing page pane
 features[user_permission][] = create new books
 features[user_permission][] = create ocio_landing_page content
 features[user_permission][] = create url aliases
@@ -240,6 +244,7 @@ features[user_permission][] = delete fieldable text
 features[user_permission][] = delete fieldable tile_pane
 features[user_permission][] = delete fieldable tile_pane_plus_text_area
 features[user_permission][] = delete fieldable video
+features[user_permission][] = delete landing page pane
 features[user_permission][] = delete own article content
 features[user_permission][] = delete own audio files
 features[user_permission][] = delete own basic_page content
@@ -331,6 +336,7 @@ features[user_permission][] = moderate content from needs_review to draft
 features[user_permission][] = moderate content from needs_review to published
 features[user_permission][] = moderate content from published to draft
 features[user_permission][] = modify ocio theme
+features[user_permission][] = move landing page pane
 features[user_permission][] = notify of path changes
 features[user_permission][] = oauth authorize any consumers
 features[user_permission][] = oauth register any consumers
diff --git a/profiles/wcm_base/modules/custom/ocio_search/ocio_search.apachesolr_environments.inc b/profiles/wcm_base/modules/custom/ocio_search/ocio_search.apachesolr_environments.inc
index fedfb72192c4dc4b5be09ef19ef88fb87cb1473e..3f1f6013cfa82c5e47ac929ec1fa9f26fd716309 100644
--- a/profiles/wcm_base/modules/custom/ocio_search/ocio_search.apachesolr_environments.inc
+++ b/profiles/wcm_base/modules/custom/ocio_search/ocio_search.apachesolr_environments.inc
@@ -33,10 +33,7 @@ function ocio_search_apachesolr_environments() {
       7 => 'web_form',
     ),
     'file' => array(
-      0 => 'audio',
-      1 => 'document',
-      2 => 'image',
-      3 => 'video',
+      0 => 'document',
     ),
   );
   $export['solr'] = $environment;
diff --git a/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.features.features_overrides.inc b/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.features.features_overrides.inc
new file mode 100644
index 0000000000000000000000000000000000000000..10abd89c5c1b957c4e73e3e69f05add8f5721bb9
--- /dev/null
+++ b/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.features.features_overrides.inc
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @file
+ * ocio_user_config.features.features_overrides.inc
+ */
+
+/**
+ * Implements hook_features_override_default_overrides().
+ */
+function ocio_user_config_features_override_default_overrides() {
+  // This code is only used for UI in features. Exported alters hooks do the magic.
+  $overrides = array();
+
+  // Exported overrides for: views_view
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|cancel_node"]["DELETED"] = TRUE;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::role_delegation_delegate_roles_action"] = array(
+    'selected' => 1,
+    'postpone_processing' => 0,
+    'skip_confirmation' => 0,
+    'override_label' => 0,
+    'label' => '',
+  );
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::system_block_ip_action"]["DELETED"] = TRUE;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::system_goto_action"]["DELETED"] = TRUE;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::system_message_action"]["DELETED"] = TRUE;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::user_block_user_action|selected"] = 1;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::user_block_user_action|skip_confirmation"] = 0;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_argument_selector_action"]["DELETED"] = TRUE;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_delete_item"]["DELETED"] = TRUE;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|_all_"]["DELETED"] = TRUE;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|status"] = 'status';
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_contact_group"] = 'user::field_contact_group';
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_display_in_leadership_list"] = 'user::field_display_in_leadership_list';
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_display_on_contact_page"] = 'user::field_display_on_contact_page';
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_job_title"] = 'user::field_job_title';
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_leadership_group"] = 'user::field_leadership_group';
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_phone"] = 'user::field_phone';
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_room_and_building"] = 'user::field_room_and_building';
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_street_address"] = 'user::field_street_address';
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_script_action"]["DELETED"] = TRUE;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_user_cancel_action"]["DELETED"] = TRUE;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_user_roles_action"]["DELETED"] = TRUE;
+  $overrides["views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_settings|row_clickable"] = 1;
+  $overrides["views_view.admin_views_user.display|default|display_options|query|options|query_tags"] = array(
+    0 => 'administerusersbyrole_edit_access',
+  );
+
+ return $overrides;
+}
diff --git a/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.features.inc b/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.features.inc
index 41504bf5a4313affe049927d8a476c92b5994df9..d38712012c7868eb406e9b1deb03c1cc25870dfd 100644
--- a/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.features.inc
+++ b/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.features.inc
@@ -15,3 +15,43 @@ function ocio_user_config_ctools_plugin_api($module = NULL, $api = NULL) {
     return array("version" => "1");
   }
 }
+
+/**
+ * Implements hook_views_default_views_alter().
+ */
+function ocio_user_config_views_default_views_alter(&$data) {
+  if (isset($data['admin_views_user'])) {
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::role_delegation_delegate_roles_action'] = array(
+      'selected' => 1,
+      'postpone_processing' => 0,
+      'skip_confirmation' => 0,
+      'override_label' => 0,
+      'label' => '',
+    ); /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::user_block_user_action']['selected'] = 1; /* WAS: 0 */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::user_block_user_action']['skip_confirmation'] = 0; /* WAS: 1 */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_modify_action']['settings']['display_values']['status'] = 'status'; /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_modify_action']['settings']['display_values']['user::field_contact_group'] = 'user::field_contact_group'; /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_modify_action']['settings']['display_values']['user::field_display_in_leadership_list'] = 'user::field_display_in_leadership_list'; /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_modify_action']['settings']['display_values']['user::field_display_on_contact_page'] = 'user::field_display_on_contact_page'; /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_modify_action']['settings']['display_values']['user::field_job_title'] = 'user::field_job_title'; /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_modify_action']['settings']['display_values']['user::field_leadership_group'] = 'user::field_leadership_group'; /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_modify_action']['settings']['display_values']['user::field_phone'] = 'user::field_phone'; /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_modify_action']['settings']['display_values']['user::field_room_and_building'] = 'user::field_room_and_building'; /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_modify_action']['settings']['display_values']['user::field_street_address'] = 'user::field_street_address'; /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_settings']['row_clickable'] = 1; /* WAS: '' */
+    $data['admin_views_user']->display['default']->display_options['query']['options']['query_tags'] = array(
+      0 => 'administerusersbyrole_edit_access',
+    ); /* WAS: '' */
+    unset($data['admin_views_user']->display['default']->display_options['fields']['cancel_node']);
+    unset($data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::system_block_ip_action']);
+    unset($data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::system_goto_action']);
+    unset($data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::system_message_action']);
+    unset($data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_argument_selector_action']);
+    unset($data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_delete_item']);
+    unset($data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_modify_action']['settings']['display_values']['_all_']);
+    unset($data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_script_action']);
+    unset($data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_user_cancel_action']);
+    unset($data['admin_views_user']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations']['action::views_bulk_operations_user_roles_action']);
+  }
+}
diff --git a/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.info b/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.info
index 3ff099c53e9b1cf5193a141d67902c7065d9322e..32cf3e7510cc6cfcde1b69d435b8726f8ca43301 100644
--- a/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.info
+++ b/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.info
@@ -15,6 +15,31 @@ features[ctools][] = ds:ds:1
 features[ctools][] = strongarm:strongarm:1
 features[ds_layout_settings][] = user|user|default
 features[features_api][] = api:2
+features[features_override_items][] = views_view.admin_views_user
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|cancel_node
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::role_delegation_delegate_roles_action
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::system_block_ip_action
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::system_goto_action
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::system_message_action
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::user_block_user_action|selected
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::user_block_user_action|skip_confirmation
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_argument_selector_action
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_delete_item
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|_all_
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|status
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_contact_group
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_display_in_leadership_list
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_display_on_contact_page
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_job_title
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_leadership_group
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_phone
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_room_and_building
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_modify_action|settings|display_values|user::field_street_address
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_script_action
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_user_cancel_action
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_operations|action::views_bulk_operations_user_roles_action
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|fields|views_bulk_operations|vbo_settings|row_clickable
+features[features_overrides][] = views_view.admin_views_user.display|default|display_options|query|options|query_tags
 features[user_permission][] = access user profiles
 features[user_permission][] = access users overview
 features[user_permission][] = administer all users
@@ -50,3 +75,4 @@ features[user_role][] = site builder
 features[user_role][] = site manager
 features[variable][] = views_defaults
 features_exclude[dependencies][ocio_user_config] = ocio_user_config
+features_exclude[dependencies][admin_views] = admin_views
diff --git a/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.strongarm.inc b/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.strongarm.inc
index 7be4b92a640ef8c0e7ff2fc781bf1bec8741962e..909b3fa9890f1bd1ce23cb19f1cf054dd41f4539 100644
--- a/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.strongarm.inc
+++ b/profiles/wcm_base/modules/custom/ocio_user_config/ocio_user_config.strongarm.inc
@@ -15,7 +15,7 @@ function ocio_user_config_strongarm() {
   $strongarm->api_version = 1;
   $strongarm->name = 'views_defaults';
   $strongarm->value = array(
-    'admin_views_user' => TRUE,
+    'admin_views_user' => FALSE,
     'workbench_files' => TRUE,
   );
   $export['views_defaults'] = $strongarm;
diff --git a/profiles/wcm_base/modules/custom/ocio_web_form/ocio_web_form.info b/profiles/wcm_base/modules/custom/ocio_web_form/ocio_web_form.info
index 185c1f1e1613a6b9f023e23ef69a1b731312c570..6cb2a77a1e195a6cf362e9a10ff61d89f033f601 100644
--- a/profiles/wcm_base/modules/custom/ocio_web_form/ocio_web_form.info
+++ b/profiles/wcm_base/modules/custom/ocio_web_form/ocio_web_form.info
@@ -28,6 +28,9 @@ features[variable][] = node_options_web_form
 features[variable][] = node_preview_web_form
 features[variable][] = node_submitted_web_form
 features[variable][] = private_web_form
+features[variable][] = webform_default_format
+features[variable][] = webform_email_address_individual
+features[variable][] = webform_email_html_capable
 features[variable][] = webform_node_web_form
 features[variable][] = workbench_moderation_default_state_web_form
 features_exclude[field_base][body] = body
diff --git a/profiles/wcm_base/modules/custom/ocio_web_form/ocio_web_form.strongarm.inc b/profiles/wcm_base/modules/custom/ocio_web_form/ocio_web_form.strongarm.inc
index 64cfb5349c870cbc7cb2961d638add0c12053630..fa263d96e96bfd892d780aaf145c59fcbdab417a 100644
--- a/profiles/wcm_base/modules/custom/ocio_web_form/ocio_web_form.strongarm.inc
+++ b/profiles/wcm_base/modules/custom/ocio_web_form/ocio_web_form.strongarm.inc
@@ -126,6 +126,27 @@ function ocio_web_form_strongarm() {
   $strongarm->value = '1';
   $export['private_web_form'] = $strongarm;
 
+  $strongarm = new stdClass();
+  $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
+  $strongarm->api_version = 1;
+  $strongarm->name = 'webform_default_format';
+  $strongarm->value = '1';
+  $export['webform_default_format'] = $strongarm;
+
+  $strongarm = new stdClass();
+  $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
+  $strongarm->api_version = 1;
+  $strongarm->name = 'webform_email_address_individual';
+  $strongarm->value = '0';
+  $export['webform_email_address_individual'] = $strongarm;
+
+  $strongarm = new stdClass();
+  $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
+  $strongarm->api_version = 1;
+  $strongarm->name = 'webform_email_html_capable';
+  $strongarm->value = 1;
+  $export['webform_email_html_capable'] = $strongarm;
+
   $strongarm = new stdClass();
   $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
   $strongarm->api_version = 1;
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 85d167abe1966beec02699be50f411322ea060ad..b208ae343c889818316dd67affd5be15b9b8111b 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
@@ -2268,6 +2268,7 @@ div.workbench-info-block #edit-submit {
 }
 .l-region--hero-wrapper .field--name-field-banner-image img {
   display: block;
+  width: 100%;
 }
 
 /* Styles for main menu */
@@ -3296,6 +3297,7 @@ a#skip:active:hover, a#skip:focus:hover {
 }
 .l-region--pre-footer .field--name-field-pre-footer-banner-image img {
   display: block;
+  width: 100%;
 }
 
 .front .view-featured-slideshow {
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 12b4e4efbbfde542612cd164301f4b27327bcab5..669f93cf5d36673b80c58b1c6f0e30916cbc63de 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
@@ -2310,6 +2310,7 @@ div.workbench-info-block #edit-submit {
 }
 .l-region--hero-wrapper .field--name-field-banner-image img {
   display: block;
+  width: 100%;
 }
 
 /* Styles for main menu */
@@ -3342,6 +3343,7 @@ a#skip:active:hover, a#skip:focus:hover {
 }
 .l-region--pre-footer .field--name-field-pre-footer-banner-image img {
   display: block;
+  width: 100%;
 }
 
 .front .view-featured-slideshow {
diff --git a/profiles/wcm_base/themes/ocio_omega_base/preprocess/page.preprocess.inc b/profiles/wcm_base/themes/ocio_omega_base/preprocess/page.preprocess.inc
index 059ac97fc620c4ed5ddac4f48dd09a8aec504d21..6da4135108ea52286d98e25482e783ea55a7497d 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/preprocess/page.preprocess.inc
+++ b/profiles/wcm_base/themes/ocio_omega_base/preprocess/page.preprocess.inc
@@ -25,18 +25,26 @@ function ocio_omega_base_preprocess_page(&$vars) {
     );
 
     $top_banner = field_view_field('node', $vars['node'], 'field_banner_image');
-    $top_banner_text = field_view_field('node', $vars['node'], 'field_banner_image_text');
+    if (!empty($top_banner)) {
+      $top_banner['#label_display'] = 'hidden';
+      $top_banner[0]['#item']['alt'] = "";
 
-    $top_banner['#label_display'] = 'hidden';
+      $vars['page']['hero']['top_banner']['#markup'] = drupal_render($top_banner);
 
-    $vars['page']['hero']['top_banner']['#markup'] = drupal_render($top_banner);
+      $top_banner_text = field_view_field('node', $vars['node'], 'field_banner_image_text');
+      if (!empty($top_banner_text) && !empty($vars['node']->field_banner_image_text_color) && !empty($vars['node']->field_banner_image_text_location)) {
+        $top_banner_text['#label_display'] = 'hidden';
 
-    if (!empty($vars['node']->field_banner_image_text_color) && !empty($vars['node']->field_banner_image_text_location)) {
-      $top_banner_text['#label_display'] = 'hidden';
-      $vars['page']['hero']['top_banner']['#markup'] .= drupal_render($top_banner_text);
+        $vars['page']['hero']['top_banner']['#markup'] .= drupal_render($top_banner_text);
+      }
     }
+
     $bottom_banner = field_view_field('node', $vars['node'], 'field_pre_footer_banner_image');
-    $bottom_banner['#label_display'] = 'hidden';
-    $vars['page']['pre_footer']['bottom_banner']['#markup'] = drupal_render($bottom_banner);
+    if (!empty($bottom_banner)) {
+      $bottom_banner['#label_display'] = 'hidden';
+      $bottom_banner[0]['#item']['alt'] = "";
+
+      $vars['page']['pre_footer']['bottom_banner']['#markup'] = drupal_render($bottom_banner);
+    }
   }
 }
diff --git a/profiles/wcm_base/themes/ocio_omega_base/sass/components/regions/_hero.scss b/profiles/wcm_base/themes/ocio_omega_base/sass/components/regions/_hero.scss
index 116cac16c917308537d6d55cb7adefbabca64b35..297a37e2f14201e004c71c90d83bc54d1731182f 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/sass/components/regions/_hero.scss
+++ b/profiles/wcm_base/themes/ocio_omega_base/sass/components/regions/_hero.scss
@@ -4,6 +4,7 @@
   .field--name-field-banner-image {
     img {
       display: block;
+      width: 100%;
     }
   }
 }
diff --git a/profiles/wcm_base/themes/ocio_omega_base/sass/components/regions/_pre-footer.scss b/profiles/wcm_base/themes/ocio_omega_base/sass/components/regions/_pre-footer.scss
index 0881b56aec9ee4dbf5156fcabd66e00aeb0ed262..6aca106223455f70a4e2f8ec77f116b62ff500e8 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/sass/components/regions/_pre-footer.scss
+++ b/profiles/wcm_base/themes/ocio_omega_base/sass/components/regions/_pre-footer.scss
@@ -1,3 +1,4 @@
 .l-region--pre-footer .field--name-field-pre-footer-banner-image img {
   display: block;
+  width: 100%;
 }
diff --git a/profiles/wcm_base/themes/ocio_omega_base/templates/regions/region--masthead.tpl.php b/profiles/wcm_base/themes/ocio_omega_base/templates/regions/region--masthead.tpl.php
index 8d83271acf02c489c8f66ba045cb7ac1c39f4550..a74c94c424688519162c33f9aaa074445a59f09d 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/templates/regions/region--masthead.tpl.php
+++ b/profiles/wcm_base/themes/ocio_omega_base/templates/regions/region--masthead.tpl.php
@@ -48,7 +48,7 @@
 			<?php endif; ?>
     </div><!--/site-name-->
     <div id="site-logo">
-      <a href="http://osu.edu" alt="The Ohio State University" target="_blank">
+      <a href="http://osu.edu" target="_blank">
         <img src="<?php print $logo; ?>" alt="">
       </a>
     </div><!--/site-logo-->
diff --git a/profiles/wcm_base/themes/ocio_omega_base/templates/system/html.tpl.php b/profiles/wcm_base/themes/ocio_omega_base/templates/system/html.tpl.php
index 4fa4378eeab4b765f825036b23ba83eb7e59e4be..7afed328278ca4cfed8f88463bf5c0fdb96979ee 100644
--- a/profiles/wcm_base/themes/ocio_omega_base/templates/system/html.tpl.php
+++ b/profiles/wcm_base/themes/ocio_omega_base/templates/system/html.tpl.php
@@ -28,7 +28,6 @@
     <?php print $scripts; ?>
   </head>
   <body<?php print $attributes;?>>
-    <a href="#main-content" class="element-invisible element-focusable"><?php print t('Skip to main content'); ?></a>
     <?php print $page_top; ?>
     <?php print $page; ?>
     <?php print $page_bottom; ?>
diff --git a/profiles/wcm_base/wcm_base.info b/profiles/wcm_base/wcm_base.info
index 1b051aaf25d82505634ee23cf2a53f41112c4958..b449fe5841907a3888f006a41605916db7e4a559 100644
--- a/profiles/wcm_base/wcm_base.info
+++ b/profiles/wcm_base/wcm_base.info
@@ -54,6 +54,8 @@ dependencies[] = ds_forms
 dependencies[] = ds_ui
 dependencies[] = flexslider
 dependencies[] = flexslider_views
+dependencies[] = mailsystem
+dependencies[] = mimemail
 dependencies[] = override_node_options
 dependencies[] = panels_accordion
 dependencies[] = private
diff --git a/profiles/wcm_base/wcm_base.make b/profiles/wcm_base/wcm_base.make
index a273645796d5bd7d2fa1966e837a0cb8da024d15..cdff2583260094354b6da8812e1a82acedc7b89d 100644
--- a/profiles/wcm_base/wcm_base.make
+++ b/profiles/wcm_base/wcm_base.make
@@ -51,6 +51,12 @@ projects[fieldable_panels_panes][subdir] = contrib
 projects[google_analytics][version] = 2.1
 projects[google_analytics][subdir] = contrib
 
+projects[mailsystem][version] = 2.34
+projects[mailsystem][subdir] = contrib
+
+projects[mimemail][version] = 1.0-beta4
+projects[mimemail][subdir] = contrib
+
 projects[media][version] = 2.0-beta1
 projects[media][subdir] = contrib
 projects[media][patch][2093435] = http://drupal.org/files/issues/media-js-dialog-issues-2093435-21.patch
@@ -99,7 +105,7 @@ projects[views_accordion][subdir] = contrib
 projects[views_bulk_operations][version] = 3.3
 projects[views_bulk_operations][subdir] = contrib
 
-projects[webform][version] = 4.8
+projects[webform][version] = 4.11
 projects[webform][subdir] = contrib