diff --git a/sites/all/modules/wf_required_fields/README.txt b/sites/all/modules/wf_required_fields/README.txt
index c448b7d..6d67767 100755
--- a/sites/all/modules/wf_required_fields/README.txt
+++ b/sites/all/modules/wf_required_fields/README.txt
@@ -9,15 +9,29 @@ Required fields are marked on the node edit form. Also transitions are objected
 The module was tested with the field types that come with the CCK module. It
 should also work with other CCK field types that use CCK for database storage.
 
+It also cooperates with conditional_fields, and works with the state transition
+buttons provided by workflow_extensions.
+(the workflow_extensions integration only works if the patch from
+http://drupal.org/node/1313490 is applied to the workflow_extensions module).
+
 Installation
 ------------
 
-1. Copy this whole folder to modules directory, as usual. Drupal should
-   automatically detect the module. Enable the module on the modules'
-   administration page.
+Copy this whole folder to modules directory, as usual. Drupal should
+automatically detect the module. Enable the module on the modules'
+administration page.
+
+Usage
+-----
+
+Go to admin/build/wf-required-fields to configure which content types to
+use, and which fields should be required fields in which workflow state.
 
-2. Go to admin/build/wf-required-fields to configure which content types to
-   use, and which fields should be required fields in which workflow state.
+The normal "Field Settings" required checkbox is mostly ignored.  However, a
+radios widget will draw with an N/A button if you don't set it to required in
+its Field Settings.  This may or may not be desired behavior.  If there is not
+an N/A button, then once a radio button is selected, it can never be
+unselected.
 
 Authors
 -------
diff --git a/sites/all/modules/wf_required_fields/wf_required_fields.inc b/sites/all/modules/wf_required_fields/wf_required_fields.inc
index 535be4f..51c87dd 100644
--- a/sites/all/modules/wf_required_fields/wf_required_fields.inc
+++ b/sites/all/modules/wf_required_fields/wf_required_fields.inc
@@ -55,56 +55,6 @@ function wf_required_fields_is_required($type, $field, $sid) {
 }
 
 /**
- * Finds the array that has a '#required' key inside a Forms API array that has
- * $field as distant parent.
- *
- * @param array $array The Forms API array
- * @param string $field
- * @return array The array that has a '#required' key as distant parent; null
- *  if none found
- */
-function &wf_required_fields_find_required(&$array, $field) {
-  if (! is_array($array)) {
-    return null;
-  }
-  if (array_key_exists($field, $array)) {
-    return wf_required_fields_get_if_recursive_subkey($array[$field], '#required');
-  }
-  foreach (array_keys($array) as $key) {
-    $child =& wf_required_fields_find_required($array[$key], $field);
-    if ($child !== null) {
-      return $child;
-    }
-  }
-  return null;
-}
-
-/**
- * Looks for a $key in a given &$array recursively.
- *
- * @param array $array The array to search
- * @param string $key The key
- * @return array The array that has the $key; null if none found
- */
-function &wf_required_fields_get_if_recursive_subkey(&$array, $key) {
-  if (! is_array($array)) {
-    return null;
-  }
-  if (array_key_exists($key, $array)) {
-    return $array;
-  }
-  foreach (array_keys($array) as $i) {
-    if (is_array($array[$i])) {
-      $child =& wf_required_fields_get_if_recursive_subkey($array[$i], $key);
-      if ($child !== null) {
-        return $child;
-      }
-    }
-  }
-  return null;
-}
-
-/**
  * Check which fields are not filled out properly for the specified node to be
  * promoted to the specified state.
  *
@@ -125,11 +75,44 @@ function wf_required_fields_get_missing_fields($node, $sid) {
       $fields[$key] = $value;
     }
   }
+
+  // We only want to declare the fields missing if conditional fields also
+  // thinks they should be shown (that is, if conditional fields is present).
+  // So we will let conditional fields tell us which fields are untriggered.
+  // It will set #access == FALSE on untriggered fields.
+  if (function_exists('conditional_fields_nodeapi')) {
+    // We actually only want it to operate on a copy of the node object.  No
+    // need to change the real thing.
+    $node_copy = clone $node;
+    module_invoke_all('nodeapi', $node_copy, 'view', false, false);
+  } else {
+    $node_copy = null;
+  }
+
   foreach (array_keys($fields) as $field_name) {
     $info = content_database_info($fields[$field_name]);
     foreach (array_keys($info['columns']) as $column) {
       $field = $node->$field_name;
-      if (wf_required_fields_is_required($type, $field_name, $sid)) {
+      
+      // If conditional fields is not present, consider the field triggered.
+      // If it is present, consider it triggered only if conditional fields
+      // considers it triggered.
+      // If it's not triggered, we needn't require it.
+      $cond_fields_triggered = true;
+      if (!is_null($node_copy)) {
+        $controlled_group = conditional_fields_get_group($node_copy->type, $field_name);
+        if ($controlled_group) {
+          if ($node_copy->content[$controlled_group]['group'][$field_name]['#access'] === false) {
+            $cond_fields_triggered = false;
+          }
+        } else if ($node_copy->content[$field_name]['#access'] === false) {
+          $cond_fields_triggered = false;
+        }
+      }
+
+      if (wf_required_fields_is_required($type, $field_name, $sid) 
+          && $cond_fields_triggered) 
+      {
         $first_field_element = array_shift($field);
         $value = $first_field_element[$column];
         if (!in_array($value, $non_empty, true) && empty($value)) {
@@ -174,4 +157,25 @@ function wf_required_fields_set_required(&$element) {
     case 'radios':
         unset ($element['#options']['']);
   }
-}
\ No newline at end of file
+}
+
+/**
+ * We want to know what is the default state that we will go to if we don't
+ * change the workflow state.  Find it.
+ */
+function _wf_required_fields_find_workflow_default(&$form) {
+  if ($form['#type'] == 'radios' && isset($form['#default_value'])) {
+    return $form['#default_value'];
+  } else {
+    foreach ($form as $key => $elements) {
+      if ($key != 'workflow_scheduled' && is_array($form[$key])) {
+        $ret_val = _wf_required_fields_find_workflow_default($form[$key]);
+        if (!is_null($ret_val)) {
+          return $ret_val;
+        }
+      }
+    }
+  }
+
+  return null;
+}
diff --git a/sites/all/modules/wf_required_fields/wf_required_fields.module b/sites/all/modules/wf_required_fields/wf_required_fields.module
index 34ec66e..f6648c0 100644
--- a/sites/all/modules/wf_required_fields/wf_required_fields.module
+++ b/sites/all/modules/wf_required_fields/wf_required_fields.module
@@ -5,6 +5,17 @@
 module_load_include('inc', 'wf_required_fields', 'wf_required_fields');
 
 /**
+ * Implementation of hook_theme().
+ */
+function wf_required_fields_theme() {
+    return array(
+        'wf_required_fields_form_item' => array(
+            'arguments' => array(),
+        ),
+    );
+}
+
+/**
  * Implementation of hook_menu().
  * 
  * Adds the callback for the configuration page.
@@ -28,7 +39,7 @@ function wf_required_fields_menu() {
 /**
  * Implementation of hook_form_alter().
  * 
- * Sets the '#required' property of configured fields in node edit forms. 
+ * Sets up an #after_build function, if we are slated to operate on this content type. 
  * 
  * @param string $form_id The form id
  * @param array &$form Forms API array of the form
@@ -44,24 +55,240 @@ function wf_required_fields_form_alter(&$form, &$form_state, $form_id) {
   if (isset($types[$type])) {  
     $form['#after_build'][] = '_wf_required_fields_after_build';
   }
-  
 }
 
-
 /**
-* Custom after_build callback handler.
-*/
+ * An after_build function that sets up our validation function.
+ * We will change the fields so that they are not required, in the traditional
+ * form.inc sense.  Instead, we will use a custom validator that only checks
+ * requiredness if the field is configured to be required for the workflow
+ * state we are transitioning to.
+ */
 function _wf_required_fields_after_build($form, &$form_state) {
-  $sid = workflow_node_current_state($form['#node']);
   $type = $form['#node']->type;
+  $types = wf_required_fields_get_types_configured();
+
+  array_unshift($form['#validate'], '_wf_required_fields_check_required');
+
+  // The workflow_extensions module creates a separate submit button for each
+  // workflow state and sets the button's #to_state.  We are particularly
+  // interested in the state associated with the default "Submit" button.
+  // If that module is not present, we must find the regular radio button that
+  // the workflow module puts there, in order to determine the default state.
+  // The reason we want the default state is so that we can draw the fields
+  // with the requiredness that they would have if you didn't change workflow
+  // state.
+  if (isset($form['buttons']['submit']['#to_state'])) {
+    $sid = $form['buttons']['submit']['#to_state'];
+  } else {
+    $sid = _wf_required_fields_find_workflow_default($form['workflow']);
+  }
   $info = content_types($type);
   $fields_available = $info['fields'];
-  
+
+  // Required fields should only be required when moving to the right states.
+  // Since required fields validation is hardcoded in _form_validate,
+  // we need to unset the #required property and perform a custom validation.
   foreach (array_keys($fields_available) as $field) {
-    if (wf_required_fields_is_required($type, $field, $sid)) {
-      $array =& wf_required_fields_find_required($form, $field);
-      if ($array !== null) {
-        wf_required_fields_set_required($array);
+    $in_group = fieldgroup_get_group($type, $field);
+    if ($in_group) {
+      wf_required_fields_custom_required_field($form[$in_group][$field]);
+      if (wf_required_fields_is_required($type, $field, $sid)) {
+        wf_required_fields_item_apply_theme($form[$in_group][$field]);
+      }
+    }
+    else {
+      wf_required_fields_custom_required_field($form[$field]);
+      if (wf_required_fields_is_required($type, $field, $sid)) {
+        wf_required_fields_item_apply_theme($form[$field]);
+      }
+    }
+  }
+
+  // If conditional fields is present, then we want to require the field only
+  // if BOTH conditional_fields and wf_required_fields agree that it's
+  // required.  We don't want conditional fields going rogue and setting errors
+  // on its own, so we will trap it and run it on our own terms.
+  if ($index = array_search('conditional_fields_node_editing_form_validate', $form['#validate'])) {
+    $form['#wf_required_fields_additional_validate'] = array('conditional_fields_node_editing_form_validate');
+    array_splice($form['#validate'], $index, 1);
+  }
+  $form['#validate'] = array_merge(array('wf_required_fields_fields_validate'), (array)$form['#validate']);
+
+  return $form;
+}
+
+/**
+ * Unset the #required property and set a #wf_required_fields_required property for custom validation.
+ */
+function wf_required_fields_custom_required_field(&$field) {
+  if ((isset($field['#required']) && $field['#required'])
+      || (isset($field['#conditional_fields_required']) && $field['#conditional_fields_required']))
+  {
+    unset($field['#required']);
+  }
+  $field['#wf_required_fields_required'] = TRUE;
+
+  // Required radio buttons need custom validation, otherwise _form_validate
+  // will think that an invalid choice is selected when the field is submitted
+  // with no value.
+  if ($field['#type'] == 'radios' && isset($field['#needs_validation']) && $field['#needs_validation']) {
+    unset($field['#needs_validation']);
+    $field['#element_validate'] = array_merge(array('wf_required_fields_required_radios_validate'), (array) $field['#validate']);
+  }
+
+  foreach (element_children($field) as $child) {
+    wf_required_fields_custom_required_field($field[$child]);
+  }
+}
+
+/**
+ * Custom validation for radio buttons.
+ * Reproduces the behavior of _form_validate, while adding an empty option.
+ */
+function wf_required_fields_required_radios_validate($elements) {
+  $elements['#options'][''] = t('N/A');
+
+  if (isset($elements['#options']) && isset($elements['#value'])) {
+    if (is_array($elements['#value'])) {
+      foreach ($elements['#value'] as $v) {
+        if (!isset($elements['#options'][$v])) {
+          form_error($elements, t('An illegal choice has been detected. Please contact the site administrator.'));
+          watchdog('form', 'Illegal choice %choice in !name element.', array('%choice' => $v, '!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']), WATCHDOG_ERROR);
+        }
+      }
+    }
+    elseif (!isset($elements['#options'][$elements['#value']])) {
+      form_error($elements, t('An illegal choice has been detected. Please contact the site administrator.'));
+      watchdog('form', 'Illegal choice %choice in %name element.', array('%choice' => $elements['#value'], '%name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']), WATCHDOG_ERROR);
+    }
+  }
+}
+
+/**
+ * Insert appropriate themeing functions.
+ */
+function wf_required_fields_item_apply_theme(&$element, $group_name = '') {
+  // Save a previously set function so it can be called before rendering the field
+  if (!empty($element['#theme']) && $element['#theme'] != 'wf_required_fields_form_item') {
+    $element['#wf_required_fields_theme'] = $element['#theme'];
+  }
+  $element['#theme'] = 'wf_required_fields_form_item';
+}
+
+/**
+ * Prepares conditional fields for rendering and handles
+ * special cases.
+ */
+function theme_wf_required_fields_form_item($item) {
+  if (!empty($item['#wf_required_fields_required'])) {
+    $item = wf_required_fields_set_required_field($item);
+  }
+
+  if (!empty($item['#wf_required_fields_theme'])) {
+    $rendered_item = theme($item['#wf_required_fields_theme'], $item);
+  }
+  else {
+    $rendered_item = drupal_render($item);
+  }
+
+  return $rendered_item;
+}
+
+/**
+ * Wrapper for wf_required_fields_set_required_field_recurse
+ */
+function wf_required_fields_set_required_field($item) {
+  wf_required_fields_set_required_field_recurse($item);
+  return $item;
+};
+
+/**
+ * Recursive function to set required for all conditionally required fields.
+ * This causes Drupal to render conditionally required fields in a way that
+ * indicates they are required when visible.
+ */
+function wf_required_fields_set_required_field_recurse(&$item) {
+  $item['#required'] = TRUE;
+  foreach (element_children($item) as $child) {
+    wf_required_fields_set_required_field_recurse($item[$child]);
+  }
+}
+
+/**
+ * Check the required fields, as part of form validation.
+ */
+function _wf_required_fields_check_required(&$form, &$form_state) {
+  if (isset($form_state['clicked_button']['#to_state'])) {
+    $sid = $form_state['clicked_button']['#to_state'];
+  } else {
+    $sid = $form_state['values']['workflow'];
+  }
+  $type = $form['#node']->type;
+  $info = content_types($type);
+  $fields_available = $info['fields'];
+
+  // Okay, we will run the conditional fields validator first, if it exists.
+  // We will see which things it called errors on.  We will let it mess with
+  // $form and $form_state, but we will remove all the errors it gives, and
+  // just use them to check with our ideas later.
+  if ($form['#wf_required_fields_additional_validate']) {
+    // Clear the form errors.
+    $known_errors = form_get_errors();
+    $known_messages = drupal_get_messages('error', true);
+    form_set_error(null, null, true);
+
+    // Run conditional fields's validator in a safe environment.
+    $args = array();
+    $args[0] =& $form;
+    $args[1] =& $form_state;
+    foreach ($form['#wf_required_fields_additional_validate'] as $fn) {
+      call_user_func_array($fn, $args);
+    }
+
+    // Remove anything that conditional fields put there.
+    $conditional_fields_errors = form_get_errors();
+    form_set_error(null, null, true);
+    drupal_get_messages('error', true);
+
+    // Replace the messages.
+    foreach ((array)$known_messages['error'] as $msg) {
+      drupal_set_message($msg, 'error');
+    }
+
+    foreach ((array)$known_errors as $name => $message) {
+      form_set_error($name, $message);
+    }
+  }
+
+  foreach (array_keys($fields_available) as $field) {
+    $field_info = $form['#field_info'][$field];
+    $in_group = fieldgroup_get_group($type, $field);
+
+    if ($in_group) {
+      $formfield =& $form[$in_group][$field];
+    } else {
+      $formfield =& $form[$field];
+    }
+
+    $empty_func = $field_info['module']."_content_is_empty";
+
+    if (wf_required_fields_is_required($type, $field, $sid) 
+        && call_user_func($empty_func, $form_state['values'][$field][0], $field_info)) 
+    {
+      // We think that the field is required, but does conditional fields
+      // agree?  If conditional fields is not present, then we will go ahead
+      // and require this.  If it is present, it must agree that the field is
+      // required.
+      if ($in_group) {
+        $conditional_fields_attention = $form[$in_group][$field]['#conditional_fields_required'];
+      } else {
+        $conditional_fields_attention = $form[$field]['#conditional_fields_required'];
+      }
+      $conditional_fields_required = (!$conditional_fields_attention) || $conditional_fields_errors[$field];
+
+      if ($conditional_fields_required) {
+        form_set_error($field, t('!name field is required.', array('!name' => $formfield['#title'])));
       }
     }
   }
@@ -112,7 +339,7 @@ function wf_required_fields_settings_form() {
     $form['wf_required_fields']['settings'][$type] = array(
       '#type' => 'fieldset',
       '#title' => $types_applicable[$type],
-      '#description' => t('For each state, select the fields that you want to make a required field.'),
+      '#description' => t('For each state, select the fields that you want to make a required field.  The setting of "required" in the Field Settings will be ignored for the most part.  However, if a field uses a radio buttons widget, and is marked as Not Required globally, then it will not have an N/A option, so once it is set, it can never be unset.'),
       '#collapsible' => true,
       '#collapsed' => false,
     );
@@ -133,7 +360,7 @@ function wf_required_fields_settings_form() {
     foreach ($info['fields'] as $field => $field_info) {
       $form['wf_required_fields']['settings'][$type]['table'][$field] = array(
         '#prefix' => '<tr class="' . (($row = 1 - $row) ? 'even' : 'odd'). '">',
-        '#value' => '<td>' . $field_info['widget']['label'] . ($field_info['required'] ? '<br><em>' . t('Already marked required in its !link', array('!link' => l('global settings', "admin/content/node-type/$type/fields/". $field_info['field_name']))) : ''),
+        '#value' => '<td>' . $field_info['widget']['label'] . ($field_info['required'] ? '<br><em>' . t('Marked required in its !link', array('!link' => l('global settings', "admin/content/node-type/$type/fields/". $field_info['field_name']))) : '') . '</td>',
         '#suffix' => '</tr>',
       );
       foreach ($states as $sid => $sname) {
@@ -143,7 +370,6 @@ function wf_required_fields_settings_form() {
           '#type' => 'checkbox',
           '#title' => '',
           '#default_value' => wf_required_fields_is_required($type, $field, $sid),
-          '#disabled' => $field_info['required'],
         );
       }      
     }
diff --git a/sites/all/modules/workflow_extensions/workflow_extensions.module b/sites/all/modules/workflow_extensions/workflow_extensions.module
index 003f34e..c958a55 100755
--- a/sites/all/modules/workflow_extensions/workflow_extensions.module
+++ b/sites/all/modules/workflow_extensions/workflow_extensions.module
@@ -321,21 +321,36 @@ function _workflow_extensions_replace_with_buttons(&$form, $workflow_name) {
   $states = $form['workflow'][$workflow_name]['#options'];
   $submit_handlers = _workflow_extensions_assign_handlers($form);
   foreach ($states as $sid => $to_state_name) {
+    // Create button for transition from current_sid to destination state.
     if ($sid != $current_sid) {
-      // Create button for transition from current_sid to destination state.
       $button = array();
       $button['#value'] = workflow_extensions_get_transition_label($form['#wf']->wid, $current_state_name, workflow_get_state_name($sid), $node);
-      $button['#type'] = 'submit';
-      $button['#to_state'] = $sid;
-      if (isset($form['buttons']['submit']['#weight'])) { // node form
-        $button['#weight'] = $form['buttons']['submit']['#weight'] + 1;
-      }
-      elseif (isset($form['submit']['#weight'])) { // comment form
-        $button['#weight'] = $form['submit']['#weight'];
-      }
-      $button['#submit'] = $submit_handlers;
+    }
+    else {
+      // Reuse the submit button, to stay in this state.
+      if (empty($form['buttons']['submit'])) {
+        // If there was no submit button, we were probably on the workflow
+        // transition page and not the node edit page.
+        continue;
+      }
+      $button = $form['buttons']['submit'];
+    }
+    $button['#type'] = 'submit';
+    $button['#to_state'] = $sid;
+    if (isset($form['buttons']['submit']['#weight'])) { // node form
+      $button['#weight'] = $form['buttons']['submit']['#weight'] + 1;
+    }
+    elseif (isset($form['submit']['#weight'])) { // comment form
+      $button['#weight'] = $form['submit']['#weight'];
+    }
+    $button['#submit'] = $submit_handlers;
+
+    if ($sid != $current_sid) {
       $form['buttons']["submit_to_$to_state_name"] = $button;
     }
+    else {
+      $form['buttons']["submit"] = $button;
+    }
   }
   // Get rid of workflow radio buttons that live inside the fieldset
   unset($form['workflow'][$workflow_name]);
