diff --git a/block_access.admin.inc b/block_access.admin.inc
index 0c269bd..04d1340 100644
--- a/block_access.admin.inc
+++ b/block_access.admin.inc
@@ -1,6 +1,6 @@
 <?php
 // $Id$
-/* 
+/*
  * @file block_access.admin.inc
  * Admin interfaces for block_access module
  */
@@ -11,24 +11,30 @@ function block_access_admin_list() {
   return theme('block_access_admin_list', array('modules' => $modules));
 }
 
-function block_access_module_form(&$form_state, $op = NULL, $module = NULL) {
+function block_access_module_form($form, &$form_state, $module) {
   $form = array();
   $form['module'] = array(
     '#type' => 'hidden',
     '#value' => $module
   );
-  $roles = user_roles();
-  block_access_fieldset($form, $roles, 'view', $module);
-  block_access_fieldset($form, $roles, 'move', $module);
-  block_access_fieldset($form, $roles, 'enable', $module);
-  block_access_fieldset($form, $roles, 'disable', $module);
-  block_access_fieldset($form, $roles, 'config', $module);
-  block_access_fieldset($form, $roles, 'delete', $module);
-  block_access_fieldset($form, $roles, 'config_lang', $module);
-  block_access_fieldset($form, $roles, 'config_spec', $module);
-  block_access_fieldset($form, $roles, 'config_user', $module);
-  block_access_fieldset($form, $roles, 'config_role', $module);
-  block_access_fieldset($form, $roles, 'config_page', $module);
+  $delta = 0;
+  $role_options = user_roles();
+  // Add fieldset for each permission
+  block_access_fieldset($form, $role_options, 'view', $module, $delta);
+  block_access_fieldset($form, $role_options, 'move', $module, $delta);
+  block_access_fieldset($form, $role_options, 'enable', $module, $delta);
+  block_access_fieldset($form, $role_options, 'disable', $module, $delta);
+  block_access_fieldset($form, $role_options, 'config', $module, $delta);
+  block_access_fieldset($form, $role_options, 'delete', $module, $delta);
+  block_access_fieldset($form, $role_options, 'config_lang', $module, $delta);
+  block_access_fieldset($form, $role_options, 'config_title', $module, $delta);
+  block_access_fieldset($form, $role_options, 'config_desc', $module, $delta);
+  block_access_fieldset($form, $role_options, 'config_body', $module, $delta);
+  block_access_fieldset($form, $role_options, 'config_region', $module, $delta);
+  block_access_fieldset($form, $role_options, 'config_page_visibility', $module, $delta);
+  block_access_fieldset($form, $role_options, 'config_type_visibility', $module, $delta);
+  block_access_fieldset($form, $role_options, 'config_role_visibility', $module, $delta);
+  block_access_fieldset($form, $role_options, 'config_user_visibility', $module, $delta);
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Save'),
@@ -39,15 +45,19 @@ function block_access_module_form(&$form_state, $op = NULL, $module = NULL) {
 function block_access_module_form_submit($form, &$form_state) {
   $values = $form_state['values'];
   $module = $values['module'];
-  block_access_config_set_roles('view',        $values['view_roles'], $module);
-  block_access_config_set_roles('move',        $values['move_roles'], $module);
-  block_access_config_set_roles('enable',      $values['enable_roles'], $module);
-  block_access_config_set_roles('disable',     $values['disable_roles'], $module);
-  block_access_config_set_roles('config',      $values['config_roles'], $module);
-  block_access_config_set_roles('delete',      $values['delete_roles'], $module);
-  block_access_config_set_roles('config_lang', $values['config_lang_roles'], $module);
-  block_access_config_set_roles('config_spec', $values['config_spec_roles'], $module);
-  block_access_config_set_roles('config_user', $values['config_user_roles'], $module);
-  block_access_config_set_roles('config_role', $values['config_role_roles'], $module);
-  block_access_config_set_roles('config_page', $values['config_page_roles'], $module);
+  block_access_config_set_roles('view',          $form_state['values']['view_roles'], $module, $delta);
+  block_access_config_set_roles('move',          $form_state['values']['move_roles'], $module, $delta);
+  block_access_config_set_roles('enable',        $form_state['values']['enable_roles'], $module, $delta);
+  block_access_config_set_roles('disable',       $form_state['values']['disable_roles'], $module, $delta);
+  block_access_config_set_roles('config',        $form_state['values']['config_roles'], $module, $delta);
+  block_access_config_set_roles('delete',        $form_state['values']['delete_roles'], $module, $delta);
+  block_access_config_set_roles('config_lang',   $form_state['values']['config_lang_roles'], $module, $delta);
+  block_access_config_set_roles('config_title',  $form_state['values']['config_title_roles'], $module, $delta);
+  block_access_config_set_roles('config_desc',   $form_state['values']['config_desc_roles'], $module, $delta);
+  block_access_config_set_roles('config_body',   $form_state['values']['config_body_roles'], $module, $delta);
+  block_access_config_set_roles('config_region', $form_state['values']['config_region_roles'], $module, $delta);
+  block_access_config_set_roles('config_type',   $form_state['values']['config_type_visibility_roles'], $module, $delta);
+  block_access_config_set_roles('config_user',   $form_state['values']['config_user_visibility_roles'], $module, $delta);
+  block_access_config_set_roles('config_role',   $form_state['values']['config_role_visibility_roles'], $module, $delta);
+  block_access_config_set_roles('config_page',   $form_state['values']['config_page_visibility_roles'], $module, $delta);
 }
diff --git a/block_access.info b/block_access.info
index c51885d..bdb0c9a 100644
--- a/block_access.info
+++ b/block_access.info
@@ -8,3 +8,10 @@ files[] = block_access.module
 files[] = block_access.admin.inc
 files[] = block_access.db.inc
 files[] = block_access.theme.inc
+
+; Information added by drupal.org packaging script on 2011-12-03
+version = "7.x-1.x-dev"
+core = "7.x"
+project = "block_access"
+datestamp = "1322871009"
+
diff --git a/block_access.module b/block_access.module
index bef74d5..f14af49 100644
--- a/block_access.module
+++ b/block_access.module
@@ -1,6 +1,6 @@
 <?php
 // $Id: block_access.module,v 1.1.2.2 2010/05/12 17:26:02 lambic Exp $
-/* 
+/*
  * @file block_access.module
  * This module handles access permissions for the block admin page.
  * The block admin page is a beast in need of taming. This is one way
@@ -12,32 +12,40 @@
  * The first bunch relate to all blocks so are plain strings
  * The second bunch use @block placeholder to hold the title of the block
  */
-define('BLOCK_ACCESS_ADMIN',            'administer block access settings');
-define('BLOCK_ACCESS_CREATE',           'create blocks');
-define('BLOCK_ACCESS_ALL_VIEW',         'view all blocks');
-define('BLOCK_ACCESS_ALL_MOVE',         'move all blocks');
-define('BLOCK_ACCESS_ALL_ENABLE',       'enable all blocks');
-define('BLOCK_ACCESS_ALL_DISABLE',      'disable all blocks');
-define('BLOCK_ACCESS_ALL_DELETE',       'delete all blocks');
-define('BLOCK_ACCESS_ALL_CONFIG',       'configure all blocks. ');
-define('BLOCK_ACCESS_ALL_CONFIG_LANG',  'configure all language settings');
-define('BLOCK_ACCESS_ALL_CONFIG_SPEC',  'configure all specific settings');
-define('BLOCK_ACCESS_ALL_CONFIG_USER',  'configure all user settings');
-define('BLOCK_ACCESS_ALL_CONFIG_ROLE',  'configure all role settings');
-define('BLOCK_ACCESS_ALL_CONFIG_PAGE',  'configure all page settings');
+define('BLOCK_ACCESS_ADMIN',                  'administer block access settings');
+define('BLOCK_ACCESS_BLOCK_ADMIN',            'access the block administration page');
+define('BLOCK_ACCESS_CREATE',                 'create blocks');
+define('BLOCK_ACCESS_ALL_VIEW',               'view all blocks');
+define('BLOCK_ACCESS_ALL_MOVE',               'move all blocks');
+define('BLOCK_ACCESS_ALL_ENABLE',             'enable all blocks');
+define('BLOCK_ACCESS_ALL_DISABLE',            'disable all blocks');
+define('BLOCK_ACCESS_ALL_DELETE',             'delete all blocks');
+define('BLOCK_ACCESS_ALL_CONFIG',             'configure all blocks. ');
+define('BLOCK_ACCESS_ALL_CONFIG_LANG',        'configure all language settings');
+define('BLOCK_ACCESS_ALL_CONFIG_TITLE',       'configure all block titles');
+define('BLOCK_ACCESS_ALL_CONFIG_DESC',        'configure all block descriptions');
+define('BLOCK_ACCESS_ALL_CONFIG_BODY',        'configure all block body fields');
+define('BLOCK_ACCESS_ALL_CONFIG_REGION',      'configure all region settings');
+define('BLOCK_ACCESS_ALL_CONFIG_VISIBILITY',  'configure all visibility settings');
+define('BLOCK_ACCESS_ALL_CONFIG_PAGE',        'configure all page visibility settings');
+define('BLOCK_ACCESS_ALL_CONFIG_TYPE',        'configure all content type visibility settings');
+define('BLOCK_ACCESS_ALL_CONFIG_ROLE',        'configure all role visibility settings');
+define('BLOCK_ACCESS_ALL_CONFIG_USER',        'configure all user visibility settings');
 
 /*
  * Menu/Form items we need to mess with
  * The first is our own settings form, the others we are altering
  */
-define('BLOCK_ACCESS_SETTINGS',      'admin/structure/block/block-access');
-define('BLOCK_ACCESS_MENU_ADD',      'admin/structure/block/add');
-define('BLOCK_ACCESS_MENU_DELETE',   'admin/structure/block/delete');
-define('BLOCK_ACCESS_MENU_CONFIG',   'admin/structure/block/configure');
-define('BLOCK_ACCESS_FORM_ADMIN',    'block_admin_display_form');
-define('BLOCK_ACCESS_FORM_CONFIG',   'block_admin_configure');
-
-/* 
+define('BLOCK_ACCESS_BLOCK_ADMIN_PAGE', 'admin/structure/block');
+define('BLOCK_ACCESS_SETTINGS',         'admin/structure/block/block-access');
+define('BLOCK_ACCESS_MENU_ADD',         'admin/structure/block/add');
+define('BLOCK_ACCESS_MENU_DELETE',      'admin/structure/block/delete');
+define('BLOCK_ACCESS_MENU_MANAGE',      'admin/structure/block/manage/%/%');
+define('BLOCK_ACCESS_MENU_CONFIG',      'admin/structure/block/manage/%/%/configure');
+define('BLOCK_ACCESS_FORM_ADMIN',       'block_admin_display_form');
+define('BLOCK_ACCESS_FORM_CONFIG',      'block_admin_configure');
+
+/*
  * Implementation of hook_theme()
  */
 function block_access_theme() {
@@ -49,7 +57,7 @@ function block_access_theme() {
   );
 }
 
-/* 
+/*
  * Implementation of hook_menu()
  */
 function block_access_menu() {
@@ -79,14 +87,19 @@ function block_access_menu() {
  * @param $items array of menu items
  */
 function block_access_menu_alter(&$items) {
-    
+
+  $items[BLOCK_ACCESS_BLOCK_ADMIN_PAGE]['access arguments'] = array(BLOCK_ACCESS_BLOCK_ADMIN);
+
   $items[BLOCK_ACCESS_MENU_ADD]['access arguments'] = array(BLOCK_ACCESS_CREATE);
 
   $items[BLOCK_ACCESS_MENU_DELETE]['access callback'] = 'block_access_check_delete';
   $items[BLOCK_ACCESS_MENU_DELETE]['access arguments'] = array(4);
 
+  // Not sure if it's necessary to do both paths...
   $items[BLOCK_ACCESS_MENU_CONFIG]['access callback'] = 'block_access_check_config';
   $items[BLOCK_ACCESS_MENU_CONFIG]['access arguments'] = array(4, 5);
+  $items[BLOCK_ACCESS_MENU_MANAGE]['access callback'] = 'block_access_check_config';
+  $items[BLOCK_ACCESS_MENU_MANAGE]['access arguments'] = array(4, 5);
 
 }
 
@@ -102,19 +115,31 @@ function block_access_permission() {
       'title' => t(ucfirst(BLOCK_ACCESS_ADMIN)),
       'restrict access' => TRUE,
     ),
+    BLOCK_ACCESS_BLOCK_ADMIN => array('title' => t(ucfirst(BLOCK_ACCESS_BLOCK_ADMIN)),
+                                      'description' => t('Allow access to the block administration page. This does not stop users from configuring individual blocks (for example through the "Configure block" contextual link).')),
     BLOCK_ACCESS_CREATE => array('title' => t(ucfirst(BLOCK_ACCESS_CREATE))),
     BLOCK_ACCESS_ALL_VIEW => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_VIEW))),
     BLOCK_ACCESS_ALL_MOVE => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_MOVE))),
     BLOCK_ACCESS_ALL_ENABLE => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_ENABLE))),
     BLOCK_ACCESS_ALL_DISABLE => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_DISABLE))),
-    BLOCK_ACCESS_ALL_CONFIG => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG))),
     BLOCK_ACCESS_ALL_DELETE => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_DELETE))),
+    BLOCK_ACCESS_ALL_CONFIG => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG))),
     BLOCK_ACCESS_ALL_CONFIG_LANG => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_LANG))),
-    BLOCK_ACCESS_ALL_CONFIG_SPEC => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_SPEC))),
+    BLOCK_ACCESS_ALL_CONFIG_TITLE => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_TITLE))),
+    BLOCK_ACCESS_ALL_CONFIG_DESC => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_DESC))),
+    BLOCK_ACCESS_ALL_CONFIG_BODY => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_BODY))),
+    BLOCK_ACCESS_ALL_CONFIG_REGION => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_REGION))),
+    BLOCK_ACCESS_ALL_CONFIG_VISIBILITY => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_VISIBILITY)),
+                                                'description' => t('This must be checked for the individual visibility permissions to work. It will also override any individual visibility settings if not checked.')),
     BLOCK_ACCESS_ALL_CONFIG_USER => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_USER))),
     BLOCK_ACCESS_ALL_CONFIG_ROLE => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_ROLE))),
     BLOCK_ACCESS_ALL_CONFIG_PAGE => array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_PAGE))),
   );
+  // The content type visibility settings only gets added if the node module is enabled.
+  // I'm not sure who uses drupal without node enabled but it's possible...
+  if (module_exists('node')) {
+    $access[BLOCK_ACCESS_ALL_CONFIG_TYPE] = array('title' => t(ucfirst(BLOCK_ACCESS_ALL_CONFIG_TYPE)));
+  }
 
   return $access;
 }
@@ -146,6 +171,31 @@ function block_access_user_access($module, $delta, $perm) {
   return $perms[$module][$delta][$perm];
 }
 
+/**
+ * Implementation of hook_module_implements_alter
+ *
+ * We need this to change the order of when the hook_form_alters
+ * are called, so that block_access runs last. This is so that
+ * any other modules adding options to the form using a form_alter
+ * will run before ours and we'll be able to act on them. There is
+ * still the outstanding issue of how to resolve form alters that use
+ * the hook_form_FORM_ID_alter vs. hook_form_alter (see issue:
+ * http://drupal.org/node/765860#comment-5343140) but for now this will
+ * do. Another option could be to just increase the module weight on
+ * install...
+ *
+ * The reason for this implementation was because node.module is adding
+ * content type specific visibility settings after block_access did it's
+ * magic.
+ */
+function block_access_module_implements_alter(&$implementations, $hook) {
+  if ($hook == 'form_alter') {
+    $group = $implementations['block_access'];
+    unset($implementations['block_access']);
+    $implementations['block_access'] = $group;
+  }
+}
+
 /*
  * Helpers for each permission
  */
@@ -155,7 +205,7 @@ function block_access_can_view($module, $delta) {
 }
 
 function block_access_can_delete($module, $delta) {
-  return user_access(t(BLOCK_ACCESS_ALL_DELETE)) 
+  return user_access(t(BLOCK_ACCESS_ALL_DELETE))
       || block_access_user_access($module, $delta, 'delete');
 }
 
@@ -180,16 +230,24 @@ function block_access_can_move($module, $delta) {
 function block_access_can_config($module, $delta) {
   return user_access(t(BLOCK_ACCESS_ALL_CONFIG))
       || user_access(t(BLOCK_ACCESS_ALL_CONFIG_LANG))
-      || user_access(t(BLOCK_ACCESS_ALL_CONFIG_SPEC))
+      || user_access(t(BLOCK_ACCESS_ALL_CONFIG_TITLE))
+      || user_access(t(BLOCK_ACCESS_ALL_CONFIG_DESC))
+      || user_access(t(BLOCK_ACCESS_ALL_CONFIG_BODY))
+      || user_access(t(BLOCK_ACCESS_ALL_CONFIG_REGION))
+      || user_access(t(BLOCK_ACCESS_ALL_CONFIG_TYPE))
       || user_access(t(BLOCK_ACCESS_ALL_CONFIG_USER))
       || user_access(t(BLOCK_ACCESS_ALL_CONFIG_ROLE))
       || user_access(t(BLOCK_ACCESS_ALL_CONFIG_PAGE))
-      || block_access_user_access($module, $delta, 'config') 
+      || block_access_user_access($module, $delta, 'config')
       || block_access_user_access($module, $delta, 'config_lang')
-      || block_access_user_access($module, $delta, 'config_spec')
-      || block_access_user_access($module, $delta, 'config_user')
-      || block_access_user_access($module, $delta, 'config_role')
-      || block_access_user_access($module, $delta, 'config_page');
+      || block_access_user_access($module, $delta, 'config_title')
+      || block_access_user_access($module, $delta, 'config_desc')
+      || block_access_user_access($module, $delta, 'config_body')
+      || block_access_user_access($module, $delta, 'config_region')
+      || block_access_user_access($module, $delta, 'config_type_visibility')
+      || block_access_user_access($module, $delta, 'config_user_visibility')
+      || block_access_user_access($module, $delta, 'config_role_visibility')
+      || block_access_user_access($module, $delta, 'config_page_visibility');
 }
 
 function block_access_can_config_lang($module, $delta) {
@@ -197,27 +255,52 @@ function block_access_can_config_lang($module, $delta) {
       || block_access_user_access($module, $delta, 'config_lang');
 }
 
-function block_access_can_config_spec($module, $delta) {
-  return user_access(t(BLOCK_ACCESS_ALL_CONFIG_SPEC))
-      || block_access_user_access($module, $delta, 'config_spec'); 
+function block_access_can_config_title($module, $delta) {
+  return user_access(t(BLOCK_ACCESS_ALL_CONFIG_TITLE))
+      || block_access_user_access($module, $delta, 'config_title');
+}
+
+function block_access_can_config_description($module, $delta) {
+  return user_access(t(BLOCK_ACCESS_ALL_CONFIG_DESC))
+      || block_access_user_access($module, $delta, 'config_desc');
+}
+
+function block_access_can_config_body($module, $delta) {
+  return user_access(t(BLOCK_ACCESS_ALL_CONFIG_BODY))
+      || block_access_user_access($module, $delta, 'config_body');
+}
+
+function block_access_can_config_region($module, $delta) {
+  return user_access(t(BLOCK_ACCESS_ALL_CONFIG_REGION))
+      || block_access_user_access($module, $delta, 'config_region');
+}
+
+function block_access_can_config_visibility($module, $delta) {
+  return user_access(t(BLOCK_ACCESS_ALL_CONFIG_VISIBILITY))
+      || block_access_user_access($module, $delta, 'config_visibility');
+}
+
+function block_access_can_config_type($module, $delta) {
+  return user_access(t(BLOCK_ACCESS_ALL_CONFIG_TYPE))
+      || block_access_user_access($module, $delta, 'config_type_visibility');
 }
 
 function block_access_can_config_user($module, $delta) {
   return user_access(t(BLOCK_ACCESS_ALL_CONFIG_USER))
-      || block_access_user_access($module, $delta, 'config_user');
+      || block_access_user_access($module, $delta, 'config_user_visibility');
 }
 
 function block_access_can_config_role($module, $delta) {
   return user_access(t(BLOCK_ACCESS_ALL_CONFIG_ROLE))
-      || block_access_user_access($module, $delta, 'config_role');
+      || block_access_user_access($module, $delta, 'config_role_visibility');
 }
 
 function block_access_can_config_page($module, $delta) {
   return user_access(t(BLOCK_ACCESS_ALL_CONFIG_PAGE))
-      || block_access_user_access($module, $delta, 'config_page');
+      || block_access_user_access($module, $delta, 'config_page_visibility');
 }
 
-/* 
+/*
  * Separate out the permission checking for cleanliness
  * This one fiddles with the main block admin form
  * @param $form  array - the form API structure
@@ -230,35 +313,37 @@ function block_access_check_perms(&$form, $key, $block) {
 
   // Remove the block completely if it's not allowed to be viewed
   if (!block_access_can_view($module, $delta)) {
-    unset($form[$key]);
+    unset($form['blocks'][$key]);
   }
   else {
     // Remove the delete link if the user can't delete this block
     if (!block_access_can_delete($module, $delta)) {
-      unset($form[$key]['delete']);
+      $form['blocks'][$key]['delete']['#access'] = FALSE;
     }
     // Remove the configure link if the user can't configure this block
     if (!block_access_can_config($module, $delta)) {
-      unset($form[$key]['configure']);
+      $form['blocks'][$key]['configure']['#access'] = FALSE;
     }
 
-    // if a block is in BLOCK_REGION_NONE it is effectively disabled
-    if ($block['region']['#default_value'] == BLOCK_REGION_NONE) {
-      // Disable the region selection and weight if the user can't enable the block
-      if (!block_access_can_enable($module, $delta)) {
-        $form[$key]['region']['#disabled'] = TRUE;
-        $form[$key]['weight']['#disabled'] = TRUE;
-      }
+    // Disable the region selection and weight if the user can't move the block
+    if (!block_access_can_move($module, $delta)) {
+      $form['blocks'][$key]['region']['#access'] = FALSE;
+      $form['blocks'][$key]['weight']['#access'] = FALSE;
     }
     else {
-      // Disable the region selection and weight if the user can't move the block
-      if (!block_access_can_move($module, $delta)) {
-        $form[$key]['region']['#disabled'] = TRUE;
-        $form[$key]['weight']['#disabled'] = TRUE;
+      // if a block is in BLOCK_REGION_NONE it is effectively disabled
+      if ($form['blocks'][$key]['region']['#empty_value'] == BLOCK_REGION_NONE && !$form['blocks'][$key]['region']['#default_value']) {
+        // Disable the region selection and weight if the user can't enable the block
+        if (!block_access_can_enable($module, $delta)) {
+          $form['blocks'][$key]['region']['#access'] = FALSE;
+          $form['blocks'][$key]['weight']['#access'] = FALSE;
+        }
       }
-      // Remove the <none> option from the select list if the user can't disable the block
-      if (!block_access_can_disable($module, $delta)) {
-        unset($form[$key]['region']['#options'][BLOCK_REGION_NONE]);
+      if ($form['blocks'][$key]['region']['#default_value']) {
+        // Remove the <none> option from the select list if the user can't disable the block
+        if (!block_access_can_disable($module, $delta)) {
+          unset($form['blocks'][$key]['region']['#empty_value']);
+        }
       }
     }
   }
@@ -276,28 +361,57 @@ function block_access_check_config_form(&$form) {
   if (!block_access_can_config_lang($module, $delta)) {
     unset($form['i18n']);
   }
-  if (!block_access_can_config_spec($module, $delta)) {
-    unset($form['block_settings']);
+  if (!block_access_can_config_title($module, $delta)) {
+    $form['settings']['title']['#access'] = FALSE;
+  }
+  if (!block_access_can_config_description($module, $delta)) {
+    $form['settings']['info']['#access'] = FALSE;
   }
-  if (!block_access_can_config_user($module, $delta)) {
-    unset($form['user_vis_settings']);
+  if (!block_access_can_config_body($module, $delta)) {
+    $form['settings']['body_field']['#access'] = FALSE;
   }
-  if (!block_access_can_config_role($module, $delta)) {
-    unset($form['role_vis_settings']);
-    unset($form['role_view_settings']);
-    unset($form['role_move_settings']);
-    unset($form['role_enable_settings']);
-    unset($form['role_disable_settings']);
-    unset($form['role_delete_settings']);
-    unset($form['role_config_settings']);
-    unset($form['role_config_lang_settings']);
-    unset($form['role_config_spec_settings']);
-    unset($form['role_config_user_settings']);
-    unset($form['role_config_role_settings']);
-    unset($form['role_config_page_settings']);
+  if (!block_access_can_config_region($module, $delta)) {
+    $form['regions']['#access'] = FALSE;
   }
-  if (!block_access_can_config_page($module, $delta)) {
-    unset($form['page_vis_settings']);
+
+  // If the user can't config any visibility settings
+  if (!block_access_can_config_visibility($module, $delta)) {
+    $form['visibility']['#access'] = FALSE;
+    $form['visibility_title']['#access'] = FALSE;
+  }
+  else {
+    if (!block_access_can_config_page($module, $delta)) {
+      $form['visibility']['path']['#access'] = FALSE;
+    }
+    if (!block_access_can_config_role($module, $delta)) {
+      $form['visibility']['role']['#access'] = FALSE;
+      unset($form['role_view_settings']);
+      unset($form['role_move_settings']);
+      unset($form['role_enable_settings']);
+      unset($form['role_disable_settings']);
+      unset($form['role_delete_settings']);
+      unset($form['role_config_settings']);
+      unset($form['role_config_lang_settings']);
+      unset($form['role_config_title_settings']);
+      unset($form['role_config_desc_settings']);
+      unset($form['role_config_body_settings']);
+      unset($form['role_config_region_settings']);
+      unset($form['role_config_page_visibility_settings']);
+      unset($form['role_config_type_visibility_settings']);
+      unset($form['role_config_role_visibility_settings']);
+      unset($form['role_config_user_visibility_settings']);
+    }
+    if (!block_access_can_config_user($module, $delta)) {
+      $form['visibility']['user']['#access'] = FALSE;
+    }
+    if (module_exists('node') && !block_access_can_config_type($module, $delta)) {
+      $form['visibility']['node_type']['#access'] = FALSE;
+    }
+    // Hide the Visibility settings title if there are none available
+    if (!block_access_can_config_page($module, $delta) && !block_access_can_config_role($module, $delta) &&
+        !block_access_can_config_user($module, $delta) && (module_exists('node') && !block_access_can_config_type($module, $delta))) {
+      $form['visibility_title']['#access'] = FALSE;
+    }
   }
 }
 
@@ -305,19 +419,16 @@ function block_access_check_config_form(&$form) {
  * Implementation of hook_form_alter
  */
 function block_access_form_alter(&$form, &$form_state, $form_id) {
-
   // Only alter the form we're interested in
   if ($form_id == BLOCK_ACCESS_FORM_ADMIN) {
-
     // loop over all values, ignoring those that are not block arrays
-    foreach ($form as $key => $block) {
+    foreach ($form['blocks'] as $key => $block) {
       // it's a block array if it has the info attribute (assumption)
       if (is_array($block) && isset($block['info'])) {
         block_access_check_perms($form, $key, $block);
       }
     }
-
-    // override the submit button to run perm validation before block.admin 
+    // override the submit button to run perm validation before block.admin
     $form['#submit'][] = 'block_access_admin_display_submit';
   }
   // Or the other form we're interested in
@@ -327,19 +438,25 @@ function block_access_form_alter(&$form, &$form_state, $form_id) {
     $module = $form['module']['#value'];
     $delta = $form['delta']['#value'];
 
-    // Add fieldset for each permission
-    block_access_fieldset($form, $role_options, 'view', $module, $delta);
-    block_access_fieldset($form, $role_options, 'move', $module, $delta);
-    block_access_fieldset($form, $role_options, 'enable', $module, $delta);
-    block_access_fieldset($form, $role_options, 'disable', $module, $delta);
-    block_access_fieldset($form, $role_options, 'config', $module, $delta);
-    block_access_fieldset($form, $role_options, 'delete', $module, $delta);
-    block_access_fieldset($form, $role_options, 'config_lang', $module, $delta);
-    block_access_fieldset($form, $role_options, 'config_spec', $module, $delta);
-    block_access_fieldset($form, $role_options, 'config_user', $module, $delta);
-    block_access_fieldset($form, $role_options, 'config_role', $module, $delta);
-    block_access_fieldset($form, $role_options, 'config_page', $module, $delta);
-    array_unshift($form['#submit'], 'block_access_config_presubmit');
+    // Add fieldset for each permission if they have permission to change permissions
+    if (user_access('administer permissions')) {
+      block_access_fieldset($form, $role_options, 'view', $module, $delta);
+      block_access_fieldset($form, $role_options, 'move', $module, $delta);
+      block_access_fieldset($form, $role_options, 'enable', $module, $delta);
+      block_access_fieldset($form, $role_options, 'disable', $module, $delta);
+      block_access_fieldset($form, $role_options, 'delete', $module, $delta);
+      block_access_fieldset($form, $role_options, 'config', $module, $delta);
+      block_access_fieldset($form, $role_options, 'config_lang', $module, $delta);
+      block_access_fieldset($form, $role_options, 'config_title', $module, $delta);
+      block_access_fieldset($form, $role_options, 'config_desc', $module, $delta);
+      block_access_fieldset($form, $role_options, 'config_body', $module, $delta);
+      block_access_fieldset($form, $role_options, 'config_region', $module, $delta);
+      block_access_fieldset($form, $role_options, 'config_page_visibility', $module, $delta);
+      block_access_fieldset($form, $role_options, 'config_type_visibility', $module, $delta);
+      block_access_fieldset($form, $role_options, 'config_role_visibility', $module, $delta);
+      block_access_fieldset($form, $role_options, 'config_user_visibility', $module, $delta);
+    }
+    //array_unshift($form['#submit'], 'block_access_config_presubmit');
     $form['#submit'][] = 'block_access_config_submit';
     $form['submit']['#weight'] = 99;
 
@@ -386,7 +503,7 @@ function block_access_check_submit($form, $key, $block) {
   $name = check_plain($block['info']);
 
   // If the user is trying to disable the block but can't, report it
-  if ($block['region'] == BLOCK_REGION_NONE && $form[$key]['region']['#value'] != BLOCK_REGION_NONE 
+  if ($block['region'] == BLOCK_REGION_NONE && $form[$key]['region']['#value'] != BLOCK_REGION_NONE
   && !block_access_can_delete($block['module']['#value'], $block['delta']['#value'])) {
     drupal_set_message(t('You cannot disable @block.', array('@block' => $name)));
     $valid = FALSE;
@@ -412,6 +529,8 @@ function block_access_check_submit($form, $key, $block) {
 
 /*
  * Called on submit, before all other submit handlers to reset removed values
+ *
+ * NOT SURE IF THIS IS NEEDED ANYMORE...
  */
 function block_access_config_presubmit($form, &$form_state) {
   $module = $form_state['values']['module'];
@@ -452,18 +571,23 @@ function block_access_config_submit($form, &$form_state) {
   $module = $form_state['values']['module'];
   $delta = $form_state['values']['delta'];
 
+  // If there's one, they're all there.
   if (isset($form_state['values']['view_roles'])) {
-    block_access_config_set_roles('view',        $form_state['values']['view_roles'], $module, $delta);
-    block_access_config_set_roles('move',        $form_state['values']['move_roles'], $module, $delta);
-    block_access_config_set_roles('enable',      $form_state['values']['enable_roles'], $module, $delta);
-    block_access_config_set_roles('disable',     $form_state['values']['disable_roles'], $module, $delta);
-    block_access_config_set_roles('config',      $form_state['values']['config_roles'], $module, $delta);
-    block_access_config_set_roles('delete',      $form_state['values']['delete_roles'], $module, $delta);
-    block_access_config_set_roles('config_lang', $form_state['values']['config_lang_roles'], $module, $delta);
-    block_access_config_set_roles('config_spec', $form_state['values']['config_spec_roles'], $module, $delta);
-    block_access_config_set_roles('config_user', $form_state['values']['config_user_roles'], $module, $delta);
-    block_access_config_set_roles('config_role', $form_state['values']['config_role_roles'], $module, $delta);
-    block_access_config_set_roles('config_page', $form_state['values']['config_page_roles'], $module, $delta);
+    block_access_config_set_roles('view',          $form_state['values']['view_roles'], $module, $delta);
+    block_access_config_set_roles('move',          $form_state['values']['move_roles'], $module, $delta);
+    block_access_config_set_roles('enable',        $form_state['values']['enable_roles'], $module, $delta);
+    block_access_config_set_roles('disable',       $form_state['values']['disable_roles'], $module, $delta);
+    block_access_config_set_roles('delete',        $form_state['values']['delete_roles'], $module, $delta);
+    block_access_config_set_roles('config',        $form_state['values']['config_roles'], $module, $delta);
+    block_access_config_set_roles('config_lang',   $form_state['values']['config_lang_roles'], $module, $delta);
+    block_access_config_set_roles('config_title',  $form_state['values']['config_title_roles'], $module, $delta);
+    block_access_config_set_roles('config_desc',   $form_state['values']['config_desc_roles'], $module, $delta);
+    block_access_config_set_roles('config_body',   $form_state['values']['config_body_roles'], $module, $delta);
+    block_access_config_set_roles('config_region', $form_state['values']['config_region_roles'], $module, $delta);
+    block_access_config_set_roles('config_type',   $form_state['values']['config_type_visibility_roles'], $module, $delta);
+    block_access_config_set_roles('config_user',   $form_state['values']['config_user_visibility_roles'], $module, $delta);
+    block_access_config_set_roles('config_role',   $form_state['values']['config_role_visibility_roles'], $module, $delta);
+    block_access_config_set_roles('config_page',   $form_state['values']['config_page_visibility_roles'], $module, $delta);
   }
 }
 
