diff --git a/sites/all/modules/taxonomy_access_control/tac.admin.php b/sites/all/modules/taxonomy_access_control/tac.admin.php
new file mode 100644
index 0000000000000000000000000000000000000000..d7340d5e74e708f585a58e9761e1f199369c86b8
--- /dev/null
+++ b/sites/all/modules/taxonomy_access_control/tac.admin.php
@@ -0,0 +1,114 @@
+<?php
+
+
+function tac_admin($form, $form_state, $rid = NULL)
+{    
+    $vocabularyObjects = taxonomy_get_vocabularies();
+    $vocabularies = array(-1 => '[Select One]');
+    foreach ($vocabularyObjects as $vocabularyObject) {
+        $vocabularies[$vocabularyObject->vid] = $vocabularyObject->name;
+    }
+    
+    $vocabulary = variable_get('tac_vocabulary', -1);
+    
+    $form = array();
+    $form[] = array(
+        'vocabulary' => array(
+              '#type' => 'select',
+              '#options' => $vocabularies,
+              '#title' => t('Vocabulary to use for Access Control'),
+              '#default_value' => $vocabulary
+        )
+    );
+    
+    if ($vocabulary > 0) {
+        
+        $query = db_select('tac_map', 'm');
+        $query->fields('m');
+        $data = $query->execute()->fetchAll();
+        
+        $currentValues = array();
+        foreach ($data as $row) {
+            $currentValues[$row->rid][$row->tid] = $row;
+        }
+                
+        foreach (user_roles() as $rid => $role) {
+            $subform = array(
+            	'#theme' => 'tac_term_list',
+            	'#title' => 'Permissions for role "' . $role . '"'
+            );
+            foreach (taxonomy_get_tree($vocabulary) as $term) {
+                $prefix = 'edit[' . $rid . '][' . $term->tid . ']';
+                $subform['term_' . $term->tid] = array(
+                    '#title'   => $term->name,
+                    'view' => array(
+                        '#parents' => array('edit', $rid, $term->tid, 'view'),
+                        '#type' => 'checkbox',
+                        '#default_value' => $currentValues[$rid][$term->tid]->grant_view
+                    ),
+                    'update' => array(
+                        '#parents' => array('edit', $rid, $term->tid, 'update'),
+                        '#type' => 'checkbox',
+                        '#default_value' => $currentValues[$rid][$term->tid]->grant_update
+                    ),
+                    'delete' => array(
+                        '#parents' => array('edit', $rid, $term->tid, 'delete'),
+                        '#type' => 'checkbox',
+                        '#default_value' => $currentValues[$rid][$term->tid]->grant_delete
+                    )
+                );
+            }
+            $form['role' . $rid] = $subform;
+        }
+    }
+    
+    $form[] = array(
+  		'#type' => 'submit',
+  		'#value' => t('Submit'),
+    );
+    
+    return $form;
+}
+
+function theme_tac_term_list($variables)
+{
+    $form = $variables['form'];
+    
+    $headers = array('Term', 'View', 'Update', 'Delete');
+    foreach (element_children($form) as $key) {
+        $rows[] = array(
+        	'data' => array(
+                $form[$key]['#title'],
+                drupal_render($form[$key]['view']),
+                drupal_render($form[$key]['update']),
+                drupal_render($form[$key]['delete']),
+            )
+        );
+    }
+    
+    return theme('table', array('header' => $headers, 'rows' => $rows, 'caption' => $form['#title']));
+}
+
+function tac_admin_submit($form, &$form_state)
+{
+    $vocabulary = $form_state['values']['vocabulary'];
+    if ($vocabulary > 0 && $vocabulary != variable_get('tac_vocabulary')) {
+        variable_set('tac_vocabulary', $vocabulary);
+        return;
+    } else if ($vocabulary <= 0) {
+        variable_del('tac_vocabulary');
+    }
+    
+    
+    db_delete('tac_map')->execute();
+    $insert = db_insert('tac_map')->fields(array('rid', 'tid', 'grant_view', 'grant_update', 'grant_delete'));
+    
+    foreach ($form_state['values']['edit'] as $rid => $terms) {
+        foreach ($terms as $tid => $grants) {
+            $insert->values(array($rid, $tid, $grants['view'], $grants['update'], $grants['delete']));
+        }
+    }
+    
+    $insert->execute();
+}
+
diff --git a/sites/all/modules/taxonomy_access_control/tac.info b/sites/all/modules/taxonomy_access_control/tac.info
new file mode 100644
index 0000000000000000000000000000000000000000..0374133cc165ce80034f42f9d9b5667fd8a8b310
--- /dev/null
+++ b/sites/all/modules/taxonomy_access_control/tac.info
@@ -0,0 +1,8 @@
+name = Taxonomy Access Control
+description = Enhances the Taxonomy feature of drupal to be used for Access Control.
+core = 7.x
+version = "7.x-1.0-20100901"
+
+dependencies[] = taxonomy
+files[] = tac.install
+files[] = tac.module
diff --git a/sites/all/modules/taxonomy_access_control/tac.install b/sites/all/modules/taxonomy_access_control/tac.install
new file mode 100644
index 0000000000000000000000000000000000000000..3aa690423cb24ee38f2e5bcda5916db89dcbb452
--- /dev/null
+++ b/sites/all/modules/taxonomy_access_control/tac.install
@@ -0,0 +1,129 @@
+<?php
+
+function tac_schema()
+{
+  $schema = array();
+  
+  $schema['tac_map'] = array(
+    'description' => 'Identifies which term/role pairs a user must possess in order to view, update, or delete specific nodes.',
+    'fields' => array(
+      'rid' => array(
+        'description' => 'The {role}.rid this record affects.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'tid' => array(
+        'description' => "The {taxonomy}.tid this record affects.",
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'grant_view' => array(
+        'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+      ),
+      'grant_update' => array(
+        'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+      ),
+      'grant_delete' => array(
+        'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+      ),
+    ),
+    'primary key' => array('rid', 'tid'),
+    'foreign keys' => array(
+      'affected_node' => array(
+        'table' => 'role',
+        'columns' => array('rid' => 'rid'),
+      ),
+      'affected_term' => array(
+        'table' => 'taxonomy_term_dat',
+        'columns' => array('tid' => 'tid'),
+      )
+    ),
+  );
+  
+  return $schema;
+}
+
+function tac_update_7100()
+{
+  $table = array(
+    'description' => 'Identifies which term/role pairs a user must possess in order to view, update, or delete specific nodes.',
+    'fields' => array(
+      'rid' => array(
+        'description' => 'The {role}.rid this record affects.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'tid' => array(
+        'description' => "The {taxonomy}.tid this record affects.",
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'grant_view' => array(
+        'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+      ),
+      'grant_update' => array(
+        'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+      ),
+      'grant_delete' => array(
+        'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+      ),
+    ),
+    'primary key' => array('rid', 'tid'),
+    'foreign keys' => array(
+      'affected_node' => array(
+        'table' => 'role',
+        'columns' => array('rid' => 'rid'),
+      ),
+      'affected_term' => array(
+        'table' => 'taxonomy_term_dat',
+        'columns' => array('tid' => 'tid'),
+      )
+    ),
+  );
+  
+  db_create_table('tac_map', $table);
+}
+
+
+
+
+
+
diff --git a/sites/all/modules/taxonomy_access_control/tac.module b/sites/all/modules/taxonomy_access_control/tac.module
new file mode 100644
index 0000000000000000000000000000000000000000..9e1cd0666d140d2c3e4fc005fcc28aaa9207b398
--- /dev/null
+++ b/sites/all/modules/taxonomy_access_control/tac.module
@@ -0,0 +1,106 @@
+<?php
+
+function tac_menu()
+{
+    $items = array();
+    
+    $items['admin/people/permissions/tac'] = array(
+        'title' => 'Taxonomy Access Controls',
+    	'page callback' => 'drupal_get_form',
+    	'page arguments' => array('tac_admin'),
+        'access callback' => TRUE,
+    	'file' => 'tac.admin.php',
+    	'type' => MENU_LOCAL_TASK
+    );
+    
+    return $items;
+}
+
+function tac_theme()
+{
+    return array(
+        'tac_term_list' => array(
+            'render element' => 'form'
+        )
+    );
+}
+
+function tac_form_alter(&$form, $form_state, $form_id)
+{
+    
+}
+
+function tac_node_access($node, $op, $account)
+{
+    return NODE_ACCESS_IGNORE;
+}
+
+function tac_node_access_records($node)
+{
+    $tac_vid = variable_get('tac_vocabulary', -1);
+    $fields_to_check = array();
+    
+    $fields = field_info_instances('node', $node->type);
+    foreach ($fields as $field) {
+        $fieldInfo = field_info_field($field['field_name']);
+        if ($fieldInfo['type'] != 'taxonomy_term_reference') {
+            continue;
+        }
+        $fields_to_check[] = $field['field_name'];
+    }
+    
+    $selected_tids = array();
+    foreach ($fields_to_check as $field) {
+        $fieldData = $node->$field;
+        foreach ($fieldData['und'] as $tid_array) {
+            $selected_tids[] = $tid_array['tid'];
+        }
+    }
+    
+    $selected_terms = taxonomy_term_load_multiple($selected_tids);
+    $grant_ids = array();
+    foreach ($selected_terms as $selected_term) {
+        if ($selected_term->vid != $tac_vid) {
+            continue;
+        }
+        $grant_ids[] = $selected_term->tid;
+    }
+    
+    $grants = array();
+    $grants[] = array(
+      'realm' => 'all',
+      'gid' => 0,
+      'grant_view' => 1,
+      'grant_update' => 0,
+      'grant_delete' => 0,
+      'priority' => 0,
+    );
+    
+    foreach ($grant_ids as $grant_id) {
+        //TODO: lookup which grant_x are supposed to be applied from the database.
+        $grants[] = array(
+          'realm' => 'tac',
+          'gid' => $grant_id,
+          'grant_view' => 1,
+          'grant_update' => 1,
+          'grant_delete' => 1,
+          'priority' => 0,
+        );
+    }
+    
+    return $grants;
+}
+
+function tac_node_grants($account, $op)
+{
+    $query = db_select('tac_map', 'm');
+    $query->addField('m', 'tid');
+    $query->condition('m.grant_' . $op, 1);
+    $query->condition('m.rid', array_keys($account->roles));
+    $tids = $query->execute()->fetchCol();
+    
+    $grants = array();
+    $grants['tac'] = $tids;
+    
+    return $grants;
+}