diff --git a/commons_groups.features.field_instance.inc b/commons_groups.features.field_instance.inc
index b821802..36dda8c 100644
--- a/commons_groups.features.field_instance.inc
+++ b/commons_groups.features.field_instance.inc
@@ -385,6 +385,8 @@ function commons_groups_field_default_field_instances() {
   t('Group');
   t('Group membership');
   t('Group visibility');
+  t('Group content visibility');
+  t('Group roles and permissions');
   t('Request message');
   t('This is the text a user may send to the group administrators.');
   t('Group Logo');
diff --git a/commons_groups.info b/commons_groups.info
index 2d43154..e731c2f 100644
--- a/commons_groups.info
+++ b/commons_groups.info
@@ -24,13 +24,16 @@ features[features_api][] = api:1
 features[field_base][] = group_access
 features[field_base][] = group_content_access
 features[field_base][] = group_group
+features[field_base][] = og_roles_permissions
 features[field_base][] = og_group_ref
 features[field_base][] = og_membership_request
 features[field_base][] = og_user_group_ref
 features[field_base][] = field_group_logo
 features[field_instance][] = node-group-field_group_logo
 features[field_instance][] = node-group-body
+features[field_instance][] = node-group-group_access
 features[field_instance][] = node-group-group_group
+features[field_instance][] = node-group-og_roles_permissions
 features[field_instance][] = node-group-field_topics
 features[field_instance][] = og_membership-og_membership_type_default-og_membership_request
 features[image][] = 35x35
diff --git a/commons_groups.module b/commons_groups.module
index 74482dd..570db6d 100644
--- a/commons_groups.module
+++ b/commons_groups.module
@@ -39,12 +39,6 @@ function commons_groups_entity_view($entity, $type, $view_mode, $langcode) {
  * Alter the privacy settings fields.
  */
 function commons_groups_form_group_node_form_alter(&$form, &$form_state) {
-  if (!module_exists('og_access')) {
-    $form['field_og_subscribe_settings']['#access'] = FALSE;
-    $form['field_og_access_default_value']['#access'] = FALSE;
-    return;
-  }
-
   // Wrap the privacy fields with a fieldset.
   $form['privacy_settings'] = array(
     '#type' => 'fieldset',
@@ -52,31 +46,30 @@ function commons_groups_form_group_node_form_alter(&$form, &$form_state) {
     '#weight' => 20,
   );
   $form['privacy_settings']['field_og_subscribe_settings'] = $form['field_og_subscribe_settings'];
-  $form['privacy_settings']['field_og_access_default_value'] = $form['field_og_access_default_value'];
-  unset($form['field_og_subscribe_settings'], $form['field_og_access_default_value']);
+  unset($form['field_og_subscribe_settings']);
 
   // Hide the settings label.
   $form['privacy_settings']['field_og_subscribe_settings'][LANGUAGE_NONE]['#title'] = '';
   $form['privacy_settings']['field_og_subscribe_settings'][LANGUAGE_NONE]['#required'] = FALSE;
 
-  // Display the private content checkbox only when "Joining requires approval"
-  // is selected.
-  $form['privacy_settings']['field_og_access_default_value']['#states'] = array(
-    'visible' => array(
-      ':input[name="field_og_subscribe_settings[' . LANGUAGE_NONE . ']"]' => array('value' => 'approval'),
-    ),
-  );
+  if (module_exists('og_access')) {
+    $form['privacy_settings']['field_og_access_default_value'] = $form['field_og_access_default_value'];
+    unset($form['field_og_access_default_value']);
+
+    // Display the private content checkbox only when "Joining requires approval"
+    // is selected.
+    $form['privacy_settings']['field_og_access_default_value']['#states'] = array(
+      'visible' => array(
+        ':input[name="field_og_subscribe_settings[' . LANGUAGE_NONE . ']"]' => array('value' => 'approval'),
+      ),
+    );
+
+    $form['#after_build'] = array('commons_groups_form_group_node_after_build');
+  }
 
-  $form['#after_build'] = array('commons_groups_form_group_node_after_build');
   $form['#attached']['css'] = array(
     drupal_get_path('module', 'commons_groups') . '/css/commons_groups.css',
   );
-
-  // Block the subscription field when editing an existing group since there's
-  // currently no hook for changing the actual permissions.
-  if ($form['nid']['#value']) {
-    $form['privacy_settings']['field_og_subscribe_settings']['#disabled'] = TRUE;
-  }
 }
 
 /**
@@ -91,6 +84,69 @@ function commons_groups_form_group_node_after_build($form, $form_state) {
 }
 
 /**
+ * Implements hook_og_role_revoke_permissions().
+ *
+ * Update the subscription settings field on a group when the relevant
+ * permissions are changed.
+ */
+function commons_groups_og_role_revoke_permissions($role, $permissions) {
+  if (!$role->gid || $role->name != 'non-member') {
+    return;
+  }
+
+  // Get all non members permissions.
+  $permissions = og_role_permissions(array($role->rid => $role->name));
+  // If there are no such permissions send an empty array.
+  _commons_groups_update_group_permissions($role->group_type, $role->gid, !empty($permissions[$role->rid]) ? $permissions[$role->rid] : array());
+}
+
+/**
+ * Implements hook_og_role_revoke_permissions().
+ *
+ * Update the subscription settings field on a group when the relevant
+ * permissions are changed.
+ */
+function commons_groups_og_role_grant_permissions($role, $permissions) {
+  if (!$role->gid || $role->name != 'non-member') {
+    return;
+  }
+
+  // Get all non members permissions.
+  $permissions = og_role_permissions(array($role->rid => $role->name));
+  if (!empty($permissions[$role->rid])) {
+    _commons_groups_update_group_permissions($role->group_type, $role->gid, $permissions[$role->rid]);
+  }
+}
+
+/**
+ * Update the group permission field.
+ *
+ * @param $group_type
+ *   The entity type of the group of which the permissions are being changed.
+ * @param $group_id
+ *   The entity ID of the group of which the permissions are being changed.
+ * @param $permissions
+ *   The anonymous user permissions of the group.
+ */
+function _commons_groups_update_group_permissions($group_type, $group_id, $permissions) {
+  if (!empty($permissions['subscribe without approval'])) {
+    $subscribe_type = 'anyone';
+  }
+  elseif (!empty($permissions['subscribe'])) {
+    $subscribe_type = 'approval';
+  }
+  else {
+    $subscribe_type = 'invitation';
+  }
+
+  $wrapper = entity_metadata_wrapper($group_type, $group_id);
+  if ($wrapper->field_og_subscribe_settings->value() != $subscribe_type) {
+    $wrapper->field_og_subscribe_settings->set($subscribe_type);
+    $wrapper->save();
+  }
+}
+
+/**
  * Implements hook_menu_alter().
  */
 function commons_groups_menu_alter(&$items) {
@@ -283,8 +339,8 @@ function commons_groups_system_info_alter(&$info, $file, $type) {
       foreach ($group_content_entity_types as $entity_type => $bundles) {
         foreach(array_keys($bundles) as $bundle) {
           $info['features']['field_instance'][] = "$entity_type-$bundle-og_group_ref";
+          $info['features']['field_instance'][] = "$entity_type-$bundle-field_og_subscribe_settings";
           if (module_exists('og_access')) {
-            $info['features']['field_instance'][] = "$entity_type-$bundle-field_og_subscribe_settings";
             $info['features']['field_instance'][] = "$entity_type-$bundle-field_og_access_default_value";
             $info['features']['field_instance'][] = "$entity_type-$bundle-group-group_access";
           }
@@ -592,7 +648,7 @@ function commons_groups_node_insert($node) {
 }
 
 /**
- * Set the group's permnissions according to field_og_subscribe_settings.
+ * Set the group's permissions according to field_og_subscribe_settings.
  *
  * @param $node
  *   A group node.
@@ -600,7 +656,7 @@ function commons_groups_node_insert($node) {
 function commons_groups_set_group_permissions($node) {
   $wrapper = entity_metadata_wrapper('node', $node);
   $permission = $wrapper->field_og_subscribe_settings->value();
-  $og_roles = og_roles('node', $node->type);
+  $og_roles = og_roles('node', $node->type, $node->nid);
   $anon_rid = array_search(OG_ANONYMOUS_ROLE, $og_roles);
 
   $permissions = array(
diff --git a/css/commons_groups.css b/css/commons_groups.css
new file mode 100644
index 0000000..db04154
--- /dev/null
+++ b/css/commons_groups.css
@@ -0,0 +1 @@
+#edit-field-og-access-default-value { margin-left: 20px; }
diff --git a/modules/commons_group_privacy/commons_group_privacy.features.field_base.inc b/modules/commons_group_privacy/commons_group_privacy.features.field_base.inc
deleted file mode 100644
index 99cd47c..0000000
--- a/modules/commons_group_privacy/commons_group_privacy.features.field_base.inc
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-/**
- * @file
- * commons_group_privacy.features.field_base.inc
- */
-
-/**
- * Implements hook_field_default_field_bases().
- */
-function commons_group_privacy_field_default_field_bases() {
-  $field_bases = array();
-
-  // Exported field_base: 'group_access'
-  $field_bases['group_access'] = array(
-    'active' => '1',
-    'cardinality' => '1',
-    'deleted' => '0',
-    'entity_types' => array(),
-    'field_name' => 'group_access',
-    'foreign keys' => array(),
-    'indexes' => array(
-      'value' => array(
-        0 => 'value',
-      ),
-    ),
-    'locked' => '0',
-    'module' => 'list',
-    'no_ui' => TRUE,
-    'settings' => array(
-      'allowed_values' => array(
-        0 => 'Public - accessible to all site users',
-        1 => 'Private - accessible only to group members',
-      ),
-      'allowed_values_function' => '',
-    ),
-    'translatable' => '0',
-    'type' => 'list_boolean',
-  );
-
-  // Exported field_base: 'group_content_access'
-  $field_bases['group_content_access'] = array(
-    'active' => '1',
-    'cardinality' => '1',
-    'deleted' => '0',
-    'entity_types' => array(),
-    'field_name' => 'group_content_access',
-    'foreign keys' => array(),
-    'indexes' => array(
-      'value' => array(
-        0 => 'value',
-      ),
-    ),
-    'locked' => '0',
-    'module' => 'list',
-    'no_ui' => TRUE,
-    'settings' => array(
-      'allowed_values' => array(
-        0 => 'Use group defaults',
-        1 => 'Public - accessible to all site users',
-        2 => 'Private - accessible only to group members',
-      ),
-      'allowed_values_function' => '',
-    ),
-    'translatable' => '0',
-    'type' => 'list_integer',
-  );
-
-  // Exported field_base: 'og_roles_permissions'
-  $field_bases['og_roles_permissions'] = array(
-    'active' => '1',
-    'cardinality' => '1',
-    'deleted' => '0',
-    'entity_types' => array(),
-    'field_name' => 'og_roles_permissions',
-    'foreign keys' => array(),
-    'indexes' => array(
-      'value' => array(
-        0 => 'value',
-      ),
-    ),
-    'locked' => '0',
-    'module' => 'list',
-    'settings' => array(
-      'allowed_values' => array(
-        0 => 'Use default roles and permissions',
-        1 => 'Override default roles and permissions',
-      ),
-      'allowed_values_function' => '',
-    ),
-    'translatable' => '0',
-    'type' => 'list_boolean',
-  );
-
-  return $field_bases;
-}
diff --git a/modules/commons_group_privacy/commons_group_privacy.features.field_instance.inc b/modules/commons_group_privacy/commons_group_privacy.features.field_instance.inc
deleted file mode 100644
index 6ff12af..0000000
--- a/modules/commons_group_privacy/commons_group_privacy.features.field_instance.inc
+++ /dev/null
@@ -1,186 +0,0 @@
-<?php
-/**
- * @file
- * commons_group_privacy.features.field_instance.inc
- */
-
-/**
- * Implements hook_field_default_field_instances().
- */
-function commons_group_privacy_field_default_field_instances() {
-  $field_instances = array();
-   // Get a list of content types that should have the og_groups_ref field added.
-  // Modules can alter this list by implementing hook_strongarm_alter().
-  $commons_groups_entity_types = commons_groups_get_group_content_entity_types();
-  if (!empty($commons_groups_entity_types)) {
-    foreach ($commons_groups_entity_types as $entity_type => $bundles) {
-      foreach(array_keys($bundles) as $bundle) {
-        commons_group_privacy_field_definition($field_instances, $entity_type, $bundle);
-      }
-    }
-  }
-
-  // Exported field_instance: 'node-group-group_access'
-  $field_instances['node-group-group_access'] = array(
-    'bundle' => 'group',
-    'default_value' => array(
-      0 => array(
-        'value' => 0,
-      ),
-    ),
-    'deleted' => '0',
-    'description' => '',
-    'display' => array(
-      'default' => array(
-        'label' => 'above',
-        'module' => 'list',
-        'settings' => array(),
-        'type' => 'list_default',
-        'weight' => 2,
-      ),
-      'teaser' => array(
-        'label' => 'above',
-        'settings' => array(),
-        'type' => 'hidden',
-        'weight' => 0,
-      ),
-    ),
-    'entity_type' => 'node',
-    'field_name' => 'group_access',
-    'label' => 'Group visibility',
-    'required' => TRUE,
-    'settings' => array(
-      'user_register_form' => FALSE,
-    ),
-    'view modes' => array(
-      'full' => array(
-        'label' => 'above',
-        'type' => 'options_onoff',
-      ),
-      'teaser' => array(
-        'label' => 'above',
-        'type' => 'options_onoff',
-      ),
-    ),
-    'widget' => array(
-      'module' => 'options',
-      'settings' => array(),
-      'type' => 'options_buttons',
-      'weight' => 2,
-    ),
-    'widget_type' => 'options_select',
-  );
-
-  // Exported field_instance: 'node-group-og_roles_permissions'
-  $field_instances['node-group-og_roles_permissions'] = array(
-    'bundle' => 'group',
-    'default_value' => array(
-      0 => array(
-        'value' => 0,
-      ),
-    ),
-    'deleted' => '0',
-    'description' => '',
-    'display' => array(
-      'default' => array(
-        'label' => 'above',
-        'module' => 'list',
-        'settings' => array(),
-        'type' => 'list_default',
-        'weight' => 1,
-      ),
-      'teaser' => array(
-        'label' => 'above',
-        'settings' => array(),
-        'type' => 'hidden',
-        'weight' => 0,
-      ),
-    ),
-    'entity_type' => 'node',
-    'field_name' => 'og_roles_permissions',
-    'label' => 'Group roles and permissions',
-    'required' => TRUE,
-    'settings' => array(
-      'user_register_form' => FALSE,
-    ),
-    'view modes' => array(
-      'full' => array(
-        'custom settings' => FALSE,
-        'label' => 'Full',
-        'type' => 'list_default',
-      ),
-      'teaser' => array(
-        'custom settings' => FALSE,
-        'label' => 'Teaser',
-        'type' => 'list_default',
-      ),
-    ),
-    'widget' => array(
-      'module' => 'options',
-      'settings' => array(),
-      'type' => 'options_select',
-      'weight' => 1,
-    ),
-  );
-
-  // Translatables
-  // Included for use with string extractors like potx.
-  t('Group content visibility');
-  t('Group roles and permissions');
-  t('Group visibility');
-
-  return $field_instances;
-}
-
-function commons_group_privacy_field_definition(&$field_instances, $entity_type, $bundle) {
-  // Exported field_instance: 'node-TYPE-group_content_access'
-  $field_instances["$entity_type-$bundle-group_content_access"] = array(
-    'bundle' => $bundle,
-    'default_value' => array(
-      0 => array(
-        'value' => 0,
-      ),
-    ),
-    'deleted' => '0',
-    'description' => '',
-    'display' => array(
-      'default' => array(
-        'label' => 'above',
-        'module' => 'list',
-        'settings' => array(),
-        'type' => 'list_default',
-        'weight' => 5,
-      ),
-      'teaser' => array(
-        'label' => 'above',
-        'settings' => array(),
-        'type' => 'hidden',
-        'weight' => 0,
-      ),
-    ),
-    'entity_type' => $entity_type,
-    'field_name' => 'group_content_access',
-    'label' => 'Group content visibility',
-    'required' => TRUE,
-    'settings' => array(
-      'user_register_form' => FALSE,
-    ),
-    'view modes' => array(
-      'full' => array(
-        'label' => 'above',
-        'type' => 'list_default',
-      ),
-      'teaser' => array(
-        'label' => 'above',
-        'type' => 'list_default',
-      ),
-    ),
-    'widget' => array(
-      'module' => 'options',
-      'settings' => array(),
-      'type' => 'options_select',
-      'weight' => 7,
-    ),
-    'widget_type' => 'options_select',
-  );
-}
diff --git a/modules/commons_group_privacy/commons_group_privacy.info b/modules/commons_group_privacy/commons_group_privacy.info
deleted file mode 100644
index a5714a7..0000000
--- a/modules/commons_group_privacy/commons_group_privacy.info
+++ /dev/null
@@ -1,14 +0,0 @@
-name = Commons Group Privacy
-core = 7.x
-package = Commons - Building blocks
-dependencies[] = commons_groups
-dependencies[] = features
-dependencies[] = list
-dependencies[] = og_access
-features[features_api][] = api:1
-features[field_base][] = group_access
-features[field_base][] = group_content_access
-features[field_base][] = og_roles_permissions
-features[field_instance][] = node-group-group_access
-features[field_instance][] = node-group-og_roles_permissions
-features[field_instance][] = node-post-group_content_access
\ No newline at end of file
diff --git a/modules/commons_group_privacy/commons_group_privacy.install b/modules/commons_group_privacy/commons_group_privacy.install
deleted file mode 100644
index 104f051..0000000
--- a/modules/commons_group_privacy/commons_group_privacy.install
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-/**
-* Revert field instances for group content privacy,
-* which where not added per http://drupal.org/node/1936446.
-*/
-function commons_group_privacy_update_3100() {
-  features_revert(array('commons_group_privacy' => array('field_instance')));
-  return array();
-}
\ No newline at end of file
diff --git a/modules/commons_group_privacy/commons_group_privacy.module b/modules/commons_group_privacy/commons_group_privacy.module
deleted file mode 100644
index 1a431fc..0000000
--- a/modules/commons_group_privacy/commons_group_privacy.module
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-/**
- * @file
- * Drupal needs this blank file.
- */
-
-
-/**
- * Implements hook_features_pipe_alter().
- *
- */
-function commons_group_privacy_features_pipe_alter(&$pipe, $data, $export) {
-  $group_access_fields = array(
-    'group_content_access', 'og_roles_permissions', 'group_access',
-  );
-  // Prevent Commons Group privacy fields from being piped in features
-  // when a content type includes those fields.
-  if (!empty($pipe['field_instance'])) {
-    foreach ($pipe['field_instance'] as $delta => $value) {
-      $args = explode('-', $value);
-      $field_name = $args[2];
-      if (in_array($field_name, $group_access_fields)) {
-        unset($pipe['field_instance'][$delta]);
-      }
-    }
-  }
-  if (!empty($pipe['field_base'])) {
-    foreach ($pipe['field_base'] as $delta => $value) {
-      if (in_array($delta, $group_access_fields)) {
-        unset($pipe['field_base'][$delta]);
-      }
-    }
-  }
-}
-
-/**
-* Implements hook_system_info_alter().
-*/
-function commons_group_privacy_system_info_alter(&$info, $file, $type) {
-  // Commons Groups dynamically adds the og_group_ref field to
-  // content types that request it by altering the
-  // commons_groups_entity_types variable.
-  // We must add a corresponding line for each field instance
-  // to commons_groups.info so that Features is aware of the instance
-  // and can sucessfully revert the field_instance component back
-  // to its default state.
-  if ($file->name == 'commons_group_privacy') {
-    $group_content_entity_types = commons_groups_get_group_content_entity_types();
-    if (!empty($group_content_entity_types)) {
-      foreach ($group_content_entity_types as $entity_type => $bundles) {
-        foreach(array_keys($bundles) as $bundle) {
-          $info['features']['field_instance'][] = "$entity_type-$bundle-group_content_access";
-        }
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/plugins/entityreference/selection/OgCommonsSelectionHandler.class.php b/plugins/entityreference/selection/OgCommonsSelectionHandler.class.php
new file mode 100644
index 0000000..09fcbfd
--- /dev/null
+++ b/plugins/entityreference/selection/OgCommonsSelectionHandler.class.php
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @file
+ * OG Commons groups selection handler.
+ */
+
+class OgCommonsSelectionHandler extends OgSelectionHandler {
+
+  public static function getInstance($field, $instance = NULL, $entity_type = NULL, $entity = NULL) {
+    return new self($field, $instance, $entity_type, $entity);
+  }
+
+  /**
+   * Overrides OgSelectionHandler::buildEntityFieldQuery().
+   */
+  public function buildEntityFieldQuery($match = NULL, $match_operator = 'CONTAINS') {
+    $group_type = $this->field['settings']['target_type'];
+
+    if (empty($this->instance['field_mode']) || $group_type != 'node') {
+      return parent::buildEntityFieldQuery($match, $match_operator);
+    }
+
+    $handler = EntityReference_SelectionHandler_Generic::getInstance($this->field, $this->instance, $this->entity_type, $this->entity);
+    $query = $handler->buildEntityFieldQuery($match, $match_operator);
+
+    // Show only the entities that are active groups.
+    $query->fieldCondition(OG_GROUP_FIELD, 'value', 1);
+    $query->fieldCondition('field_og_subscribe_settings', 'value', 'anyone');
+
+    // Add this property to make sure we will have the {node} table later on in
+    // OgCommonsSelectionHandler::entityFieldQueryAlter().
+    $query->propertyCondition('nid', 0, '>');
+
+    $query->addMetaData('entityreference_selection_handler', $this);
+
+    // FIXME: http://drupal.org/node/1325628
+    unset($query->tags['node_access']);
+
+    $query->addTag('entity_field_access');
+    $query->addTag('og');
+
+    return $query;
+  }
+
+  /**
+   * Overrides OgSelectionHandler::entityFieldQueryAlter().
+   *
+   * Add the user's groups along with the rest of the "public" groups.
+   */
+  public function entityFieldQueryAlter(SelectQueryInterface $query) {
+    $gids = og_get_entity_groups();
+    if (empty($gids['node'])) {
+      return;
+    }
+
+    $conditions = &$query->conditions();
+    // Find the condition for the "field_data_field_privacy_settings" query, and
+    // the one for the "node.nid", so we can later db_or() them.
+    $public_condition = array();
+    foreach ($conditions as $key => $condition) {
+      if ($key !== '#conjunction' && is_string($condition['field'])) {
+        if (strpos($condition['field'], 'field_data_field_og_subscribe_settings') === 0) {
+          $public_condition = $condition;
+          unset($conditions[$key]);
+        }
+
+        if ($condition['field'] === 'node.nid') {
+          unset($conditions[$key]);
+        }
+      }
+    }
+
+    if (!$public_condition) {
+      return;
+    }
+
+    $or = db_or();
+    $or->condition($public_condition['field'], $public_condition['value'], $public_condition['operator']);
+    $or->condition('node.nid', $gids['node'], 'IN');
+    $query->condition($or);
+  }
+}
diff --git a/plugins/entityreference/selection/og_commons.inc b/plugins/entityreference/selection/og_commons.inc
new file mode 100644
index 0000000..55fc029
--- /dev/null
+++ b/plugins/entityreference/selection/og_commons.inc
@@ -0,0 +1,6 @@
+<?php
+
+$plugin = array(
+  'title' => t('Commons OG'),
+  'class' => 'OgCommonsSelectionHandler',
+);
