diff --git a/modules/crm_core_activity/crm_core_activity.controller.inc b/modules/crm_core_activity/crm_core_activity.controller.inc
new file mode 100644
index 0000000..47aaf83
--- /dev/null
+++ b/modules/crm_core_activity/crm_core_activity.controller.inc
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * CRM Activity Entity Class.
+ */
+class CRMCoreActivityEntity extends Entity {
+  protected function defaultLabel() {
+    return $this->title;
+  }
+
+  protected function defaultUri() {
+    return array(
+      'path' => 'crm/activity/' . $this->identifier(),
+      'options' => array(
+        'absolute' => TRUE,
+      ),
+    );
+  }
+}
+
+/**
+ * Controller class for CRM Activity.
+ */
+class CRMCoreActivityController extends EntityAPIController {
+  public function create(array $values = array()) {
+    global $user;
+    $values += array(
+      'title' => '',
+      'created' => REQUEST_TIME,
+      'changed' => REQUEST_TIME,
+      'uid' => $user->uid,
+    );
+
+    return parent::create($values);
+  }
+}
+
+/**
+ * Use a separate class for profile types so we can specify some defaults
+ * modules may alter.
+ */
+class CRMActivityType extends Entity {
+  public $type;
+  public $label;
+  public $weight = 0;
+
+  public function __construct($values = array()) {
+    parent::__construct($values, 'crm_core_activity_type');
+  }
+
+  function isLocked() {
+    return isset($this->status) && empty($this->is_new) && (($this->status & ENTITY_IN_CODE) || ($this->status & ENTITY_FIXED));
+  }
+}
+
+/**
+ * Controller class for CRM Activity Type.
+ */
+class CRMCoreActivityTypeController extends EntityAPIControllerExportable {
+  public function create(array $values = array()) {
+    $values += array(
+      'type' => '',
+      'label' => '',
+      'description' => '',
+      'is_new' => TRUE,
+    );
+
+    return parent::create($values);
+  }
+}
diff --git a/modules/crm_core_activity/crm_core_activity.info b/modules/crm_core_activity/crm_core_activity.info
index a23fcbc..69e4559 100644
--- a/modules/crm_core_activity/crm_core_activity.info
+++ b/modules/crm_core_activity/crm_core_activity.info
@@ -25,19 +25,7 @@ dependencies[] = date_views
 ; Module Files
 ; =======================
 
-; Base Files
-files[] = crm_core_activity.module
-files[] = crm_core_activity.install
-files[] = crm_core_activity.admin.inc
-
-; Fields
-files[] = crm_core_activity.fields.inc
-
-; Module includes
-;files[] = includes/crm_contact.controller.inc
-
-; Views include
-;files[] = views/crm_core_activity.views.inc
+files[] = crm_core_activity.controller.inc
 
 ; Views handlers
 files[] = views/handlers/crm_core_activity_handler_field_links.inc
diff --git a/modules/crm_core_activity/crm_core_activity.install b/modules/crm_core_activity/crm_core_activity.install
index b212cea..938a954 100644
--- a/modules/crm_core_activity/crm_core_activity.install
+++ b/modules/crm_core_activity/crm_core_activity.install
@@ -2,36 +2,36 @@
 
 /**
  * Implements hook_install()
- */ 
+ */
 function crm_core_activity_install() {
-  
+
   // create a default meeting activity type
-  $meeting = crm_core_activity_type_new();
-  $meeting->type = 'meeting';
-  $meeting->label = t('Meeting');
-  $meeting->description = t('A meeting between 2 or more contacts');
-  $meeting->is_new = TRUE;
+  $meeting = entity_create('crm_core_activity_type', array(
+    'type' => 'meeting',
+    'label' => t('Meeting'),
+    'description' => t('A meeting between 2 or more contacts'),
+  ));
   crm_core_activity_type_save($meeting);
-  
+
   // create a phone call activity type
-  $phone_call = crm_core_activity_type_new();
-  $phone_call->type = 'phone_call';
-  $phone_call->label = t('Phone call');
-  $phone_call->description = t('A phone call between 2 or more contacts');
-  $phone_call->is_new = TRUE;
+  $phone_call = entity_create('crm_core_activity_type', array(
+    'type' => 'phone_call',
+    'label' => t('Phone call'),
+    'description' => t('A phone call between 2 or more contacts'),
+  ));
   crm_core_activity_type_save($phone_call);
 }
 
 function crm_core_activity_uninstall() {
 
   // delete all the fields
-  // right now we only have the default fields, what if we can add more fields to the 
+  // right now we only have the default fields, what if we can add more fields to the
   // activities? (we will need to go through the field array and idenfity activity fields?)
   module_load_include('inc', 'crm_core_activity', 'crm_core_activity.fields');
   foreach (_crm_core_activity_type_default_fields() as $field) {
     field_delete_field($field['field_name']);
   }
-  
+
 }
 
 /**
@@ -49,13 +49,6 @@ function crm_core_activity_schema() {
         'unsigned' => TRUE,
         'not null' => TRUE,
       ),
-//      'revision_id' => array(
-//        'description' => 'The current {crm_core_activity_revision}.revision_id version identifier.',
-//        'type' => 'int',
-//        'unsigned' => TRUE,
-//        'not null' => TRUE,
-//        'default' => 0,
-//      ),
       'type' => array(
         'description' => 'The type (bundle) of this activity.',
         'type' => 'varchar',
@@ -89,76 +82,7 @@ function crm_core_activity_schema() {
       ),
     ),
     'primary key' => array('activity_id'),
-//    'unique keys' => array(
-//      'revision_id' => array('revision_id'),
-//    ),
-//    'foreign keys' => array(
-//      'current_revision' => array(
-//        'table' => 'crm_core_activity_revision',
-//        'columns'=> array('revision_id' => 'revision_id'),
-//      ),
-//    ),
   );
-//  $schema['crm_core_activity_revision'] = array(
-//    'description' => 'Saves information about each saved revision of a {crm_core_activity}.',
-//    'fields' => array(
-//      'revision_id' => array(
-//        'description' => 'The current {crm_core_activity_revision}.revision_id version identifier.',
-//        'type' => 'serial',
-//        'unsigned' => TRUE,
-//        'not null' => TRUE,
-//      ),
-//      'activity_id' => array(
-//        'description' => 'The primary identifier for an activity.',
-//        'type' => 'int',
-//        'unsigned' => TRUE,
-//        'not null' => TRUE,
-//        'default' => 0,
-//      ),
-//      'log' => array(
-//        'description' => 'The log entry explaining the changes in this version.',
-//        'type' => 'text',
-//        'not null' => TRUE,
-//        'size' => 'big',
-//      ),
-//      'uid' => array(
-//        'description' => 'The {users}.uid that owns this activity.',
-//        'type' => 'int',
-//        'not null' => TRUE,
-//        'default' => 0,
-//      ),
-//      'title' => array(
-//        'description' => 'The title of the activity.',
-//        'type' => 'varchar',
-//        'length' => 255,
-//        'not null' => TRUE,
-//        'default' => '',
-//      ),
-//      'created' => array(
-//        'description' => 'The Unix timestamp when the activity was created.',
-//        'type' => 'int',
-//        'not null' => TRUE,
-//        'default' => 0,
-//      ),
-//      'changed' => array(
-//        'description' => 'The Unix timestamp when the activity was most recently saved.',
-//        'type' => 'int',
-//        'not null' => TRUE,
-//        'default' => 0,
-//      ),
-//    ),
-//    'foreign keys' => array(
-//      'versioned_contact' => array(
-//        'table' => 'crm_core_activity',
-//        'columns' => array('activity_id' => 'activity_id'),
-//      ),
-//      'version_creator' => array(
-//        'table' => 'user',
-//        'columns' => array('uid' => 'uid'),
-//      ),
-//    ),
-//    'primary key' => array('revision_id'),
-//  );
 
   $schema['crm_core_activity_type'] = array(
     'description' => 'Stores information about all defined activity types.',
diff --git a/modules/crm_core_activity/crm_core_activity.module b/modules/crm_core_activity/crm_core_activity.module
index c6a96da..6d29505 100644
--- a/modules/crm_core_activity/crm_core_activity.module
+++ b/modules/crm_core_activity/crm_core_activity.module
@@ -12,16 +12,14 @@ function crm_core_activity_entity_info() {
   $return = array(
     'crm_core_activity' => array(
       'label' => t('Activity'),
-      'entity class' => 'Entity',
-      'controller class' => 'EntityAPIController',
+      'entity class' => 'CRMCoreActivityEntity',
+      'controller class' => 'CRMCoreActivityController',
       'base table' => 'crm_core_activity',
       'access callback' => 'crm_core_activity_access',
-//      'revision table' => 'crm_activity_revision',
       'fieldable' => TRUE,
       'entity keys' => array(
         'id' => 'activity_id',
         'bundle' => 'type',
-//        'revision' => 'revision_id',
       ),
       'bundle keys' => array(
         'bundle' => 'type',
@@ -34,8 +32,8 @@ function crm_core_activity_entity_info() {
           'custom settings' => FALSE,
         ),
       ),
-      'label callback' => 'crm_core_activity_label',
-      'uri callback' => 'crm_core_activity_uri',
+      'label callback' => 'entity_class_label',
+      'uri callback' => 'entity_class_uri',
       'module' => 'crm_core_activity',
       'permission labels' => array(
         'singular' => t('activity'),
@@ -46,7 +44,7 @@ function crm_core_activity_entity_info() {
   $return['crm_core_activity_type'] = array(
     'label' => t('Activity Type'),
     'entity class' => 'CRMActivityType',
-    'controller class' => 'EntityAPIControllerExportable',
+    'controller class' => 'CRMCoreActivityTypeController',
     'base table' => 'crm_core_activity_type',
     'fieldable' => FALSE,
     'bundle of' => 'crm_core_activity',
@@ -61,10 +59,9 @@ function crm_core_activity_entity_info() {
     'admin ui' => array(
       'path' => 'admin/structure/crm/activity-types',
       'file' => 'crm_core_activity.admin.inc',
-      'controller class' => 'CRMActivityTypeUIController',
+      'controller class' => 'EntityDefaultUIController',
     ),
     'access callback' => 'crm_core_activity_type_access',
-    'access arguments' => array('administer activity types'),
   );
 
   return $return;
@@ -84,157 +81,12 @@ function crm_core_activity_entity_info_alter(&$entity_info) {
         'path' => 'admin/structure/crm/activity-types/manage/%crm_core_activity_type',
         'real path' => 'admin/structure/crm/activity-types/manage/' . $type,
         'bundle argument' => 5,
-        // TODO write proper hook_permissions and set proper access callback here.
-        'access callback' => TRUE,
-        'access arguments' => array('administer crm_core_activity types'),
       ),
     );
   }
 }
 
 /**
- * Implements hook_search_info().
- */
-function crm_core_activity_search_info() {
-  return array(
-    'title' => 'Activities', 
-    'path' => 'activity',
-  );
-}
-
-/**
- * Implements hook_search_access().
- */
-function crm_core_activity_search_access() {
-  return user_access('administer crm_core_activity entities') || user_access('view any crm_core_activity entity');
-}
-
-/**
- * Implements hook_search_reset().
- */
-function crm_core_activity_search_reset() {
-  db_update('search_dataset')
-    ->fields(array('reindex' => REQUEST_TIME))
-    ->condition('type', 'crm_core_activity')
-    ->execute();
-}
-
-/**
- * Implements hook_search_status().
- */
-function crm_core_activity_search_status() {
-  $total = db_query('SELECT COUNT(*) FROM {crm_core_activity}')->fetchField();
-  $remaining = db_query("SELECT COUNT(*) FROM {crm_core_activity} a LEFT JOIN {search_dataset} d ON d.type = 'crm_core_activity' AND d.sid = a.activity_id WHERE d.sid IS NULL OR d.reindex <> 0")->fetchField();
-  return array('remaining' => $remaining, 'total' => $total);
-}
-
-/**
- * Implements hook_search_execute().
- */
-function crm_core_activity_search_execute($keys = NULL, $conditions = NULL) {
-  // Build matching conditions
-
-  $query = db_select('search_index', 'i', array('target' => 'slave'))->extend('SearchQuery')->extend('PagerDefault');
-  $query->join('crm_core_activity', 'a', 'a.activity_id = i.sid');
-  $query->searchExpression($keys, 'crm_core_activity');
-
-  // Insert special keywords.
-  $query->setOption('type', 'a.type');
-  $query->setOption('language', 'a.language');
-
-  // Only continue if the first pass query matches.
-  if (!$query->executeFirstPass()) {
-    return array();
-  }
-
-  // Load results.
-  $find = $query
-    ->limit(10)
-    ->execute();
-  $results = array();
-  foreach ($find as $item) {
-    // Render the contact.
-    $activity = crm_core_activity_load($item->sid);
-    $build = crm_core_activity_view($activity);
-    unset($build['#theme']);
-    $activity->rendered = drupal_render($build);
-    $uri = entity_uri('crm_core_activity', $activity);
-    $results[] = array(
-      'link' => url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE))),
-      'type' => check_plain(crm_core_activity_type_get_name($activity->type)),
-      'title' => check_plain($activity->title),
-      'user' => theme('username', array('account' => user_load($activity->uid))),
-      'date' => $activity->changed,
-      'contact' => $activity,
-      'score' => $item->calculated_score,
-      'snippet' => search_excerpt($keys, $activity->rendered),
-      'language' => (isset($activity->language)) ? $activity->language : LANGUAGE_NONE,
-    );
-  }
-  return $results;
-}
-
-/**
- * Search condition callback.
- */
-  function crm_core_activity_search_conditions_callback($keys) {
-  $conditions = array();
-
-  if (!empty($_REQUEST['keys'])) {
-    $conditions['keys'] = $_REQUEST['keys'];
-  }
-  if (!empty($_REQUEST['sample_search_keys'])) {
-    $conditions['sample_search_keys'] = $_REQUEST['sample_search_keys'];
-  }
-  if ($force_keys = variable_get('sample_search_force_keywords', '')) {
-    $conditions['sample_search_force_keywords'] = $force_keys;
-  }
-  return $conditions;
-}
-
-/**
- * Implements hook_update_index().
- */
-function crm_core_activity_update_index() {
-  $limit = (int) variable_get('search_cron_limit', 100);
-
-  $result = db_query_range("SELECT a.activity_id FROM {crm_core_activity} a LEFT JOIN {search_dataset} d ON d.type = 'crm_core_activity' AND d.sid = a.activity_id WHERE d.sid IS NULL OR d.reindex <> 0 ORDER BY d.reindex ASC, a.activity_id ASC", 0, $limit);
-
-  foreach ($result as $activity) {
-    $activity = crm_core_activity_load($activity->activity_id);
-    variable_set('crm_core_activity_cron_last', $activity->changed);
-
-    // Render the activity.
-    $text = drupal_render(crm_core_activity_view($activity));
-    // Update index
-    search_index($activity->activity_id, 'crm_core_activity', $text);
-  }
-}
-
-/**
- * Implements hook_crm_core_contact_delete.
- */
-function crm_core_activity_crm_core_contact_delete($crm_core_contact) {
-
-  // query the activities that belongs to the contact
-  // @todo for activities involving other contacts, it might be wise to just
-  // delete the contact from the participant list?
-  $query = new EntityFieldQuery;
-  $results = $query
-    ->entityCondition('entity_type', 'crm_core_activity')
-    ->fieldCondition('field_activity_participants', 'target_id', $crm_core_contact->contact_id, '=')
-    ->fieldCondition('field_activity_participants', 'target_type', 'crm_core_contact', '=')
-    ->execute();
-
-  if(empty($results)) {
-    return;
-  }
-  foreach($results['crm_core_activity'] as $crm_core_activity) {
-    crm_core_activity_delete($crm_core_activity);
-  }
-}
-
-/**
  * Implements hook_permission().
  */
 function crm_core_activity_permission() {
@@ -252,37 +104,48 @@ function crm_core_activity_permission() {
 }
 
 /**
- * Use a separate class for profile types so we can specify some defaults
- * modules may alter.
+ * Access callback for activity.
  */
-class CRMActivityType extends Entity {
-  public $type;
-  public $label;
-  public $weight = 0;
+function crm_core_activity_access($op, $activity, $account = NULL, $entity_type = NULL) {
+  global $user;
 
-  public function __construct($values = array()) {
-    parent::__construct($values, 'crm_core_activity_type');
+  if (!isset($account)) {
+    $account = $user;
   }
-
-  function isLocked() {
-    return isset($this->status) && empty($this->is_new) && (($this->status & ENTITY_IN_CODE) || ($this->status & ENTITY_FIXED));
+  if (is_object($activity)) {
+    $activity_type = $activity->type;
+  }
+  else {
+    $activity_type = $activity;
+  }
+  switch ($op) {
+    case 'create':
+      return (user_access('administer crm_core_activity entities', $account)
+       || user_access('create crm_core_activity entities', $account)
+       || user_access('create crm_core_activity entities of bundle ' . $activity_type, $account));
+    case 'view':
+      return (user_access('administer crm_core_activity entities', $account)
+       || user_access('view any crm_core_activity entity', $account)
+       || user_access('view any crm_core_activity entity of bundle ' . $activity_type, $account));
+    case 'edit':
+    case 'update':
+      return (user_access('administer crm_core_activity entities', $account)
+       || user_access('edit any crm_core_activity entity', $account)
+       || user_access('edit any crm_core_activity entity of bundle ' . $activity_type));
   }
 }
 
 /**
- * UI controller for CRM Activity Type.
+ * Activity type access callback.
  */
-class CRMActivityTypeUIController extends EntityDefaultUIController {
-  /**
-   * Overrides hook_menu() defaults.
-   */
-  public function hook_menu() {
-    $items = parent::hook_menu();
-    $items[$this->path]['description'] = 'Manage activity types.';
-    return $items;
-  }
+function crm_core_activity_type_access() {
+  return user_access('administer activity types');
 }
 
+/*******************************************************************************
+ ********************** CRM Activity helpers ***********************************
+ ******************************************************************************/
+
 /**
  * Load a CRM Activity object.
  */
@@ -299,21 +162,6 @@ function crm_core_activity_load_multiple($activity_ids = array(), $conditions =
 }
 
 /**
- * Create new activity object.
- *   Wrapper for controller.
- *
- * @param array $values
- *   Keyed array of new object attribures.
- *
- * @return object crm_core_activity entity
- *
- * @see entity_create()
- */
-function crm_core_activity_create($values) {
-  return new Entity($values, 'crm_core_activity');
-}
-
-/**
  * Save single activity object to db.
  *   Wrapper for controller.
  *
@@ -332,9 +180,6 @@ function crm_core_activity_save($activity) {
  */
 function crm_core_activity_delete($activity) {
   crm_core_activity_delete_multiple(array($activity->activity_id));
-  // create a hook for deleting an activity
-  module_invoke_all('crm_core_activity_delete', $activity);
-  field_attach_delete('crm_core_activity', $activity);
 }
 
 /**
@@ -348,9 +193,9 @@ function crm_core_activity_delete_multiple($activity_ids) {
   entity_get_controller('crm_core_activity')->delete($activity_ids);
 }
 
-/**
- * CRM Activity Type helpers.
- */
+/*******************************************************************************
+ ********************** CRM Activity Type helpers ******************************
+ ******************************************************************************/
 
 /**
  * Load Activity Type.
@@ -393,6 +238,27 @@ function crm_core_activity_type_get_name($type_name = NULL) {
 }
 
 /**
+ * Creates or Saves an activity type
+ *
+ * @param stdClass $activity_type
+ *   The activity type info to be saved
+ *
+ */
+function crm_core_activity_type_save($activity_type) {
+  return entity_get_controller('crm_core_activity_type')->save($activity_type);
+}
+
+/**
+ * Implements hook_crm_core_activity_type_insert().
+ *
+ * Add default fields.
+ */
+function crm_core_activity_crm_core_activity_type_insert($activity_type) {
+  module_load_include('inc', 'crm_core_activity', 'crm_core_activity.admin');
+  crm_core_activity_type_add_default_fields($activity_type);
+}
+
+/**
  * Implements hook_forms().
  *
  * Create form for adding/editing crm_activity.
@@ -428,29 +294,6 @@ function crm_core_activity_view($activity) {
 }
 
 /**
- * Label callback for activity.
- *
- * Used to set title of the view activity page.
- */
-function crm_core_activity_label($activity) {
-  return $activity->title;
-}
-
-/**
- * URI callback for activity.
- *
- * Used to set uri of the activity.
- */
-function crm_core_activity_uri($activity) {
-  return array(
-    'path' => 'crm/activity/' . $activity->activity_id,
-    'options' => array(
-      'absolute' => TRUE,
-    ),
-  );
-}
-
-/**
  * Implements hook_views_api().
  */
 function crm_core_activity_views_api() {
@@ -461,113 +304,143 @@ function crm_core_activity_views_api() {
 }
 
 /**
- * Activity type access callback.
+ * Implements hook_crm_core_contact_delete.
  */
-function crm_core_activity_type_access($string) {
-  return user_access($string);
-}
+function crm_core_activity_crm_core_contact_delete($crm_core_contact) {
 
-/**
- * Access callback for activity.
- */
-function crm_core_activity_access($op, $activity, $account = NULL, $entity_type = NULL) {
-  global $user;
+  // query the activities that belongs to the contact
+  // @todo for activities involving other contacts, it might be wise to just
+  // delete the contact from the participant list?
+  $query = new EntityFieldQuery;
+  $results = $query
+    ->entityCondition('entity_type', 'crm_core_activity')
+    ->fieldCondition('field_activity_participants', 'target_id', $crm_core_contact->contact_id, '=')
+    ->fieldCondition('field_activity_participants', 'target_type', 'crm_core_contact', '=')
+    ->execute();
 
-  if (!isset($account)) {
-    $account = $user;
+  if(empty($results)) {
+    return;
   }
-  $activity_type = $activity->type;
-  switch ($op) {
-    case 'create':
-      return (user_access('administer crm_core_activity entities', $account)
-       || user_access('create crm_core_activity entities', $account)
-       || user_access('create crm_core_activity entities of bundle ' . $activity_type, $account));
-    case 'view':
-      return (user_access('administer crm_core_activity entities', $account)
-       || user_access('view any crm_core_activity entity', $account)
-       || user_access('view any crm_core_activity entity of bundle ' . $activity_type, $account));
-    case 'edit':
-    case 'update':
-      return (user_access('administer crm_core_activity entities', $account)
-       || user_access('edit any crm_core_activity entity', $account)
-       || user_access('edit any crm_core_activity entity of bundle ' . $activity_type));
+  foreach($results['crm_core_activity'] as $crm_core_activity) {
+    crm_core_activity_delete($crm_core_activity);
   }
 }
 
 /**
- * Access callback to create new activity (deprecated in favour of crm_core_activity_access).
- *
- * @param type $contact
- * @param type $activity_type
+ * Implements hook_search_info().
  */
-function crm_core_activity_create_access($contact, $activity_type) {
-  return (user_access('administer crm_core_activity entities')
-       || user_access('create crm_core_activity entities')
-       || user_access('create crm_core_activity entities of bundle ' . $activity_type));
+function crm_core_activity_search_info() {
+  return array(
+    'title' => 'Activities',
+    'path' => 'activity',
+  );
 }
 
-function crm_core_activity_view_access($activity) {
-  global $user;
-  return (user_access('administer crm_core_activity entities')
-   || user_access('view any crm_core_activity entity')
-   || user_access('view any crm_core_activity entity of bundle ' . $activity->type));
+/**
+ * Implements hook_search_access().
+ */
+function crm_core_activity_search_access() {
+  return user_access('administer crm_core_activity entities') || user_access('view any crm_core_activity entity');
 }
 
-function crm_core_activity_edit_access($activity) {
-  global $user;
-  return (user_access('administer crm_core_activity entities')
-   || user_access('edit any crm_core_activity entity')
-   || user_access('edit any crm_core_activity entity of bundle ' . $activity->type));
+/**
+ * Implements hook_search_reset().
+ */
+function crm_core_activity_search_reset() {
+  db_update('search_dataset')
+    ->fields(array('reindex' => REQUEST_TIME))
+    ->condition('type', 'crm_core_activity')
+    ->execute();
 }
 
 /**
- * Creates or Saves an activity type
- *
- * @param stdClass $activity_type
- *   The activity type info to be saved
- *
+ * Implements hook_search_status().
  */
-function crm_core_activity_type_save($activity_type) {
-
-  $op = drupal_write_record('crm_core_activity_type', $activity_type, (!$activity_type->is_new) ? 'id' : array());
+function crm_core_activity_search_status() {
+  $total = db_query('SELECT COUNT(*) FROM {crm_core_activity}')->fetchField();
+  $remaining = db_query("SELECT COUNT(*) FROM {crm_core_activity} a LEFT JOIN {search_dataset} d ON d.type = 'crm_core_activity' AND d.sid = a.activity_id WHERE d.sid IS NULL OR d.reindex <> 0")->fetchField();
+  return array('remaining' => $remaining, 'total' => $total);
+}
 
-  menu_rebuild();
+/**
+ * Implements hook_search_execute().
+ */
+function crm_core_activity_search_execute($keys = NULL, $conditions = NULL) {
+  // Build matching conditions
 
- // If this is a new activity type and the insert did not fail...
-  if ($activity_type->is_new && $op != FALSE) {
-    // Notify the field API that a new bundle has been created.
-    field_attach_create_bundle('crm_core_activity_type', $activity_type->type);
+  $query = db_select('search_index', 'i', array('target' => 'slave'))->extend('SearchQuery')->extend('PagerDefault');
+  $query->join('crm_core_activity', 'a', 'a.activity_id = i.sid');
+  $query->searchExpression($keys, 'crm_core_activity');
 
-    // Add base fields to the contact
-    /// Bug: the function is in crm_activity_admin.inc, why file not auto included
-    module_load_include('inc', 'crm_core_activity', 'crm_core_activity.admin');
-    crm_core_activity_type_add_default_fields($activity_type);
+  // Insert special keywords.
+  $query->setOption('type', 'a.type');
+  $query->setOption('language', 'a.language');
 
-    // Notify other modules that a new contact type has been created.
-    module_invoke_all('crm_core_activity_type_insert', $activity_type);
+  // Only continue if the first pass query matches.
+  if (!$query->executeFirstPass()) {
+    return array();
   }
-  else {
-    // Notify other modules that an existing contact type has been updated.
-    module_invoke_all('crm_core_activity_type_update', $activity_type);
+
+  // Load results.
+  $find = $query
+    ->limit(10)
+    ->execute();
+  $results = array();
+  foreach ($find as $item) {
+    // Render the contact.
+    $activity = crm_core_activity_load($item->sid);
+    $build = crm_core_activity_view($activity);
+    unset($build['#theme']);
+    $activity->rendered = drupal_render($build);
+    $uri = entity_uri('crm_core_activity', $activity);
+    $results[] = array(
+      'link' => url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE))),
+      'type' => check_plain(crm_core_activity_type_get_name($activity->type)),
+      'title' => check_plain($activity->title),
+      'user' => theme('username', array('account' => user_load($activity->uid))),
+      'date' => $activity->changed,
+      'contact' => $activity,
+      'score' => $item->calculated_score,
+      'snippet' => search_excerpt($keys, $activity->rendered),
+      'language' => (isset($activity->language)) ? $activity->language : LANGUAGE_NONE,
+    );
   }
+  return $results;
+}
+
+/**
+ * Search condition callback.
+ */
+  function crm_core_activity_search_conditions_callback($keys) {
+  $conditions = array();
 
-  return $op;
+  if (!empty($_REQUEST['keys'])) {
+    $conditions['keys'] = $_REQUEST['keys'];
+  }
+  if (!empty($_REQUEST['sample_search_keys'])) {
+    $conditions['sample_search_keys'] = $_REQUEST['sample_search_keys'];
+  }
+  if ($force_keys = variable_get('sample_search_force_keywords', '')) {
+    $conditions['sample_search_force_keywords'] = $force_keys;
+  }
+  return $conditions;
 }
 
 /**
- * Return a new activity type with initialize fields.
- *
- * @param string $type
- *   The machine-readable name of the contact type. (eg. Meeting)
- *
- * @return
- *   A stdClass object with activity fields
+ * Implements hook_update_index().
  */
-function crm_core_activity_type_new($type = '') {
-  return (object) array(
-    'type' => $type,
-    'label' => '',
-    'description' => '',
-    // 'help' => '',
-  );
+function crm_core_activity_update_index() {
+  $limit = (int) variable_get('search_cron_limit', 100);
+
+  $result = db_query_range("SELECT a.activity_id FROM {crm_core_activity} a LEFT JOIN {search_dataset} d ON d.type = 'crm_core_activity' AND d.sid = a.activity_id WHERE d.sid IS NULL OR d.reindex <> 0 ORDER BY d.reindex ASC, a.activity_id ASC", 0, $limit);
+
+  foreach ($result as $activity) {
+    $activity = crm_core_activity_load($activity->activity_id);
+    variable_set('crm_core_activity_cron_last', $activity->changed);
+
+    // Render the activity.
+    $text = drupal_render(crm_core_activity_view($activity));
+    // Update index
+    search_index($activity->activity_id, 'crm_core_activity', $text);
+  }
 }
diff --git a/modules/crm_core_activity_ui/crm_core_activity_ui.module b/modules/crm_core_activity_ui/crm_core_activity_ui.module
index 7f4a431..b464516 100755
--- a/modules/crm_core_activity_ui/crm_core_activity_ui.module
+++ b/modules/crm_core_activity_ui/crm_core_activity_ui.module
@@ -27,8 +27,8 @@ function crm_core_activity_ui_menu() {
       'description' => 'Add an activity to this contact',
       'page callback' => 'crm_core_activity_entity_ui_get_form_wrapper',
       'page arguments' => array(2, 5),
-      'access callback' => 'crm_core_activity_create_access',
-      'access arguments' => array(2, 5),
+      'access callback' => 'entity_access',
+      'access arguments' => array('create', 'crm_core_activity', 5),
       'type' => MENU_NORMAL_ITEM,
       'file' => 'crm_core_activity_ui.pages.inc',
     );
@@ -40,8 +40,8 @@ function crm_core_activity_ui_menu() {
     'page arguments' => array(2),
     'title callback' => 'crm_core_activity_label',
     'title arguments' => array(2),
-    'access callback' => 'crm_core_activity_view_access',
-    'access arguments' => array(2),
+    'access callback' => 'entity_access',
+    'access arguments' => array('view', 'crm_core_activity', 2),
     'type' => MENU_NORMAL_ITEM,
   );
 
@@ -56,8 +56,8 @@ function crm_core_activity_ui_menu() {
     'title' => 'Edit',
     'page callback' => 'entity_ui_get_form',
     'page arguments' => array('crm_core_activity', 2, 'edit'),
-    'access callback' => 'crm_core_activity_edit_access',
-    'access arguments' => array(2),
+    'access callback' => 'entity_access',
+    'access arguments' => array('edit', 'crm_core_activity', 2),
     'type' => MENU_LOCAL_TASK,
     'file' => 'crm_core_activity_ui.pages.inc',
   );
@@ -66,8 +66,8 @@ function crm_core_activity_ui_menu() {
     'title' => 'Delete',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('crm_core_activity_form_delete_confirm', 2),
-    'access callback' => 'crm_core_activity_edit_access',
-    'access arguments' => array(2),
+    'access callback' => 'entity_access',
+    'access arguments' => array('edit', 'crm_core_activity', 2),
     'weight' => 1,
     'type' => MENU_NORMAL_ITEM,
     'file' => 'crm_core_activity_ui.pages.inc',
@@ -119,7 +119,7 @@ function crm_core_activity_ui_admin_menu_map() {
  */
 function crm_core_activity_ui_form_alter(&$form, &$form_state, $form_id) {
   // Alter the operations links so they looks like CTools dropbutton
-  if($form_id == 'crm_core_activity_type_overview_form') {
+  if ($form_id == 'crm_core_activity_type_overview_form') {
     $ops_count = $form['table']['#header'][2]['colspan'];
     $form['table']['#header'][2] = t('Operations');
 
@@ -133,4 +133,4 @@ function crm_core_activity_ui_form_alter(&$form, &$form_state, $form_id) {
       $form['table']['#rows'][$key] = array_merge(array_slice($row, 0, count($row) - $ops_count), array($output));
     }
   }
-}
\ No newline at end of file
+}
diff --git a/modules/crm_core_activity_ui/crm_core_activity_ui.pages.inc b/modules/crm_core_activity_ui/crm_core_activity_ui.pages.inc
index 3ecc994..e3123d3 100755
--- a/modules/crm_core_activity_ui/crm_core_activity_ui.pages.inc
+++ b/modules/crm_core_activity_ui/crm_core_activity_ui.pages.inc
@@ -1,13 +1,6 @@
 <?php
 
 /**
- * A list of activities this contact has participated in.
- */
-function crm_core_contact_activity() {
-  return "This is a stub";
-}
-
-/**
  * Wrapper around entity_ui_get_form().
  *
  * Create new crm_activity entity and pass it to entity_ui_get_form().
@@ -16,11 +9,9 @@ function crm_core_contact_activity() {
  * @param type $type
  */
 function crm_core_activity_entity_ui_get_form_wrapper($contact, $type) {
-  global $user;
   // Default empty Activity.
   $values = array(
     'type' => $type,
-    'uid' => $user->uid,
     'field_activity_participants' => array(
       LANGUAGE_NONE => array(array(
           'target_id' => $contact->contact_id,
@@ -28,10 +19,9 @@ function crm_core_activity_entity_ui_get_form_wrapper($contact, $type) {
         ),
       ),
     ),
-    'title' => '',
   );
 
-  $activity = crm_core_activity_create($values);
+  $activity = entity_create('crm_core_activity', $values);
 
   return entity_ui_get_form('crm_core_activity', $activity, 'add');
 }
diff --git a/modules/crm_core_activity_ui/crm_core_activity_ui.test b/modules/crm_core_activity_ui/crm_core_activity_ui.test
index 4a084d9..643692e 100644
--- a/modules/crm_core_activity_ui/crm_core_activity_ui.test
+++ b/modules/crm_core_activity_ui/crm_core_activity_ui.test
@@ -122,6 +122,6 @@ class CRMCoreActivityUITestCase extends DrupalWebTestCase {
    * Generate random Time for form element input.
    */
   function randomTime() {
-    return rand(0, 24) . ':' . rand(0, 60);
+    return rand(0, 23) . ':' . rand(0, 60);
   }
 }
\ No newline at end of file
