diff --git a/field_permission_example/field_permission_example.css b/field_permission_example/field_permission_example.css
new file mode 100644
index 0000000..59cda31
--- /dev/null
+++ b/field_permission_example/field_permission_example.css
@@ -0,0 +1,22 @@
+/**
+ * @file
+ * CSS for Field Example.
+ */
+.stickynote {
+background:#fefabc;
+padding:0.8em;
+font-family:cursive;
+font-size:1.1em;
+color: #000;
+width:15em;
+
+-moz-transform: rotate(2deg);
+-webkit-transform: rotate(2deg);
+-o-transform: rotate(2deg);
+-ms-transform: rotate(2deg);
+transform: rotate(2deg);
+
+box-shadow: 0px 4px 6px #333;
+-moz-box-shadow: 0px 4px 6px #333;
+-webkit-box-shadow: 0px 4px 6px #333;
+}
diff --git a/field_permission_example/field_permission_example.info b/field_permission_example/field_permission_example.info
new file mode 100644
index 0000000..cdd9253
--- /dev/null
+++ b/field_permission_example/field_permission_example.info
@@ -0,0 +1,5 @@
+name = Field Permission Example
+description = A Field API Example: Fieldnote with Permissions
+package = Example modules
+core = 7.x
+files[] = tests/field_permission_example.test
diff --git a/field_permission_example/field_permission_example.install b/field_permission_example/field_permission_example.install
new file mode 100644
index 0000000..55388d2
--- /dev/null
+++ b/field_permission_example/field_permission_example.install
@@ -0,0 +1,32 @@
+<?php
+/**
+ * @file
+ * Install function for the field_permission_example module.
+ */
+
+/**
+ * Implements hook_field_schema().
+ *
+ * Defines the database schema of the field, using the format used by the
+ * Schema API.
+ *
+ * We only want a simple text field, similar to the body of a node.
+ *
+ * Note that this field has only a normal text (which translates to
+ * 16k of text in MySQL), and so therefore doesn't have an index.
+ * More complex schema would probably have at least one indexed
+ * column.
+ *
+ * @see http://drupal.org/node/146939
+ * @see schemaapi
+ * @see hook_field_schema()
+ * @ingroup field_permission_example
+ */
+function field_permission_example_field_schema($field) {
+  $columns = array(
+    'notes' => array('type' => 'text', 'size' => 'normal', 'not null' => FALSE),
+  );
+  return array(
+    'columns' => $columns,
+  );
+}
diff --git a/field_permission_example/field_permission_example.module b/field_permission_example/field_permission_example.module
new file mode 100644
index 0000000..1226221
--- /dev/null
+++ b/field_permission_example/field_permission_example.module
@@ -0,0 +1,321 @@
+<?php
+/**
+ * @file
+ * An example field using the Field Types API.
+ */
+
+/**
+ * @defgroup field_permission_example Example: Field Permissions
+ * @ingroup examples
+ * @{
+ * Example using permissions on a Field API field.
+ *
+ * This example is a relatively simple text field you can attach to
+ * any fieldable entity.
+ *
+ * In this module we demonstrate how to limit access to a field.
+ * Drupal's Field API gives you two operations to permit or restrict:
+ * view and edit. So you can then decide who gets to see fields,
+ * who can edit them, and who can manage them.
+ *
+ * Our field is called field_permission_example_fieldnote. It has a
+ * simple default widget of a text area, and a default formatter
+ * that applies a CSS style to make it look like a sticky note.
+ *
+ * In addition to demonstrating how to set up permissions-based
+ * access to a field, this module also demonstrates the absolute
+ * minimum required to implement a field, since it doesn't have
+ * any field settings. The tests also have a generalized
+ * field testing class, called FieldTestGeneric, which can be easily
+ * subclassed and reused for other fields.
+ *
+ * If you wish to use this code as skeleton code for a field without
+ * permissions, you can simply remove field_permission_exampe_permission()
+ * and field_permission_field_access(). Also field_permission_example_menu()
+ * and _field_permission_example_page() are vestigial to the Examples
+ * project.
+ *
+ * How does it work?
+ *
+ * You can install this module and go to path /examples/field_permission_example
+ * for an introduction on how to use this field. Or see the same content at
+ * _field_permission_example_page().
+ *
+ * OK, how does the code work?
+ *
+ * As with any permission system, we implement hook_permission() in
+ * order to define a few permissions. In our case, users will want
+ * to either view or edit fieldnote fields. And, similar to the way
+ * node permissions work, we'll also include a context of either
+ * their own content or any content. So that gives us 4 permissions
+ * which administrators can assign to various roles. See
+ * field_permission_example_permission() for the list.
+ *
+ * With our permissions defined in hook_permission(), we can now
+ * handle requests for access. Those come in through
+ * hook_field_access(), which we've implemented as
+ * field_permission_example_field_acces(). This function determines
+ * whether the user has the ability to view or edit the field
+ * in question by calling user_access(). We also give special edit
+ * access to users with the 'bypass node access' and 
+ * 'administer content types' permissions, defined by the node module.
+ *
+ * One tricky part is that our field won't always be attached to
+ * nodes. It could be attached to any type of entity. This means
+ * that there's no general way to figure out if the user 'owns'
+ * the entity or not. Since this is a simple example, we'll just
+ * check for 'any' access to unknown entity types. We'll also
+ * limit our known entity types to node and user, since those
+ * are easy to demonstrate.
+ *
+ * In a real application, we'd have use-case specific permissions
+ * which might be more complex than these. Or perhaps simpler.
+ *
+ * You can see a more complex field implementation in
+ * field_example.module.
+ *
+ * @see field_example
+ * @see field_example.module
+ * @see field_types
+ * @see field
+ */
+
+/**
+ * Implements hook_permission().
+ *
+ * We want to let site administrators figure out who should
+ * be able to view, edit, and administer our field.
+ *
+ * Field permission operations can only be view or edit, in the
+ * context of one's own content or that of others. Constrast
+ * with content types where we also have to worry about who can
+ * create or delete content.
+ */
+function field_permission_example_permission() {
+  // Note: This would be very easy to generate programatically,
+  // but it's all typed out here for clarity.
+  // The key text is the machine name of the permission.
+  $perms['view own fieldnote'] = array('title' => t('View own fieldnote'));
+  $perms['edit own fieldnote'] = array('title' => t('Edit own fieldnote'));
+  $perms['view any fieldnote'] = array('title' => t('View any fieldnote'));
+  $perms['edit any fieldnote'] = array('title' => t('Edit any fieldnote'));
+
+  return $perms;
+}
+
+/**
+ * Implements hook_field_access().
+ *
+ * We want to make sure that fields aren't being seen or edited
+ * by those who shouldn't.
+ *
+ * We have to build a permission string similar to those in
+ * hook_permission() in order to ask Drupal whether the user
+ * has that permission. Permission strings will end up being
+ * like 'view any fieldnote' or 'edit own fieldnote'.
+ *
+ * The tricky thing here is that a field can be attached to any type
+ * of entity, so it's not always trivial to figure out whether
+ * $account 'owns' the entity. We'll support access restrictions for
+ * user and node entity types, and be permissive with others,
+ * since that's easy to demonstrate.
+ *
+ * @see field_permission_example_permissions()
+ */
+function field_permission_example_field_access($op, $field, $entity_type, $entity, $account) {
+  // This hook will be invoked for every field type, so we have to
+  // check that it's the one we're interested in.
+  if ($field['type'] == 'field_permission_example_fieldnote') {
+    // First we'll check if the user has the 'superuser'
+    // permissions that node provides. This way administrators
+    // will be able to administer the content types.
+    if (user_access('bypass node access', $account)) {
+      drupal_set_message(t('User can bypass node access.'));
+      return TRUE;
+    }
+    if (user_access('administer content types', $account)) {
+      drupal_set_message(t('User can administer content types.'));
+      return TRUE;
+    }
+    // Now check for our own permissions.
+    // $context will end up being either 'any' or 'own.'
+    $context = 'any';
+    switch ($entity_type) {
+      case 'user':
+      case 'node':
+        // While administering the field itself, $entity will be
+        // NULL, so we have to check it.
+        if ($entity) {
+          if ($entity->uid == $account->uid) $context = 'own';
+        }
+    }
+    // Assemble a permission string, such as
+    // 'view any fieldnote'
+    $permission = $op . ' ' . $context . ' fieldnote';
+    // Finally, ask Drupal if this account has that permission.
+    $access = user_access($permission, $account);
+    drupal_set_message('Fieldnote permission: ' . $permission. ', which is: ' . $access);
+    return $access;
+  }
+  // We have no opinion on field types other than our own.
+  return TRUE;
+}
+
+/**
+ * Implements hook_field_info().
+ *
+ * Provides the description of the field.
+ */
+function field_permission_example_field_info() {
+  return array(
+    // We name our field as the associative name of the array.
+    'field_permission_example_fieldnote' => array(
+      'label' => t('Fieldnote'),
+      'description' => t('Place a note-taking field on entities, with granular permissions.'),
+      'default_widget' => 'field_permission_example_widget',
+      'default_formatter' => 'field_permission_example_formatter',
+    ),
+  );
+}
+
+/**
+ * Implements hook_field_is_empty().
+ *
+ * hook_field_is_emtpy() is where Drupal asks us if this field is empty.
+ * Return TRUE if it does not contain data, FALSE if it does. This lets
+ * the form API flag an error when required fields are empty.
+ */
+function field_permission_example_field_is_empty($item, $field) {
+  return empty($item['notes']);
+}
+
+/**
+ * Implements hook_field_formatter_info().
+ *
+ * We need to tell Drupal about our excellent field formatter.
+ *
+ * It's some text in a div, styled to look like a sticky note.
+ *
+ * @see field_permission_example_field_formatter_view().
+ */
+function field_permission_example_field_formatter_info() {
+  return array(
+    // This formatter simply displays the text in a text field.
+    'field_permission_example_formatter' => array(
+      'label' => t('Simple text-based formatter'),
+      'field types' => array('field_permission_example_fieldnote'),
+    ),
+  );
+}
+
+/**
+ * Implements hook_field_formatter_view().
+ *
+ * Here we output the field for general consumption.
+ *
+ * The field will have a sticky note appearance, thanks to some
+ * simple CSS.
+ *
+ * Note that all of the permissions and access logic happens
+ * in hook_field_access(), and none of it is here.
+ */
+function field_permission_example_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+  $element = array();
+
+  switch ($display['type']) {
+    case 'field_permission_example_formatter':
+      foreach ($items as $delta => $item) {
+        $element[$delta] = array(
+          // We wrap the fieldnote content up in a div tag.
+          '#type' => 'html_tag',
+          '#tag' => 'div',
+          '#value' => check_plain($item['notes']),
+          // Let's give the note a nice appearance.
+          // It's a sticky note.
+          '#attributes' => array(
+            'class' => 'stickynote',
+            ),
+          // ..And this is the CSS for the stickynote.
+          '#attached' => array(
+            'css' => array(drupal_get_path('module', 'field_permission_example') .
+              '/field_permission_example.css'),
+            ),
+        );
+      }
+      break;
+  }
+  return $element;
+}
+
+/**
+ * Implements hook_field_widget_info().
+ *
+ * We're implementing just one widget: A basic textarea.
+ *
+ * @see field_permission_example_field_widget_form().
+ */
+function field_permission_example_field_widget_info() {
+  return array(
+    'field_permission_example_widget' => array(
+      'label' => t('Field note textarea'),
+      'field types' => array('field_permission_example_fieldnote'),
+    ),
+  );
+}
+
+/**
+ * Implements hook_field_widget_form().
+ *
+ * Drupal wants us to create a form for our field. We'll use
+ * something very basic like a default textarea.
+ *
+ * @see field_permission_example_field_widget_info().
+ */
+function field_permission_example_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+  // Grab the existing value for the field.
+  $value = isset($items[$delta]['notes']) ? $items[$delta]['notes'] : '';
+  // Grab a reference to the form element.
+  $widget = $element;
+  // Set up the delta for our return element.
+  $widget['#delta'] = $delta;
+  
+  // Figure out which widget we need to generate.
+  // In our case, there's only one type.
+  switch ($instance['widget']['type']) {
+    case 'field_permission_example_widget':
+      $widget += array(
+        '#type' => 'textarea',
+        '#default_value' => $value,
+      );
+      break;
+  }
+
+  $element['notes'] = $widget;
+  return $element;
+}
+
+/**
+ * Implements hook_menu().
+ *
+ * Provides a simple user interface that gives the developer some clues.
+ */
+function field_permission_example_menu() {
+  $items['examples/field_permission_example'] = array(
+    'title' => 'Field Permission Example',
+    'page callback' => '_field_permission_example_page',
+    'access callback' => TRUE,
+  );
+  return $items;
+}
+
+/**
+ * A simple page to explain to the developer what to do.
+ *
+ * @see field_permission_example.module
+ */
+function _field_permission_example_page() {
+  return t("The Field Example provides a field composed of an HTML RGB value, like #ff00ff. To use it, add the field to a content type.");
+}
+/**
+ * @} End of "defgroup field_permission_example".
+ */
diff --git a/field_permission_example/tests/field_permission_example.test b/field_permission_example/tests/field_permission_example.test
new file mode 100644
index 0000000..0def5a9
--- /dev/null
+++ b/field_permission_example/tests/field_permission_example.test
@@ -0,0 +1,267 @@
+<?php
+/**
+ * @file
+ * Tests for Field Example.
+ */
+
+/**
+ * A generic field testing class.
+ *
+ * Subclass this one to test your specific field type
+ * and get some basic unit testing for free.
+ */
+class FieldTestGeneric extends DrupalWebTestCase {
+
+  protected $node_type = ''; // Our special node type.
+
+  protected $field_names = array(); // The test fields we add.
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Generic Field Test',
+      'description' => 'Someone neglected to override FieldTestGeneric::getInfo().',
+      'group' => 'Examples',
+    );
+  }
+
+  protected function getFieldTypes() {
+    return array('these_are_not', 'valid_field_types', 'please_override');
+  }
+
+  protected function getModule() {
+    return 'this-is-not-a-module-name-please-override';
+  }
+
+  /**
+   * Our field types that have a UI.
+   */
+  protected function getFieldTypesUI() {
+    $return = array();
+    $field_types = $this->getFieldTypes();
+    foreach ($field_types as $type) {
+      $info = field_info_field_types($type);
+      if (!isset($info['no_ui'])) {
+        $return[] = $type;
+      } else {
+        if (!$info['no_ui']) $return[] = $type;
+      }
+    }
+    return $return;
+  }
+
+  function setUp() {
+    $modules = func_get_args();
+    if (isset($modules[0]) && is_array($modules[0])) {
+      $modules = $modules[0];
+    }
+    $modules[] = 'node';
+    $modules[] = 'field_ui';
+    parent::setUp($modules);
+  }
+
+  /**
+   * Verify that all the necessary info is specified in hook_field_info().
+   *
+   * The full list is label, description, settings, instance_settings,
+   * default_widget, default_formatter, no_ui.
+   *
+   * Some are optional, and we won't check for those.
+   *
+   * @see hook_field_info()
+   */
+  function testGenericFieldInfo() {
+    $field_types = $this->getFieldTypes();
+    $module = $this->getModule();
+    $info_keys = array(
+      'label',
+      'description',
+      'default_widget',
+      'default_formatter',
+    );
+
+    // We don't want to use field_info_field_types()
+    // because then Drupal might have filled in some defaults.
+    // So invoke hook_field_info() ourselves.
+    $modules = module_implements('field_info');
+    $this->assertTrue(in_array($module, $modules),
+      'Module ' . $module . ' implements hook_field_info()');
+
+    foreach ($field_types as $field_type) {
+      $field_info = module_invoke($module, 'field_info');
+      $this->assertTrue(isset($field_info[$field_type]),
+        'Module ' . $module . ' defines field type ' . $field_type);
+      $field_info = $field_info[$field_type];
+      foreach ($info_keys as $key) {
+        $this->assertTrue(
+          isset($field_info[$key]),
+          $field_type . "'s " . $key . ' is set.'
+        );
+      }
+    }
+  }
+
+  /**
+   * Test basic functionality of the field.
+   *
+   * - Creates an 'administer content types' user.
+   * - Creates a content type.
+   * - Adds all our field types.
+   * - Creates a node of the new type.
+   * - Adds content to the fieldnote.
+   * - Tests the result.
+   */
+  function testGenericAddAllFieldsToNode() {
+    // 32 is max length of content type string.
+    $this->node_type = strtolower($this->randomName(32));
+
+    // Create and login user.
+    $account = $this->drupalCreateUser(array(
+      'administer content types',
+      ));
+    $this->drupalLogin($account);
+
+    $this->drupalGet('admin/structure/types');
+
+    // Create the content type.
+    $this->clickLink(t('Add content type'));
+
+    $edit = array(
+      'name' => $this->node_type,
+      'type' => $this->node_type,
+    );
+    $this->drupalPost(NULL, $edit, t('Save and add fields'));
+    $this->assertText(t('The content type @name has been added.', array('@name' => $this->node_type)));
+
+    // Get all our field types.
+    $field_types = $this->getFieldTypes();
+    // Keep a list of no_ui fields so we can tell the user.
+    $unsafe_field_types = array();
+
+    foreach ($field_types as $field_type) {
+      // Get the field info.
+      $field_info = field_info_field_types($field_type);
+      // Exclude no_ui field types.
+      if (isset($field_info['no_ui']) && $field_info['no_ui']) {
+        $unsafe_field_types[] = $field_type;
+      } else {
+        // Generate a name for our field.
+        // 26 is max length for field name.
+        $field_name = strtolower($this->randomName(26));
+        $this->field_names[] = $field_name;
+        // Create the field through Form API.
+        $this->formCreateField($field_type, $field_name, $field_info['default_widget'], 1);
+      }
+    }
+
+    // Tell the user which fields we couldn't test.
+    if (!empty($unsafe_field_types))
+      $this->pass(
+        'Generic test is unable to test these no_ui fields: ' .
+        implode(', ', $unsafe_field_types)
+      );
+
+    // Somehow clicking "save" isn't enough, and we have to
+    // rebuild a few caches.
+    node_types_rebuild();
+    menu_rebuild();
+
+    $types = node_type_get_names();
+    $this->assertTrue(isset($types[$this->node_type]),
+      'Content type ' . $this->node_type . ' has been created.'
+      );
+  }
+
+  function testGenericRemoveAllFields() {
+
+  }
+
+/*    $permissions = array(
+      'create ' . $content_type_machine . ' content',
+      'administer content types',
+      );
+    // Reset the permissions cache.
+    $this->checkPermissions($permissions, TRUE);
+  }
+    // Now that we have a new content type, create a user that has privileges
+    // on the content type.
+    $account = $this->drupalCreateUser($permissions);
+    $this->drupalLogin($account);
+
+    $this->drupalGet('node/add/' . $content_type_machine);
+
+    // Add a node.
+    $title = $this->randomName(20);
+    $fieldnote_content = $this->randomName(30);
+    $edit = array(
+      'title' => $title,
+      'field_' . $fieldnote . '[und][0][notes]' => $fieldnote_content,
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertText(t('@content_type_machine @title has been created', array('@content_type_machine' => $content_type_machine, '@title' => $title)));
+*/
+/*
+    $output_strings = $this->xpath("//div[contains(@class,'field-type-field-example-rgb')]/div/div/p/text()");
+
+    $this->assertEqual((string)$output_strings[0], t("The color code in this field is #000001"));
+    $this->assertEqual((string)$output_strings[1], t("The color code in this field is #000002"));
+    $this->assertEqual((string)$output_strings[2], t("The color code in this field is #000003"));
+    $this->assertEqual((string)$output_strings[3], t("The color code in this field is #000004"));
+    $this->assertEqual((string)$output_strings[4], t("The color code in this field is #000005"));
+  }
+*/
+  /**
+   * Create fields on a content type from the 'manage fields' page.
+   *
+   * @param $field_type
+   *   Type of the field we're adding.
+   * @param $field_name
+   *   Name of the field, like field_something
+   * @param $widget_type
+   *   Widget type, like field_something_widget
+   * @param $cardinality
+   *   Cardinality. How many?
+   */
+  protected function formCreateField($field_type, $field_name, $widget_type, $cardinality) {
+    $edit = array(
+      'fields[_add_new_field][label]' => $field_name,
+      'fields[_add_new_field][field_name]' => $field_name,
+      'fields[_add_new_field][type]' => $field_type,
+      'fields[_add_new_field][widget_type]' => $widget_type,
+
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    // Assume there are no settings for this,
+    // so just press the button.
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+
+    $edit = array('field[cardinality]' => (string)$cardinality);
+    $this->drupalPost(NULL, $edit, t('Save settings'));
+
+    debug(t('Saved settings for field !field_name with widget !widget_type and cardinality !cardinality', array('!field_name' => $field_name, '!widget_type' => $widget_type, '!cardinality' => $cardinality)));
+
+    $this->assertText(t('Saved @name configuration.', array('@name' => $field_name)));
+  }
+}
+
+class FieldTestPermissionsExample extends FieldTestGeneric {
+  function setUp() {
+    parent::setUp(array('field_permission_example'));
+  }
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Field Permission Example',
+      'description' => 'Various tests on the functionality of the Fieldnote field.',
+      'group' => 'Examples',
+    );
+  }
+
+  function getFieldTypes() {
+    return array('field_permission_example_fieldnote');
+  }
+
+  function getModule() {
+    return 'field_permission_example';
+  }
+}
