diff --git a/content_entity_example/config/install/user.role.contact_manager.yml b/content_entity_example/config/install/user.role.contact_manager.yml
new file mode 100644
index 0000000..b3ad639
--- /dev/null
+++ b/content_entity_example/config/install/user.role.contact_manager.yml
@@ -0,0 +1,14 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - content_entity_example
+id: contact_manager
+label: 'Campaign Manager'
+weight: 3
+is_admin: null
+permissions:
+ - 'view contact entity'
+ - 'add contact entity'
+ - 'edit contact entity'
+ - 'delete contact entity'
diff --git a/content_entity_example/config/install/user.role.contact_volunteer.yml b/content_entity_example/config/install/user.role.contact_volunteer.yml
new file mode 100644
index 0000000..a426680
--- /dev/null
+++ b/content_entity_example/config/install/user.role.contact_volunteer.yml
@@ -0,0 +1,13 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - content_entity_example
+id: contact_volunteer
+label: 'Campaign Volunteer'
+weight: 3
+is_admin: null
+permissions:
+ - 'view contact entity'
+ - 'add contact entity'
+ - 'edit contact entity'
diff --git a/content_entity_example/content_entity_example.module b/content_entity_example/content_entity_example.module
index 2a73e82..3544671 100755
--- a/content_entity_example/content_entity_example.module
+++ b/content_entity_example/content_entity_example.module
@@ -5,6 +5,8 @@
  * Contains Drupal\content_entity_example\content_entity_example.module
  */
 
+use Drupal\Core\Access\AccessResult;
+
 /**
  * @defgroup content_entity_example Example: Content Entity
  * @ingroup examples
@@ -31,3 +33,65 @@
  * Where ever possible, we use the amazing tools built into D8 natively.
  * }
  */
+
+
+/**
+ * Control access to fields.
+ *
+ * Implementation of hook_entity_field_access.
+ *
+ * In our exacmple code we demonstrate role based access, using roles we install with our module.
+ *
+ * This hook is invoked from
+ * \Drupal\Core\Entity\EntityAccessControlHandler::fieldAccess() to let modules
+ * grant or deny operations on fields.
+ *
+ * @param string $operation
+ *   The operation to be performed. See
+ *   \Drupal\Core\Access\AccessibleInterface::access() for possible values.
+ * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+ *   The field definition.
+ * @param \Drupal\Core\Session\AccountInterface $account
+ *   The user account to check.
+ * @param \Drupal\Core\Field\FieldItemListInterface $items
+ *   (optional) The entity field object on which the operation is to be
+ *   performed.
+ *
+ * @return \Drupal\Core\Access\AccessResultInterface
+ *   The access result.
+ */
+function content_entity_example_entity_field_access($operation, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, \Drupal\Core\Session\AccountInterface $account, \Drupal\Core\Field\FieldItemListInterface $items = NULL) {
+
+  //In our example, let's make field access control optional, by using a config setting to control it.  Since this
+  //hook can be called multiple times, we'll also cache some information between invocations.
+  $access_info = drupal_static(__FUNCTION__);
+  if (empty($access_info)) {
+    $config = \Drupal::config('content_entity_example.settings');
+    $access_info['activate_field_access'] = $config->get('activate_field_access');
+  }
+
+  //We only want to look at our own Content Entity, so ignore anything else.
+  if ((empty($access_info['activate_field_access'])) or
+      $field_definition->getTargetEntityTypeId() != 'content_entity_example_contact') {
+    return AccessResult::neutral();
+  }
+
+  //Get needed info for doing role-based field access:
+  $field_name = $field_definition->getName();
+  $roles = $account->getRoles();
+
+  //and define who is allowed to see and do everything. We're going to say that anyone that
+  //can administer our settings or has the 'contact_manager' role is an admin for this purpose.
+  if ($account->hasPermission('administer contact entity') or in_array('contact_manager', $roles)) {
+    return AccessResult::allowed();
+  }
+  //We allow people with our 'contact_volunteer' to see some but not all of our fields
+  else if (in_array('contact_volunteer', $roles)) {
+    if (in_array($operation, ['view', 'edit']) and $field_name != 'volunteer_rating') {
+      return AccessResult::allowed();
+    }
+    return AccessResult::forbidden();
+  }
+  //Do not interfere with any other field.
+  return AccessResult::neutral();
+}
diff --git a/content_entity_example/content_entity_example.routing.yml b/content_entity_example/content_entity_example.routing.yml
index f1e10e0..0a6317f 100755
--- a/content_entity_example/content_entity_example.routing.yml
+++ b/content_entity_example/content_entity_example.routing.yml
@@ -35,7 +35,7 @@ entity.content_entity_example_contact.edit_form:
   defaults:
   # Calls the form.edit controller, defined in the contact entity.
     _entity_form: content_entity_example_contact.edit
-    _title: 'Edit Contact'
+    _title_callback: 'Drupal\content_entity_example\Form\ContactForm::getTitle'
   requirements:
     _entity_access: 'content_entity_example_contact.edit'
 
diff --git a/content_entity_example/src/Entity/Contact.php b/content_entity_example/src/Entity/Contact.php
index 002ce20..4bca5c0 100755
--- a/content_entity_example/src/Entity/Contact.php
+++ b/content_entity_example/src/Entity/Contact.php
@@ -150,6 +150,19 @@ class Contact extends ContentEntityBase implements ContactInterface {
 
   /**
    * {@inheritdoc}
+   *
+   * We use this to set the display name to LAST, FIRST if it is not
+   * already set.
+   */
+  public function preSave(EntityStorageInterface $storage) {
+    if (empty($this->name->value)) {
+      $this->name = $this->last_name->value . ", " . $this->first_name->value;
+    }
+    parent::preSave($storage);
+  }
+  
+  /**
+   * {@inheritdoc}
    */
   public function getCreatedTime() {
     return $this->get('created')->value;
@@ -220,8 +233,8 @@ class Contact extends ContentEntityBase implements ContactInterface {
     // We set display options for the view as well as the form.
     // Users with correct privileges can change the view and edit configuration.
     $fields['name'] = BaseFieldDefinition::create('string')
-      ->setLabel(t('Name'))
-      ->setDescription(t('The name of the Contact entity.'))
+      ->setLabel(t('Display Name'))
+      ->setDescription(t('The display name of the Contact entity. Defaults to "LAST, FIRST"'))
       ->setSettings(array(
         'default_value' => '',
         'max_length' => 255,
@@ -239,6 +252,26 @@ class Contact extends ContentEntityBase implements ContactInterface {
       ->setDisplayConfigurable('form', TRUE)
       ->setDisplayConfigurable('view', TRUE);
 
+    $fields['last_name'] = BaseFieldDefinition::create('string')
+      ->setLabel(t('Last Name'))
+      ->setDescription(t('The last name of the Contact entity.'))
+      ->setSettings(array(
+        'default_value' => '',
+        'max_length' => 255,
+        'text_processing' => 0,
+      ))
+      ->setDisplayOptions('view', array(
+        'label' => 'above',
+        'type' => 'string',
+        'weight' => -5,
+      ))
+      ->setDisplayOptions('form', array(
+        'type' => 'string',
+        'weight' => -5,
+      ))
+      ->setDisplayConfigurable('form', TRUE)
+      ->setDisplayConfigurable('view', TRUE);
+
     $fields['first_name'] = BaseFieldDefinition::create('string')
       ->setLabel(t('First Name'))
       ->setDescription(t('The first name of the Contact entity.'))
@@ -259,6 +292,33 @@ class Contact extends ContentEntityBase implements ContactInterface {
       ->setDisplayConfigurable('form', TRUE)
       ->setDisplayConfigurable('view', TRUE);
 
+    //A popup field with potentially sensitive content.
+    //We'll use field access control to limit who can see this
+    //or edit it.
+    $fields['volunteer_rating'] = BaseFieldDefinition::create('list_integer')
+      ->setLabel(t('Volunteer Rating'))
+      ->setDescription(t('Rating of the volunteer represented by this contact.'))
+      ->setSettings(array(
+        'allowed_values' => array(
+          5 => t('Super'),
+          4 => t('Trusted'),
+          3 => t('Reliable'),
+          2 => t('Average'),
+          1 => t('Problem')
+        ),
+      ))
+      ->setDisplayOptions('view', array(
+        'label' => 'above',
+        'type' => 'list_default',
+        'weight' => -4,
+      ))
+      ->setDisplayOptions('form', array(
+        'type' => 'options_select',
+        'weight' => -4,
+      ))
+      ->setDisplayConfigurable('form', TRUE)
+      ->setDisplayConfigurable('view', TRUE);
+      
     // Gender field for the contact.
     // ListTextType with a drop down menu widget.
     // The values shown in the menu are 'male' and 'female'.
@@ -276,22 +336,23 @@ class Contact extends ContentEntityBase implements ContactInterface {
       ->setDisplayOptions('view', array(
         'label' => 'above',
         'type' => 'string',
-        'weight' => -4,
+        'weight' => -3,
       ))
       ->setDisplayOptions('form', array(
         'type' => 'options_select',
-        'weight' => -4,
+        'weight' => -3,
       ))
       ->setDisplayConfigurable('form', TRUE)
       ->setDisplayConfigurable('view', TRUE);
+      
 
     // Owner field of the contact.
     // Entity reference field, holds the reference to the user object.
     // The view shows the user name field of the user.
     // The form presents a auto complete field for the user name.
     $fields['user_id'] = BaseFieldDefinition::create('entity_reference')
-      ->setLabel(t('User Name'))
-      ->setDescription(t('The Name of the associated user.'))
+      ->setLabel(t('Creator Name'))
+      ->setDescription(t('The Name of the user who created/owns this contact.'))
       ->setSetting('target_type', 'user')
       ->setSetting('handler', 'default')
       ->setDisplayOptions('view', array(
diff --git a/content_entity_example/src/Entity/Controller/ContactListBuilder.php b/content_entity_example/src/Entity/Controller/ContactListBuilder.php
index bce8428..3aeb77b 100755
--- a/content_entity_example/src/Entity/Controller/ContactListBuilder.php
+++ b/content_entity_example/src/Entity/Controller/ContactListBuilder.php
@@ -45,8 +45,9 @@ class ContactListBuilder extends EntityListBuilder {
    */
   public function buildHeader() {
     $header['id'] = $this->t('ContactID');
-    $header['name'] = $this->t('Name');
+    $header['name'] = $this->t('Display Name');
     $header['first_name'] = $this->t('First Name');
+    $header['last_name'] = $this->t('Last Name');
     $header['gender'] = $this->t('Gender');
     return $header + parent::buildHeader();
   }
@@ -59,6 +60,7 @@ class ContactListBuilder extends EntityListBuilder {
     $row['id'] = $entity->id();
     $row['name'] = $entity->link();
     $row['first_name'] = $entity->first_name->value;
+    $row['last_name'] = $entity->last_name->value;
     $row['gender'] = $entity->gender->value;
     return $row + parent::buildRow($entity);
   }
diff --git a/content_entity_example/src/Form/ContactForm.php b/content_entity_example/src/Form/ContactForm.php
index 146d9ec..6b96c82 100755
--- a/content_entity_example/src/Form/ContactForm.php
+++ b/content_entity_example/src/Form/ContactForm.php
@@ -9,6 +9,7 @@ namespace Drupal\content_entity_example\Form;
 use Drupal\Core\Entity\ContentEntityForm;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Entity\EntityInterface;
 
 /**
  * Form controller for the content_entity_example entity edit forms.
@@ -42,4 +43,17 @@ class ContactForm extends ContentEntityForm {
     $entity = $this->getEntity();
     $entity->save();
   }
+  
+  /**
+   * Route callback so we can set the title dynamically
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $content_entity_example_contact
+   *   The current contact. The variable name *must* match the parameter in *.route.yml!!
+   *
+   * @return string
+   */
+  public function getTitle(EntityInterface $content_entity_example_contact ) {
+    $name = $content_entity_example_contact->name->value;
+    return $this->t('Edit Contact "@display_name"', ['@display_name' => $name]);
+  }
 }
diff --git a/content_entity_example/src/Form/ContactSettingsForm.php b/content_entity_example/src/Form/ContactSettingsForm.php
index 91ae840..7a3076d 100755
--- a/content_entity_example/src/Form/ContactSettingsForm.php
+++ b/content_entity_example/src/Form/ContactSettingsForm.php
@@ -6,7 +6,7 @@
 
 namespace Drupal\content_entity_example\Form;
 
-use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Form\FormStateInterface;
 
 /**
@@ -14,7 +14,7 @@ use Drupal\Core\Form\FormStateInterface;
  * @package Drupal\content_entity_example\Form
  * @ingroup content_entity_example
  */
-class ContactSettingsForm extends FormBase {
+class ContactSettingsForm extends ConfigFormBase {
   /**
    * Returns a unique string identifying the form.
    *
@@ -26,6 +26,13 @@ class ContactSettingsForm extends FormBase {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  protected function getEditableConfigNames() {
+    return ['content_entity_example.settings'];
+  }
+  
+  /**
    * Form submission handler.
    *
    * @param FormStateInterface $form
@@ -34,7 +41,10 @@ class ContactSettingsForm extends FormBase {
    *   An associative array containing the current state of the form.
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    // Empty implementation of the abstract submit class.
+    $this->config('content_entity_example.settings')
+      ->set('activate_field_access', $form_state->getValue('activate_field_access'))
+      ->save();
+    parent::submitForm($form, $form_state);
   }
 
 
@@ -49,7 +59,20 @@ class ContactSettingsForm extends FormBase {
    *   An associative array containing the current state of the form.
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
+    $config = $this->config('content_entity_example.settings');
     $form['contact_settings']['#markup'] = 'Settings form for ContentEntityExample. Manage field settings here.';
-    return $form;
+    $form['contact_settings']['field_access'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Activate Role-Based Field Access'),
+      '#description' => $this->t('In this example, you have the same access to fields that you do to the entity. If you check this box, users with the "Contact Manager" role can see all of the fields, and users with the "Campaign Volunteer" will see everything except the "Volunteer Rating" field.'),
+      'activate_field_access' => [
+        '#type' => 'checkbox',
+        '#title' => $this->t('Activate Role Based Access'),
+        '#default_value' => $config->get('activate_field_access')
+      ],
+    ];
+
+    return parent::buildForm($form, $form_state);
   }
+  
 }
