diff --git a/entity.api.php b/entity.api.php
index dff6cdc..8579a10 100644
--- a/entity.api.php
+++ b/entity.api.php
@@ -100,6 +100,8 @@
  *   module has been specified (see 'module') and the module does not provide
  *   any views integration. Else it defaults to FALSE, which disables this
  *   feature. See EntityDefaultViewsController.
+ * - views handlers: (optional) Views data about handlers, overriding the data
+ *   generated by EntityDefaultViewsController.
  * - access callback: (optional) Specify a callback that returns access
  *   permissions for the operations 'create', 'update', 'delete' and 'view'.
  *   The callback gets optionally the entity and the user account to check for
diff --git a/entity.info b/entity.info
index 3fce9ed..1f8feaf 100644
--- a/entity.info
+++ b/entity.info
@@ -1,6 +1,7 @@
 name = Entity API
 description = Enables modules to work with any entity type and to provide entities.
 core = 7.x
+files[] = views/handlers/entity.row_view.inc
 files[] = includes/entity.controller.inc
 files[] = includes/entity.inc
 files[] = includes/entity.ui.inc
@@ -9,3 +10,15 @@ files[] = entity.features.inc
 files[] = entity.info.inc
 files[] = entity.rules.inc
 files[] = entity.test
+files[] = views/handlers/entity_handler_field_property_boolean.inc
+files[] = views/handlers/entity_handler_field_property_date.inc
+files[] = views/handlers/entity_handler_field_property_numeric.inc
+files[] = views/handlers/entity_handler_field_property_uri.inc
+files[] = views/handlers/entity_handler_field_property_string.inc
+
+; Information added by drupal.org packaging script on 2011-03-21
+version = "7.x-1.0-beta8"
+core = "7.x"
+project = "entity"
+datestamp = "1300731067"
+
diff --git a/entity.module b/entity.module
index 432d469..26c9177 100644
--- a/entity.module
+++ b/entity.module
@@ -118,11 +118,21 @@ function entity_save($entity_type, &$entity) {
  * @see entity_type_supports()
  */
 function entity_delete($entity_type, $id) {
-  return entity_delete_multiple($entity_type, array($id));
+  $info = entity_get_info($entity_type);
+  if (isset($info['deletion callback'])) {
+    $info['deletion callback']($id);
+  }
+  elseif (in_array('EntityAPIControllerInterface', class_implements($info['controller class']))) {
+    entity_get_controller($entity_type)->delete(array($id));
+  }
+  else {
+    return FALSE;
+  }
 }
 
 /**
  * Permanently delete multiple entities.
+ * @todo: Add support for entity types not provided via the CRUD API.
  *
  * @param $entity_type
  *   The type of the entity.
@@ -133,12 +143,7 @@ function entity_delete($entity_type, $id) {
  */
 function entity_delete_multiple($entity_type, $ids) {
   $info = entity_get_info($entity_type);
-  if (isset($info['deletion callback'])) {
-    foreach ($ids as $id) {
-      $info['deletion callback']($id);
-    }
-  }
-  elseif (in_array('EntityAPIControllerInterface', class_implements($info['controller class']))) {
+  if (in_array('EntityAPIControllerInterface', class_implements($info['controller class']))) {
     entity_get_controller($entity_type)->delete($ids);
   }
   else {
@@ -590,21 +595,14 @@ function _entity_modules_get_default_types($modules) {
 
 /**
  * Defines schema fields required for exportable entities.
- *
- * Warning: Do not call this function in your module's hook_schema()
- * implementation or update functions. It is not safe to call functions of
- * dependencies at this point. Instead of calling the function, just copy over
- * the content.
- * For more details see the issue http://drupal.org/node/1122812.
+ * To be utilized by modules defining exportable entities.
  */
 function entity_exportable_schema_fields($module_col = 'module', $status_col = 'status') {
   return array(
     $status_col => array(
       'type' => 'int',
       'not null' => TRUE,
-      // Set the default to ENTITY_CUSTOM without using the constant as it is
-      // not safe to use it at this point.
-      'default' => 0x01,
+      'default' => ENTITY_CUSTOM,
       'size' => 'tiny',
       'description' => 'The exportable status of the entity.',
     ),
@@ -865,7 +863,7 @@ function entity_ui_get_form($entity_type, $entity, $op = 'edit') {
  */
 function entity_views_api() {
   return array(
-    'api' => '3.0-alpha1',
+    'api' => 3,
     'path' => drupal_get_path('module', 'entity') . '/views',
   );
 }
diff --git a/entity.rules.inc b/entity.rules.inc
index a85d566..1a21b4a 100644
--- a/entity.rules.inc
+++ b/entity.rules.inc
@@ -34,19 +34,27 @@ class EntityDefaultRulesController {
 
     $items[$type . '_insert'] = $defaults + array(
       'label' => t('After saving a new @entity', array('@entity' => drupal_strtolower($label))),
-      'variables' => entity_rules_events_variables($type, t('created @entity', array('@entity' => drupal_strtolower($label)))),
+      'variables' => array(
+        $type => array('type' => $type, 'label' => t('created @entity', array('@entity' => drupal_strtolower($label)))),
+      ),
     );
     $items[$type . '_update'] = $defaults + array(
       'label' => t('After updating an existing @entity', array('@entity' => drupal_strtolower($label))),
-      'variables' => entity_rules_events_variables($type, t('updated @entity', array('@entity' => drupal_strtolower($label))), TRUE),
+      'variables' => array(
+        $type => array('type' => $type, 'label' => t('updated @entity', array('@entity' => drupal_strtolower($label)))),
+      ),
     );
     $items[$type . '_presave'] = $defaults + array(
       'label' => t('Before saving a @entity', array('@entity' => drupal_strtolower($label))),
-      'variables' => entity_rules_events_variables($type, t('saved @entity', array('@entity' => drupal_strtolower($label))), TRUE),
+      'variables' => array(
+        $type => array('type' => $type, 'label' => t('saved @entity', array('@entity' => drupal_strtolower($label)))),
+      ),
     );
     $items[$type . '_delete'] = $defaults + array(
       'label' => t('After deleting a @entity', array('@entity' => drupal_strtolower($label))),
-      'variables' => entity_rules_events_variables($type, t('deleted @entity', array('@entity' => drupal_strtolower($label)))),
+      'variables' => array(
+        $type => array('type' => $type, 'label' => t('deleted @entity', array('@entity' => drupal_strtolower($label)))),
+      ),
     );
     // Specify that on presave the entity is saved anyway.
     $items[$type . '_presave']['variables'][$type]['skip save'] = TRUE;
@@ -56,25 +64,6 @@ class EntityDefaultRulesController {
 }
 
 /**
- * Returns some parameter info suiting for the specified entity type.
- */
-function entity_rules_events_variables($type, $label, $update = FALSE) {
-  $args = array(
-    $type => array('type' => $type, 'label' => $label),
-  );
-  if ($update) {
-    $args += array(
-      $type . '_unchanged' => array(
-        'type' => $type,
-        'label' => t('unchanged entity'),
-        'handler' => 'rules_events_entity_unchanged',
-      ),
-    );
-  }
-  return $args;
-}
-
-/**
  * Implements hook_rules_event_info().
  */
 function entity_rules_event_info() {
diff --git a/entity.test b/entity.test
index edb1ffa..7ae465c 100644
--- a/entity.test
+++ b/entity.test
@@ -757,7 +757,7 @@ class EntityMetadataIntegrationTestCase extends DrupalWebTestCase {
         $this->assertValue($wrapper, $key);
       }
     }
-    $this->assertEmpty($wrapper, 'parent');
+    $this->assertException($wrapper, 'parent');
   }
 
   /**
diff --git a/entity_token.info b/entity_token.info
index 66fddcb..535fab3 100644
--- a/entity_token.info
+++ b/entity_token.info
@@ -4,3 +4,10 @@ core = 7.x
 files[] = entity_token.tokens.inc
 files[] = entity_token.module
 dependencies[] = entity
+
+; Information added by drupal.org packaging script on 2011-03-21
+version = "7.x-1.0-beta8"
+core = "7.x"
+project = "entity"
+datestamp = "1300731067"
+
diff --git a/includes/entity.inc b/includes/entity.inc
index 89903cd..8cf0418 100644
--- a/includes/entity.inc
+++ b/includes/entity.inc
@@ -98,7 +98,7 @@ class Entity {
     if (isset($this->entityInfo['label callback']) && $this->entityInfo['label callback'] == 'entity_class_label') {
       return $this->defaultLabel();
     }
-    return entity_label($this->entityType, $this);
+    return entity_label($entity_type, $entity);
   }
 
   /**
diff --git a/includes/entity.property.inc b/includes/entity.property.inc
index 1e47c23..5e59a93 100644
--- a/includes/entity.property.inc
+++ b/includes/entity.property.inc
@@ -389,8 +389,6 @@ function entity_property_text_formatted_info() {
       'label' => t('Text'),
       'sanitized' => TRUE,
       'getter callback' => 'entity_metadata_field_text_get',
-      'setter callback' => 'entity_property_verbatim_set',
-      'setter permission' => 'administer nodes',
       'raw getter callback' => 'entity_property_verbatim_get',
     ),
     'summary' => array(
@@ -398,8 +396,6 @@ function entity_property_text_formatted_info() {
       'label' => t('Summary'),
       'sanitized' => TRUE,
       'getter callback' => 'entity_metadata_field_text_get',
-      'setter callback' => 'entity_property_verbatim_set',
-      'setter permission' => 'administer nodes',
       'raw getter callback' => 'entity_property_verbatim_get',
     ),
     'format' => array(
diff --git a/includes/entity.wrapper.inc b/includes/entity.wrapper.inc
index 0d90f04..28297bf 100644
--- a/includes/entity.wrapper.inc
+++ b/includes/entity.wrapper.inc
@@ -25,9 +25,9 @@ abstract class EntityMetadataWrapper {
    * @param $info
    *   Optional. Used internally to pass info about properties down the tree.
    */
-  public function __construct($type, $data = NULL, $info = array()) {
+  public function __construct($type, &$data = NULL, $info = array()) {
     $this->type = $type;
-    $this->data = $data;
+    $this->data = &$data;
     $this->info = $info + array(
       'langcode' => NULL,
     );
@@ -278,7 +278,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg
    *     data structure. It has to contain an array of property info in the same
    *     structure as used by hook_entity_property_info().
    */
-  public function __construct($type, $data = NULL, $info = array()) {
+  public function __construct($type, &$data = NULL, $info = NULL) {
     parent::__construct($type, $data, $info);
     $this->info += array('property defaults' => array());
     $info += array('property info' => array());
@@ -563,7 +563,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper {
    * @param $info
    *   Optional. Used internally to pass info about properties down the tree.
    */
-  public function __construct($type, $data = NULL, $info = array()) {
+  public function __construct($type, $data = NULL, $info = NULL) {
     parent::__construct($type, $data, $info);
     $this->setEntity($data);
     $this->setUp();
diff --git a/modules/callbacks.inc b/modules/callbacks.inc
index a1699a0..7b6b3bb 100644
--- a/modules/callbacks.inc
+++ b/modules/callbacks.inc
@@ -52,8 +52,7 @@ function entity_metadata_comment_get_properties($comment, array $options, $name)
       if (!empty($comment->pid)) {
         return $comment->pid;
       }
-      // There is no parent comment.
-      return NULL;
+      throw new EntityMetadataWrapperException('This comment has no parent comment.');
 
     case 'author':
       return $comment->uid;
@@ -153,8 +152,7 @@ function entity_metadata_poll_node_get_properties($node, array $options, $name)
     return $total_votes;
   }
   elseif (!isset($winner)) {
-    // There is no poll winner yet.
-    return NULL;
+    throw new EntityMetadataWrapperException('There is no poll winner yet.');
   }
   switch ($name) {
     case 'poll_winner_votes':
@@ -660,10 +658,6 @@ function entity_metadata_create_node($values = array()) {
   foreach (array('status', 'promote', 'sticky') as $key) {
     $node->$key = (int) in_array($key, $node_options);
   }
-  if (module_exists('comment') && !isset($node->comment)) {
-    $node->comment = variable_get("comment_$node->type", COMMENT_NODE_OPEN);
-  }
-  // Apply the given values.
   foreach ($values as $key => $value) {
     $node->$key = $value;
   }
diff --git a/modules/field.info.inc b/modules/field.info.inc
index 3e18c00..047c557 100644
--- a/modules/field.info.inc
+++ b/modules/field.info.inc
@@ -116,11 +116,7 @@ function entity_metadata_field_term_reference_callback(&$info, $entity_type, $fi
     $settings = reset($field['settings']['allowed_values']);
     $property['bundle'] = $settings['vocabulary'];
   }
-  // Only add the options list callback for controlled vocabularies, thus
-  // vocabularies not using the autocomplete widget.
-  if ($instance['widget']['type'] != 'taxonomy_autocomplete') {
-    $property['options list'] = 'entity_metadata_field_options_list';
-  }
+  $property['options list'] = 'entity_metadata_field_options_list';
   unset($property['query callback']);
 }
 
diff --git a/modules/node.info.inc b/modules/node.info.inc
index e8d53a5..44f3a92 100644
--- a/modules/node.info.inc
+++ b/modules/node.info.inc
@@ -153,7 +153,6 @@ function entity_metadata_node_entity_property_info_alter(&$info) {
     'getter callback' => 'entity_metadata_field_verbatim_get',
     'setter callback' => 'entity_metadata_field_verbatim_set',
     'property info' => entity_property_text_formatted_info(),
-    'auto creation' => 'entity_property_create_array',
     'field' => TRUE,
   );
 }
diff --git a/tests/entity_feature.info b/tests/entity_feature.info
index 03e37ce..f0ce2bb 100644
--- a/tests/entity_feature.info
+++ b/tests/entity_feature.info
@@ -5,3 +5,10 @@ core = 7.x
 files[] = entity_feature.module
 dependencies[] = entity_test
 hidden = TRUE
+
+; Information added by drupal.org packaging script on 2011-03-21
+version = "7.x-1.0-beta8"
+core = "7.x"
+project = "entity"
+datestamp = "1300731067"
+
diff --git a/tests/entity_test.info b/tests/entity_test.info
index a6ad0b6..0b77014 100644
--- a/tests/entity_test.info
+++ b/tests/entity_test.info
@@ -6,3 +6,10 @@ files[] = entity_test.module
 files[] = entity_test.install
 dependencies[] = entity
 hidden = TRUE
+
+; Information added by drupal.org packaging script on 2011-03-21
+version = "7.x-1.0-beta8"
+core = "7.x"
+project = "entity"
+datestamp = "1300731067"
+
diff --git a/tests/entity_test.install b/tests/entity_test.install
index 55ce574..0869158 100644
--- a/tests/entity_test.install
+++ b/tests/entity_test.install
@@ -112,22 +112,7 @@ function entity_test_schema() {
         'description' => 'A serialized array of additional data related to this entity_test type.',
         'merge' => TRUE,
       ),
-      'status' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        // Set the default to ENTITY_CUSTOM without using the constant as it is
-        // not safe to use it at this point.
-        'default' => 0x01,
-        'size' => 'tiny',
-        'description' => 'The exportable status of the entity.',
-      ),
-      'module' => array(
-        'description' => 'The name of the providing module if the entity has been defined in code.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => FALSE,
-      ),
-    ),
+    ) + entity_exportable_schema_fields(),
     'primary key' => array('id'),
     'unique keys' => array(
       'name' => array('name'),
diff --git a/views/entity.views.inc b/views/entity.views.inc
index 30bfedd..99f5cdb 100644
--- a/views/entity.views.inc
+++ b/views/entity.views.inc
@@ -20,7 +20,7 @@ function entity_views_data() {
       $controller = new $info['views controller class']($type);
       // Relationship data may return views data for already existing tables,
       // so merge results on the second level.
-      foreach ($controller->views_data() as $table => $table_data) {
+      foreach ($controller->viewsData() as $table => $table_data) {
         $data += array($table => array());
         $data[$table] = array_merge($data[$table], $table_data);
       }
@@ -31,6 +31,32 @@ function entity_views_data() {
 }
 
 /**
+ * Implements hook_views_plugins().
+ */
+function entity_views_plugins() {
+  foreach (views_fetch_data() as $table => $data) {
+    if (!empty($data['table']['base']['entity type'])) {
+      $base_tables[] = $table;
+    }
+  }
+  if (!empty($base_tables)) {
+    return array(
+      'row' => array(
+        'entity_row_view' => array(
+          'title' => t('Entity view'),
+          'help' => t('Displays a single entity in a specific view mode (e.g. teaser).'),
+          'handler' => 'EntityViewsRowView',
+          'uses fields' => FALSE,
+          'uses options' => TRUE,
+          'type' => 'normal',
+          'base' => $base_tables,
+        ),
+      ),
+    );
+  }
+}
+
+/**
  * Default controller for generating basic views integration.
  *
  * The controller tries to generate suiting views integration for the entity
@@ -52,65 +78,50 @@ class EntityDefaultViewsController {
   /**
    * Defines the result for hook_views_data().
    */
-  public function views_data() {
+  public function viewsData() {
     $data = array();
     $this->relationships = array();
 
     if (!empty($this->info['base table'])) {
       $table = $this->info['base table'];
+      $schema = drupal_get_schema($this->info['base table']);
+      $properties = entity_get_property_info($this->type);
       // Define the base group of this table. Fields that don't
       // have a group defined will go into this field by default.
       $data[$table]['table']['group']  = drupal_ucfirst($this->info['label']);
-
       $data[$table]['table']['base'] = array(
         'field' => $this->info['entity keys']['id'],
         'title' => drupal_ucfirst($this->info['label']),
         // @todo: Support an entity info description key or such?
         'help' => '',
+        'entity type' => $this->type,
       );
-      $data[$table] += $this->schema_fields();
 
-      // Add in any reverse-relationships which have been determined.
-      $data += $this->relationships;
-    }
-    return $data;
-  }
-
-  /**
-   * Try to come up with some views fields with the help of the schema and
-   * the entity property information.
-   */
-  protected function schema_fields() {
-    $schema = drupal_get_schema($this->info['base table']);
-    $properties = entity_get_property_info($this->type);
-    $data = array();
-
-    foreach ($properties['properties'] as $name => $property_info) {
-      // For backward compatibility, also read from 'views field'.
-      $views_field_name = isset($property_info['schema field']) ? $property_info['schema field'] : (isset($property_info['views field']) ? $property_info['views field'] : $name);
-
-      if (isset($schema['fields'][$views_field_name])) {
-        if ($views_info = $this->map_from_schema_info($views_field_name, $schema['fields'][$views_field_name], $property_info)) {
-          $data[$name] = $views_info + array(
+      foreach ($properties['properties'] as $name => $property_info) {
+        // For backward compatibility, also read from 'views field'.
+        $views_field_name = isset($property_info['schema field']) ? $property_info['schema field'] : (isset($property_info['views field']) ? $property_info['views field'] : $name);
+        $schema_field_info = isset($schema['fields'][$views_field_name]) ? $schema['fields'][$views_field_name] : array();
+        if ($views_info = $this->mapHandlers($views_field_name, $property_info, $schema_field_info)) {
+          $data[$table][$name] = $views_info + array(
             'title' => $property_info['label'],
             'help' => $property_info['description'],
           );
         }
       }
+      // Add in any reverse-relationships which have been determined.
+      $data += $this->relationships;
     }
     return $data;
   }
 
   /**
-   * Comes up with views information based on the given schema and property
-   * info.
+   * Generates views data based on property info, and schema (if provided).
    */
-  protected function map_from_schema_info($views_field_name, $schema_field_info, $property_info) {
+  protected function mapHandlers($views_field_name, $property_info, $schema_field_info) {
     $type = isset($property_info['type']) ? $property_info['type'] : 'text';
 
     // Add in relationships to related entities.
     if (($info = entity_get_info($type)) && !empty($info['base table'])) {
-
       // Prepare reversed relationship data.
       $label_lowercase = drupal_strtolower($this->info['label'][0]) . drupal_substr($this->info['label'], 1);
       $property_label_lowercase = drupal_strtolower($property_info['label'][0]) . drupal_substr($property_info['label'], 1);
@@ -138,66 +149,132 @@ class EntityDefaultViewsController {
       );
     }
 
-    if (!empty($schema_field_info['serialize'])) {
-      return FALSE;
+    // Does the property map to a column in the database?
+    if (!empty($schema_field_info)) {
+      if (!empty($schema_field_info['serialize'])) {
+        return FALSE;
+      }
+      $handlers = $this->mapFromSchema($type, $views_field_name);
+    }
+    else {
+      $handlers = $this->mapFromProperty($type, $views_field_name);
     }
 
+    // Allow developers to override the generated views data through the
+    // property info of a given property.
+    if (!empty($property_info['views handlers'])) {
+      foreach ((array) $property_info['views handlers'] as $type => $data) {
+        // Allow developers to unset certain handlers by passing an empty value.
+        // For example, 'argument' => NULL would disable the argument for that
+        // property value.
+        if (empty($data)) {
+          unset($handlers[$type]);
+        }
+        // Go through all values and override handler values with matching keys.
+        foreach ((array) $data as $key => $value) {
+          $handlers[$type][$key] = $value;
+        }
+      }
+    }
+
+    return $handlers;
+  }
+
+  /**
+   * Returns the views data for a property that maps to a column in the
+   * database (allowing it to have arguments, filters and sorts).
+   */
+  protected function mapFromSchema($type, $views_field_name) {
     switch ($type) {
+      case 'boolean':
+        $field_handler = 'views_handler_field_boolean';
+        $sort_handler = 'views_handler_sort';
+        $filter_handler = 'views_handler_filter_boolean_operator';
+        break;
       case 'token':
       case 'text':
-        return array(
-          'field' => array(
-            'field' => $views_field_name,
-            'handler' => 'views_handler_field',
-            'click sortable' => TRUE,
-           ),
-          'sort' => array(
-            'handler' => 'views_handler_sort',
-          ),
-          'filter' => array(
-            'handler' => 'views_handler_filter_string',
-          ),
-          'argument' => array(
-            'handler' => 'views_handler_argument_string',
-          ),
-        );
-
+        $field_handler = 'views_handler_field';
+        $sort_handler = 'views_handler_sort';
+        $filter_handler = 'views_handler_filter_string';
+        $argument_handler = 'views_handler_argument_string';
+        break;
       case 'decimal':
       case 'integer':
-        return array(
-          'field' => array(
-            'field' => $views_field_name,
-            'handler' => 'views_handler_field_numeric',
-            'click sortable' => TRUE,
-           ),
-          'sort' => array(
-            'handler' => 'views_handler_sort',
-          ),
-          'filter' => array(
-            'handler' => 'views_handler_filter_numeric',
-          ),
-          'argument' => array(
-            'handler' => 'views_handler_argument_numeric',
-          ),
-        );
+        $field_handler = 'views_handler_field_numeric';
+        $sort_handler = 'views_handler_sort';
+        $filter_handler = 'views_handler_filter_numeric';
+        $argument_handler = 'views_handler_argument_numeric';
+        break;
+      case 'date':
+        $field_handler = 'views_handler_field_date';
+        $sort_handler = 'views_handler_sort_date';
+        $filter_handler = 'views_handler_filter_date';
+        $argument_handler = 'views_handler_argument_date';
+        break;
+    }
+
+    $handlers = array(
+      'field' => array(
+        'field' => $views_field_name,
+        'handler' => $field_handler,
+        'click sortable' => TRUE,
+       ),
+    );
+    // Sort/filter/argument handlers are optional and might not be present.
+    if (isset($sort_handler)) {
+      $handlers['sort'] = array(
+        'handler' => $sort_handler,
+      );
+    }
+    if (isset($filter_handler)) {
+      $handlers['filter'] = array(
+        'handler' => $filter_handler,
+      );
+    }
+    if (isset($argument_handler)) {
+      $handlers['argument'] = array(
+        'handler' => $argument_handler,
+      );
+    }
+    return $handlers;
+  }
 
+  /**
+   * Returns the views data for a property that doesn't map to a column in the
+   * database (meaning it can't have arguments, filters and sorts).
+   */
+  protected function mapFromProperty($type, $views_field_name) {
+    switch ($type) {
+      case 'boolean':
+        $field_handler = 'entity_handler_field_property_boolean';
+        break;
       case 'date':
-        return array(
-          'field' => array(
-            'field' => $views_field_name,
-            'handler' => 'views_handler_field_date',
-            'click sortable' => TRUE,
-           ),
-          'sort' => array(
-            'handler' => 'views_handler_sort_date',
-          ),
-          'filter' => array(
-            'handler' => 'views_handler_filter_date',
-          ),
-          'argument' => array(
-            'handler' => 'views_handler_argument_date',
-          ),
-        );
+        $field_handler = 'entity_handler_field_property_date';
+        break;
+      case 'decimal':
+      case 'integer':
+        $field_handler = 'entity_handler_field_property_numeric';
+        break;
+      case 'uri':
+        $field_handler = 'entity_handler_field_property_uri';
+        break;
+      case 'token':
+      case 'text':
+        $field_handler = 'entity_handler_field_property_string';
+        break;
+      default:
+        // Unsupported property type.
+        return array();
     }
+
+    $handlers = array(
+      'field' => array(
+        'field' => $views_field_name,
+        'handler' => $field_handler,
+        'click sortable' => FALSE,
+        'entity type' => $this->type,
+       ),
+    );
+    return $handlers;
   }
 }
