diff --git a/CRM/Activity/Form/Activity.php b/CRM/Activity/Form/Activity.php
index 6378317e31080ecf4578f13ae64e0fbf44b27173..a323b8bbfce236a7a78d5be008bd95a11cfe69c0 100644
--- a/CRM/Activity/Form/Activity.php
+++ b/CRM/Activity/Form/Activity.php
@@ -842,7 +842,7 @@ class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task {
     if (!in_array($this->_activityTypeName, $specialActivities)) {
       // build tag widget
       $parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_activity');
-      CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_activity', $this->_activityId, FALSE, TRUE);
+      CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_activity', $this->_activityId, TRUE, TRUE);
     }
 
     // if we're viewing, we're assigning different buttons than for adding/editing
diff --git a/CRM/Admin/Page/AJAX.php b/CRM/Admin/Page/AJAX.php
index 582d090805b82de19baff40dfe9cb59ef9758462..16af8500cf319741007505f6f67dea9d2ec9819f 100644
--- a/CRM/Admin/Page/AJAX.php
+++ b/CRM/Admin/Page/AJAX.php
@@ -400,7 +400,7 @@ LIMIT $limit";
       if (!is_numeric($tagID)) {
         $tagID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $tagID, 'id', 'name');
       }
-      if ($entityId) {
+      if (!$skipEntityAction && $entityId) {
         // delete this tag entry for the entity
         $params = array(
           'entity_table' => $entityTable,
diff --git a/CRM/Case/Form/Case.php b/CRM/Case/Form/Case.php
index b8d4751d6b0f0b688769440e1af3a0b43f4cb322..a410b9bcce0adb7497d264454b5695d276f12fb8 100644
--- a/CRM/Case/Form/Case.php
+++ b/CRM/Case/Form/Case.php
@@ -275,7 +275,7 @@ class CRM_Case_Form_Case extends CRM_Core_Form {
 
     // build tag widget
     $parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_case');
-    CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_case', NULL, FALSE, TRUE);
+    CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_case', NULL, TRUE, TRUE);
 
     $this->addButtons(array(
         array(
diff --git a/CRM/Case/Form/CaseView.php b/CRM/Case/Form/CaseView.php
index cb9b73603d2744c252655eff64a491c539c83621..ef5335944141af4e821214b1fa1e46c45cf875ba 100644
--- a/CRM/Case/Form/CaseView.php
+++ b/CRM/Case/Form/CaseView.php
@@ -433,7 +433,12 @@ class CRM_Case_Form_CaseView extends CRM_Core_Form {
       $this->setDefaults(array('case_tag' => $tags));
 
       foreach ($tags as $tid) {
-        $tags[$tid] = $allTags[$tid];
+        if (isset($allTags[$tid])) {
+          $tags[$tid] = $allTags[$tid];
+        }
+        else {
+          unset($tags[$tid]);
+        }
       }
 
       $this->assign('tags', implode(', ', array_filter($tags)));
@@ -453,7 +458,7 @@ class CRM_Case_Form_CaseView extends CRM_Core_Form {
     else {
       $this->assign('showTagsets', FALSE);
     }
-    CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_case', $this->_caseID, FALSE, TRUE);
+    CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_case', $this->_caseID, TRUE, TRUE);
 
     $this->addButtons(array(
         array(
diff --git a/CRM/Case/Page/AJAX.php b/CRM/Case/Page/AJAX.php
index 92ce576c301868539c3c9c45ec442e99d4657020..3bfb16fdabcc5f8586b7866728405a309faae4e3 100644
--- a/CRM/Case/Page/AJAX.php
+++ b/CRM/Case/Page/AJAX.php
@@ -72,6 +72,7 @@ class CRM_Case_Page_AJAX {
 
     $caseId = CRM_Utils_Type::escape($_POST['case_id'], 'Integer');
     $tags = CRM_Utils_Type::escape($_POST['tag'], 'String');
+    $tagList = $_POST['taglist'];
 
     if (empty($caseId)) {
       echo 'false';
@@ -83,20 +84,26 @@ class CRM_Case_Page_AJAX {
       $tagIds = explode(',', $tags);
     }
 
-    $params = array(
-      'entity_id' => $caseId,
-      'entity_table' => 'civicrm_case',
-    );
+    if (!empty($tagIds)) {
+      $params = array(
+        'entity_id' => $caseId,
+        'entity_table' => 'civicrm_case',
+      );
 
-    CRM_Core_BAO_EntityTag::del($params);
+      CRM_Core_BAO_EntityTag::del($params);
 
-    foreach ($tagIds as $tagid) {
-      if (is_numeric($tagid)) {
-        $params['tag_id'] = $tagid;
-        CRM_Core_BAO_EntityTag::add($params);
+      foreach ($tagIds as $tagid) {
+        if (is_numeric($tagid)) {
+          $params['tag_id'] = $tagid;
+          CRM_Core_BAO_EntityTag::add($params);
+        }
       }
     }
 
+    if (!empty($tagList)) {
+      CRM_Core_Form_Tag::postProcess($tagList, $caseId, 'civicrm_case', CRM_Core_DAO::$_nullObject);
+    }
+
     $session = CRM_Core_Session::singleton();
 
     $activityParams = array();
diff --git a/CRM/Contact/BAO/Contact/Utils.php b/CRM/Contact/BAO/Contact/Utils.php
index dad319b3c55af0d8682a5023bd2cc54bb5bdff9c..a54925188f6f8e7d77904b375ee4280608b45d7b 100644
--- a/CRM/Contact/BAO/Contact/Utils.php
+++ b/CRM/Contact/BAO/Contact/Utils.php
@@ -989,8 +989,12 @@ Group By  componentId";
         $sql = "SELECT DISTINCT id, $idFldName FROM civicrm_contact WHERE contact_type = %1 ";
       }
       else {
-        $sql = "SELECT DISTINCT id, $idFldName FROM civicrm_contact WHERE contact_type = %1
-                     AND ( {$idFldName} IS NULL OR ( {$idFldName} IS NOT NULL AND {$displayFldName} IS NULL ) ) ";
+        $sql = "
+          SELECT DISTINCT id, $idFldName
+          FROM civicrm_contact
+          WHERE contact_type = %1
+          AND ({$idFldName} IS NULL
+          OR ( {$idFldName} IS NOT NULL AND ({$displayFldName} IS NULL OR {$displayFldName} = '')) )";
       }
 
       $dao = CRM_Core_DAO::executeQuery($sql, array(1 => array($contactType, 'String')));
diff --git a/CRM/Contact/BAO/Group.php b/CRM/Contact/BAO/Group.php
index 5fd0259a8923868a413a4b93c1493511c544b385..c9ff150ea60d27564af439cd28ea7cb3bf6914db 100644
--- a/CRM/Contact/BAO/Group.php
+++ b/CRM/Contact/BAO/Group.php
@@ -354,7 +354,8 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
     }
 
     // form the name only if missing: CRM-627
-    if (!CRM_Utils_Array::value('name', $params) &&
+    $nameParam = CRM_Utils_Array::value('name', $params, NULL);
+    if (!$nameParam &&
       !CRM_Utils_Array::value('id', $params)
     ) {
       $params['name'] = CRM_Utils_String::titleToVar($params['title']);
@@ -395,7 +396,9 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
         array_keys($group->parents)
       ) . CRM_Core_DAO::VALUE_SEPARATOR;
     }
-    if (!CRM_Utils_Array::value('id', $params)) {
+    if (!CRM_Utils_Array::value('id', $params) &&
+      !$nameParam
+    ) {
       $group->name .= "_tmp";
     }
     $group->save();
@@ -404,7 +407,9 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
       return NULL;
     }
 
-    if (!CRM_Utils_Array::value('id', $params)) {
+    if (!CRM_Utils_Array::value('id', $params) &&
+      !$nameParam
+    ) {
       $group->name = substr($group->name, 0, -4) . "_{$group->id}";
     }
 
diff --git a/CRM/Contact/Form/Edit/TagsAndGroups.php b/CRM/Contact/Form/Edit/TagsAndGroups.php
index 3726676014856cf7f6d5f6c5b45722877e60ec31..7917cc3a1d55797588b3747c44029e0c09d13502 100644
--- a/CRM/Contact/Form/Edit/TagsAndGroups.php
+++ b/CRM/Contact/Form/Edit/TagsAndGroups.php
@@ -162,7 +162,7 @@ class CRM_Contact_Form_Edit_TagsAndGroups {
       // build tag widget
       $parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_contact');
 
-      CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_contact', $contactId, FALSE, TRUE);
+      CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_contact', $contactId, TRUE, TRUE);
     }
     $form->assign('tagGroup', $form->_tagGroup);
   }
diff --git a/CRM/Contribute/Form/Contribution.php b/CRM/Contribute/Form/Contribution.php
index a8d26025a50d01b001ff550a6b7667b8451aa392..401e51e2e351a677207179df131f4b9162425943 100644
--- a/CRM/Contribute/Form/Contribution.php
+++ b/CRM/Contribute/Form/Contribution.php
@@ -920,7 +920,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
       }
     }
 
-    $softErrors = CRM_Contribute_Form_SoftCredit::formRule($fields);
+    $softErrors = CRM_Contribute_Form_SoftCredit::formRule($fields, $errors, $self);
 
     if (CRM_Utils_Array::value('total_amount', $fields) && (CRM_Utils_Array::value('net_amount', $fields) || CRM_Utils_Array::value('fee_amount', $fields))) {
       $sum = CRM_Utils_Rule::cleanMoney($fields['net_amount']) + CRM_Utils_Rule::cleanMoney($fields['fee_amount']);
diff --git a/CRM/Contribute/Form/SoftCredit.php b/CRM/Contribute/Form/SoftCredit.php
index 12b694667abd31f82000a714379a8817f08a1789..896d3dfa8b3e8cef0c6499240fc724ed1086ca11 100644
--- a/CRM/Contribute/Form/SoftCredit.php
+++ b/CRM/Contribute/Form/SoftCredit.php
@@ -142,7 +142,7 @@ class CRM_Contribute_Form_SoftCredit {
    * @access public
    * @static
    */
-  static function formRule($fields) {
+  static function formRule($fields, $errors, $self) {
     $errors = array();
 
     // if honor roll fields are populated but no PCP is selected
@@ -162,7 +162,7 @@ class CRM_Contribute_Form_SoftCredit {
           if ($repeat[$fields['soft_credit_contact_select_id'][$key]] > 1) {
             $errors["soft_credit_contact_select_id[$key]"] = ts('You cannot enter multiple soft credits for the same contact.');
           }
-          if ($fields['soft_credit_amount'][$key]
+          if ($self->_action == CRM_Core_Action::ADD && $fields['soft_credit_amount'][$key]
             && (CRM_Utils_Rule::cleanMoney($fields['soft_credit_amount'][$key]) > CRM_Utils_Rule::cleanMoney($fields['total_amount']))) {
             $errors["soft_credit_amount[$key]"] = ts('Soft credit amount cannot be more than the total amount.');
           }
diff --git a/CRM/Core/BAO/Dashboard.php b/CRM/Core/BAO/Dashboard.php
index c421f9f810e8eaee498e63faa93bf621fedb2b57..3e6f4b11c849c9f453442158bba784b9f8d8450a 100644
--- a/CRM/Core/BAO/Dashboard.php
+++ b/CRM/Core/BAO/Dashboard.php
@@ -82,10 +82,12 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
    * @access public
    * @static
    */
-  static function getContactDashlets($flatFormat = FALSE) {
+  static function getContactDashlets($flatFormat = FALSE, $contactID = NULL) {
     $dashlets = array();
 
-    $contactID = CRM_Core_Session::singleton()->get('userID');
+    if (!$contactID) {
+      $contactID = CRM_Core_Session::singleton()->get('userID');
+    }
 
     // get contact dashboard dashlets
     $hasDashlets = FALSE;
@@ -111,23 +113,42 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
     }
 
     // If empty then initialize contact dashboard for this user
-    if (!$hasDashlets) {
-      $defaultDashlets = self::getDashlets();
-      if ($defaultDashlets) {
-        // Add dashlet entries for logged in contact
-        // TODO: need to optimize this sql
-        $items = '';
-        foreach ($defaultDashlets as $key => $values) {
-          // Set civicrm blog as default enabled
-          $default = $values['url'] == 'civicrm/dashlet/blog&reset=1&snippet=5' ? 1 : 0;
-          $items .= ($items ? ', ' : '') . "($key, $contactID, $default, $default)";
+    $defaultDashlet = self::initializeDashlets($hasDashlets);
+    return $defaultDashlet ? $defaultDashlet : $dashlets;
+  }
+
+  static function initializeDashlets($hasDashlets) {
+    $getDashlets = civicrm_api3("Dashboard", "get", array('domain_id' => CRM_Core_Config::domainID()));
+    $contactID = CRM_Core_Session::singleton()->get('userID');
+
+    $allDashlets = CRM_Utils_Array::index(array('name'), $getDashlets['values']);
+    $defaultDashlets = array();
+    if (!$hasDashlets && CRM_Utils_Array::value('blog', $allDashlets)) {
+      $defaultDashlets['blog'] = array(
+        'dashboard_id' => $allDashlets['blog']['id'],
+        'is_active' => 1,
+        'column_no' => 1,
+        'contact_id' => $contactID,
+        'domain_id' => CRM_Core_Config::domainID(),
+      );
+    }
+    CRM_Utils_Hook::dashboard_defaults($allDashlets, $defaultDashlets);
+    if (is_array($defaultDashlets) && !empty($defaultDashlets)) {
+      foreach ($defaultDashlets as $defaultDashlet) {
+        if (!self::checkPermission($getDashlets['values'][$defaultDashlet['dashboard_id']]['permission'],
+                                   $getDashlets['values'][$defaultDashlet['dashboard_id']]['permission_operator'])) {
+          unset($defaultDashlets[$defaultDashlet]);
+          continue;
+        }
+        else {
+          $assignDashlets = civicrm_api3("dashboard_contact", "create", $defaultDashlet);
+          $dashlets[$defaultDashlet['dashboard_id']] = $defaultDashlet['dashboard_id'];
         }
-        $query = "INSERT INTO civicrm_dashboard_contact (dashboard_id, contact_id, column_no, is_active) VALUES $items";
-        CRM_Core_DAO::executeQuery($query);
       }
+      return $dashlets;
     }
 
-    return $dashlets;
+    return FALSE;
   }
 
   /**
@@ -216,7 +237,7 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
     $dashletInfo = array();
 
     $params = array(1 => array($dashletID, 'Integer'));
-    $query = "SELECT label, url, fullscreen_url, is_fullscreen FROM civicrm_dashboard WHERE id = %1";
+    $query = "SELECT name, label, url, fullscreen_url, is_fullscreen FROM civicrm_dashboard WHERE id = %1";
     $dashboadDAO = CRM_Core_DAO::executeQuery($query, $params);
     $dashboadDAO->fetch();
 
@@ -257,6 +278,7 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
 
     $dashletInfo = array(
       'title' => $dashboadDAO->label,
+      'name' => $dashboadDAO->name,
       'content' => $dao->content,
     );
 
@@ -280,12 +302,17 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
    * @access public
    * @static
    */
-  static function saveDashletChanges($columns) {
+  static function saveDashletChanges($columns, $contactID=NULL) {
+    $session = CRM_Core_Session::singleton();
+    if (!$contactID) {
+      $contactID = $session->get('userID');
+    }
+
     $session = CRM_Core_Session::singleton();
     $contactID = $session->get('userID');
 
     //we need to get existing dashletes, so we know when to update or insert
-    $contactDashlets = self::getContactDashlets(TRUE);
+    $contactDashlets = self::getContactDashlets(TRUE, $contactID);
 
     $dashletIDs = array();
     if (is_array($columns)) {
@@ -343,7 +370,8 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
   static function addDashlet(&$params) {
 
     // special case to handle duplicate entires for report instances
-    $dashboardID = NULL;
+    $dashboardID = CRM_Utils_Array::value('id', $params);
+
     if (CRM_Utils_Array::value('instanceURL', $params)) {
       $query = "SELECT id
                         FROM `civicrm_dashboard`
@@ -355,9 +383,14 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
 
     if (!$dashboardID) {
       // check url is same as exiting entries, if yes just update existing
-      $dashlet->url = CRM_Utils_Array::value('url', $params);
-      $dashlet->find(TRUE);
-      $dashlet->name = self::getDashletName(CRM_Utils_Array::value('instanceURL', $params));
+      if (CRM_Utils_Array::value('name', $params)) {
+        $dashlet->name = CRM_Utils_Array::value('name', $params);
+        $dashlet->find(TRUE);
+      }
+      else {
+        $dashlet->url = CRM_Utils_Array::value('url', $params);
+        $dashlet->find(TRUE);
+      }
     }
     else {
       $dashlet->id = $dashboardID;
@@ -435,6 +468,19 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
     }
   }
 
+  static function addContactDashletToDashboard(&$params) {
+    $valuesString = NULL;
+    $columns = array();
+    foreach ($params as $dashboardIDs) {
+      $contactID = CRM_Utils_Array::value('contact_id', $dashboardIDs);
+      $dashboardID = CRM_Utils_Array::value('dashboard_id', $dashboardIDs);
+      $column = CRM_Utils_Array::value('column_no', $dashboardIDs, 0);
+      $columns[$column][$dashboardID] = 0;
+    }
+    self::saveDashletChanges($columns, $contactID);
+    return TRUE;
+  }
+
   /**
    * Function to reset dashlet cache
    *
@@ -464,6 +510,7 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
     $dashlet = new CRM_Core_DAO_Dashboard();
     $dashlet->id = $dashletID;
     $dashlet->delete();
+    return TRUE;
   }
 }
 
diff --git a/CRM/Core/BAO/EntityTag.php b/CRM/Core/BAO/EntityTag.php
index 3aea6ff02cbef4b44583dc31d41a700197e86294..ed514f759ae9f6c7aa821353cb8ecb16254697e9 100644
--- a/CRM/Core/BAO/EntityTag.php
+++ b/CRM/Core/BAO/EntityTag.php
@@ -124,13 +124,11 @@ class CRM_Core_BAO_EntityTag extends CRM_Core_DAO_EntityTag {
   static function del(&$params) {
     $entityTag = new CRM_Core_BAO_EntityTag();
     $entityTag->copyValues($params);
-    if ($entityTag->find(TRUE)) {
-      $entityTag->delete();
+    $entityTag->delete();
 
-      //invoke post hook on entityTag
-      $object = array(0 => array(0 => $params['entity_id']), 1 => $params['entity_table']);
-      CRM_Utils_Hook::post('delete', 'EntityTag', $params['tag_id'], $object);
-    }
+    //invoke post hook on entityTag
+    $object = array(0 => array(0 => $params['entity_id']), 1 => $params['entity_table']);
+    CRM_Utils_Hook::post('delete', 'EntityTag', $params['tag_id'], $object);
   }
 
   /**
diff --git a/CRM/Core/BAO/File.php b/CRM/Core/BAO/File.php
index 6cf049bc9368bb3b055228992b8d57199b1874b1..a6a228f1b7712b78b37fcffb0b8a452295515cb3 100644
--- a/CRM/Core/BAO/File.php
+++ b/CRM/Core/BAO/File.php
@@ -393,7 +393,7 @@
      }
 
      // build tagset widget
-     CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_file', NULL, FALSE, TRUE, FALSE);
+     CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_file', NULL, TRUE, TRUE, FALSE);
    }
 
    /**
@@ -609,4 +609,4 @@
     return $results;
   }
 
-}
\ No newline at end of file
+}
diff --git a/CRM/Core/Form.php b/CRM/Core/Form.php
index 3319f2c4b85af57f3639d5684c563d6b5ab33405..e4e44e86d2ee33ab839b5c2df7dfb301bb172109 100644
--- a/CRM/Core/Form.php
+++ b/CRM/Core/Form.php
@@ -1280,8 +1280,14 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       // event form stores as an indexed array, contribution form not so much...
       $tempID = $this->_params[0]['select_contact_id'];
     }
+
     // force to ignore the authenticated user
-    if ($tempID === '0') {
+    if ($tempID === '0' || $tempID === 0) {
+      // we set the cid on the form so that this will be retained for the Confirm page
+      // in the multi-page form & prevent us returning the $userID when this is called
+      // from that page
+      // we don't really need to set it when $tempID is set because the params have that stored
+      $this->set('cid', 0);
       return $tempID;
     }
 
diff --git a/CRM/Core/Form/Tag.php b/CRM/Core/Form/Tag.php
index 5eeaec35b03d42d72d2424a4168dcb2b1748b2ff..cd45fd074bc4c5599818e3c6e136a28cb7946c65 100644
--- a/CRM/Core/Form/Tag.php
+++ b/CRM/Core/Form/Tag.php
@@ -226,6 +226,8 @@ class CRM_Core_Form_Tag {
     }
 
     if (!empty($tagset)) {
+      // assign current tagsets which is used in postProcess
+      $form->_tagsetInfo = $tagset;
       $form->assign("tagsetType", $mode);
       $form->assign("tagsetInfo_$mode", $tagset);
       $form->assign("isTagset", TRUE);
@@ -235,31 +237,90 @@ class CRM_Core_Form_Tag {
   /**
    * Function to save entity tags when it is not save used AJAX
    *
+   * @param array   $params      associated array
+   * @param int     $entityId    entity id, eg: contact id, activity id, case id, file id
+   * @param string  $entityTable entity table
+   * @param object  $form        form object
+   *
+   * @return void
+   * @access public
+   * @static
    */
   static function postProcess(&$params, $entityId, $entityTable = 'civicrm_contact', &$form) {
-    foreach ($params as $value) {
-      if (!$value) {
-        continue;
+    if ($form && !empty($form->_entityTagValues)) {
+      $existingTags = $form->_entityTagValues;
+    }
+    else {
+      $existingTags = CRM_Core_BAO_EntityTag::getTag($entityId, $entityTable);
+    }
+
+    if ($form) {
+      // if the key is missing from the form response then all the tags were deleted / cleared
+      // in that case we create empty tagset params so that below logic works and tagset are
+      // deleted correctly
+      foreach ($form->_tagsetInfo as $tagsetName => $tagsetInfo) {
+        $tagsetId = substr($tagsetName, strlen('parentId_'));
+        if (empty($params[$tagsetId])) {
+          $params[$tagsetId] = '';
+        }
       }
-      $tagsIDs      = explode(',', $value);
-      $insertValues = array();
-      $insertSQL    = NULL;
-      if (!empty($tagsIDs)) {
+    }
+
+    // when form is submitted with tagset values below logic will work and in the case when all tags in a tagset
+    // are deleted we will have to set $params[tagset id] = '' which is done by above logic
+    foreach ($params as $parentId => $value) {
+      $newTagIds = array();
+      $realTagIds = array();
+
+      if ($value) {
+        $tagsIDs = explode(',', $value);
         foreach ($tagsIDs as $tagId) {
-          if (is_numeric($tagId)) {
-            if ($form && $form->_action != CRM_Core_Action::UPDATE) {
-              $insertValues[] = "( {$tagId}, {$entityId}, '{$entityTable}' ) ";
-            }
-            elseif (!$form || !array_key_exists($tagId, $form->_entityTagValues)) {
-              $insertValues[] = "( {$tagId}, {$entityId}, '{$entityTable}' ) ";
+          if (!is_numeric($tagId)) {
+            // check if user has selected existing tag or is creating new tag
+            // this is done to allow numeric tags etc.
+            $tagValue = explode(':::', $tagId);
+
+            if (isset($tagValue[1]) && $tagValue[1] == 'value') {
+              $tagParams = array(
+                'name' => $tagValue[0],
+                'parent_id' => $parentId,
+              );
+              $tagObject = CRM_Core_BAO_Tag::add($tagParams, CRM_Core_DAO::$_nullArray);
+              $tagId = $tagObject->id;
             }
           }
+
+          $realTagIds[] = $tagId;
+          if ($form && $form->_action != CRM_Core_Action::UPDATE) {
+            $newTagIds[] = $tagId;
+          }
+          elseif (!array_key_exists($tagId, $existingTags)) {
+            $newTagIds[] = $tagId;
+          }
         }
+      }
+
+      // Any existing entity tags from this tagset missing from the $params should be deleted
+      $deleteSQL = "DELETE FROM civicrm_entity_tag
+                    USING civicrm_entity_tag, civicrm_tag
+                    WHERE civicrm_tag.id=civicrm_entity_tag.tag_id
+                      AND civicrm_entity_tag.entity_table='{$entityTable}'
+                      AND entity_id={$entityId} AND parent_id={$parentId}";
+      if (!empty($realTagIds)) {
+        $deleteSQL .= " AND tag_id NOT IN (" . implode(', ', $realTagIds) . ");";
+      }
+
+      CRM_Core_DAO::executeQuery($deleteSQL);
 
-        if (!empty($insertValues)) {
-          $insertSQL = 'INSERT INTO civicrm_entity_tag ( tag_id, entity_id, entity_table ) VALUES ' . implode(', ', $insertValues) . ';';
-          CRM_Core_DAO::executeQuery($insertSQL);
+      if (!empty($newTagIds)) {
+        // New tag ids can be inserted directly into the db table.
+        $insertValues = array();
+        foreach ($newTagIds as $tagId) {
+          $insertValues[] = "( {$tagId}, {$entityId}, '{$entityTable}' ) ";
         }
+        $insertSQL = 'INSERT INTO civicrm_entity_tag ( tag_id, entity_id, entity_table )
+          VALUES ' . implode(', ', $insertValues) . ';';
+        CRM_Core_DAO::executeQuery($insertSQL);
       }
     }
   }
diff --git a/CRM/Report/Form/Instance.php b/CRM/Report/Form/Instance.php
index aa0edc3577e362e7cbea00c8844364c7330eb768..48a6dd92b744ba3cf0ec7b59394add4084336010 100644
--- a/CRM/Report/Form/Instance.php
+++ b/CRM/Report/Form/Instance.php
@@ -254,7 +254,7 @@ class CRM_Report_Form_Instance {
     if (CRM_Utils_Array::value('is_navigation', $params)) {
       $params['navigation'] = $form->_navigation;
     }
-    else {
+    elseif ($instanceID){
       //delete navigation if exists
       $navId = CRM_Core_DAO::getFieldValue('CRM_Report_DAO_ReportInstance', $instanceID, 'navigation_id', 'id');
       if ($navId) {
diff --git a/CRM/Upgrade/Incremental/php/FourFour.php b/CRM/Upgrade/Incremental/php/FourFour.php
index dcfffb667456289f94e14873c1604e1a7152f54d..e27bb917e77991d0ecf15f1ba5609e70a667898d 100644
--- a/CRM/Upgrade/Incremental/php/FourFour.php
+++ b/CRM/Upgrade/Incremental/php/FourFour.php
@@ -250,18 +250,11 @@ WHERE a.id IS NULL;
     // task to process sql
     $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.4.4')), 'task_4_4_x_runSql', $rev);
 
-    // Consolidate activity contacts CRM-12274.
-    $this->addTask('Dashboard schema', 'dashboard');
-
-    return TRUE;
-  }
-
-  static function dashboard(CRM_Queue_TaskContext $ctx) {
-    $upgrade = new CRM_Upgrade_Form();
+    // CRM-13892 : add `name` column to dashboard schema
     $query = "
 ALTER TABLE civicrm_dashboard
     ADD name varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Internal name of dashlet.' AFTER domain_id ";
-    CRM_Core_DAO::executeQuery($query);
+    CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
 
     $dashboard = new CRM_Core_DAO_Dashboard();
     $dashboard->find();
@@ -286,8 +279,8 @@ ALTER TABLE civicrm_dashboard
   {$values}
   END;
     ";
+    CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
 
-    CRM_Core_DAO::executeQuery($query);
     return TRUE;
   }
 
diff --git a/CRM/Utils/Hook.php b/CRM/Utils/Hook.php
index 15ca491a2c6b28fd70c40e42f36614fc03da0c84..6e337115d910ab9706ed40403dd496e516e284a2 100644
--- a/CRM/Utils/Hook.php
+++ b/CRM/Utils/Hook.php
@@ -1394,4 +1394,14 @@ abstract class CRM_Utils_Hook {
   static function queryObjects(&$queryObjects, $type = 'Contact') {
     return self::singleton()->invoke(2, $queryObjects, $type, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_queryObjects');
   }
+
+  /**
+   * This hook is called while viewing contact dashboard
+   *
+   * @param array $availableDashlets list of dashlets; each is formatted per api/v3/Dashboard
+   * @param array $activeDashlets list of dashlets; each is formatted per api/v3/DashboardContact
+   */
+  static function dashboard_defaults($availableDashlets, &$defaultDashlets) {
+    return self::singleton()->invoke(2, $availableDashlets, $defaultDashlets, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_dashboard_defaults');
+  }
 }
diff --git a/api/v3/Dashboard.php b/api/v3/Dashboard.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae427790362077a141db29ecdd9e7afa871afa58
--- /dev/null
+++ b/api/v3/Dashboard.php
@@ -0,0 +1,107 @@
+<?php
+// $Id$
+
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.4                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2013                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * File for the CiviCRM APIv3 Dashboard functions
+ *
+ * @package CiviCRM_APIv3
+ * @subpackage API_Activity
+ * @copyright CiviCRM LLC (c) 2004-2013
+ * @version $Id: Activity.php 30486 2010-11-02 16:12:09Z shot $
+ *
+ */
+
+
+/**
+ * Creates or updates an Dashlet.
+ *
+ * @param array  $params       Associative array of property name/value
+ *                             pairs for the Dashlet.
+ *
+ * @return array Array containing 'is_error' to denote success or failure and details of the created activity
+ *
+ */
+function civicrm_api3_dashboard_create($params) {
+  if (!CRM_Utils_Array::value('id', $params)) {
+    civicrm_api3_verify_one_mandatory($params,
+      NULL,
+      array(
+        'name', 'label', 'url', 'fullscreen_url',
+      )
+    );
+  }
+  // create dashboard element
+  $dashboardBAO = CRM_Core_BAO_Dashboard::addDashlet($params);
+  if (isset($dashboardBAO->id)) {
+    _civicrm_api3_object_to_array($dashboardBAO, $dashboardArray[$dashboardBAO->id]);
+    return civicrm_api3_create_success($dashboardArray, $params, 'dashboard', 'create', $dashboardBAO);
+  }
+}
+
+/**
+ * Specify Meta data for create. Note that this data is retrievable via the getfields function
+ * and is used for pre-filling defaults and ensuring mandatory requirements are met.
+ * @param array $params (reference) array of parameters determined by getfields
+ */
+function _civicrm_api3_dashboard_create_spec(&$params) {
+  unset($params['version']);
+}
+
+/**
+ * Gets a CiviCRM Dashlets according to parameters
+ *
+ * @param array  $params       Associative array of property name/value
+ *                             pairs for the activity.
+ *
+ * @return array
+ *
+ */
+function civicrm_api3_dashboard_get($params) {
+  $bao = new CRM_Core_BAO_Dashboard();
+  _civicrm_api3_dao_set_filter($bao, $params, true, 'Dashboard');
+  $dashlets = _civicrm_api3_dao_to_array($bao, $params, true,'Dashboard');
+  return civicrm_api3_create_success($dashlets, $params, 'dashboard', 'get', $bao);
+}
+
+/**
+ * Delete a specified Dashlet.
+ *
+ * @param array $params array holding 'id' OR 'name' of dashlet to be deleted
+ *
+ * @return void|CRM_Core_Error  An error if 'name or ID' is invalid,
+ *
+ */
+function civicrm_api3_dashboard_delete($params) {
+  if (CRM_Core_BAO_Dashboard::deleteDashlet($params['id'])) {
+    return civicrm_api3_create_success(1, $params, 'dashboard', 'delete');
+  }
+  else {
+    return civicrm_api3_create_error('Could not delete dashlet');
+  }
+}
\ No newline at end of file
diff --git a/api/v3/DashboardContact.php b/api/v3/DashboardContact.php
new file mode 100644
index 0000000000000000000000000000000000000000..280420f70243e28ea11aab3ede957ffa3b2134e8
--- /dev/null
+++ b/api/v3/DashboardContact.php
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.4                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2013                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+*/
+
+/**
+ * File for the CiviCRM APIv3 for Dashboard Contact
+ *
+ * @package CiviCRM_APIv3
+ * @subpackage API_ActionSchedule
+ *
+ * @copyright CiviCRM LLC (c) 2004-2013
+ *
+ */
+
+/**
+ * Creates/Updates a new Dashboard Contact Entry
+ *
+ * @param array $params
+ *
+ * @return array
+ * 
+ */
+function civicrm_api3_dashboard_contact_create($params) {
+  civicrm_api3_verify_one_mandatory($params,
+    NULL,
+    array(
+      'dashboard_id',
+    )
+  );
+  $errors = _civicrm_api3_dashboard_contact_check_params($params);
+  $dashboard[] = $params;
+  $dashbordContact = CRM_Core_BAO_Dashboard::addContactDashletToDashboard($dashboard);
+  return civicrm_api3_create_success(TRUE);
+}
+
+/**
+ * Gets a CiviCRM Dashlets of Contacts according to parameters
+ *
+ * @param array  $params       Associative array of property name/value
+ *                             pairs for the activity.
+ *
+ * @return array
+ *
+ */
+function civicrm_api3_dashboard_contact_get($params) {
+  civicrm_api3_verify_one_mandatory($params,
+    NULL,
+    array(
+      'contact_id',
+    )
+  );
+  $bao = new CRM_Core_BAO_Dashboard();
+  $dashboardContact = CRM_Core_BAO_Dashboard::getContactDashlets(TRUE, CRM_Utils_Array::value('contact_id',$params));
+  return civicrm_api3_create_success($dashboardContact, $params, 'dashboard_contact', 'get');
+}
+
+/**
+ * Adjust Metadata for Create action
+ *
+ * The metadata is used for setting defaults, documentation & validation
+ * @param array $params array or parameters determined by getfields
+ */
+function _civicrm_api3_dashboard_contact_create_spec(&$params) {
+  unset($params['version']);
+}
+
+function _civicrm_api3_dashboard_contact_check_params(&$params) {
+  $dashboard_id = CRM_Utils_Array::value('dashboard_id', $params);
+  $allDashlets = CRM_Core_BAO_Dashboard::getDashlets();
+  if (!in_array($dashboard_id, $allDashlets)) {
+    return civicrm_api3_create_error('Invalid Dashboard ID');
+  }
+  return null;
+}
\ No newline at end of file
diff --git a/js/Common.js b/js/Common.js
index 3c59e8d2fd5a4efc433dcc5b18b2a00638882b18..ed859b28167036994f1cadf7affb6fabf037891f 100644
--- a/js/Common.js
+++ b/js/Common.js
@@ -443,58 +443,6 @@ function showHideRow(index) {
   return false;
 }
 
-/**
- * Function to check activity status in relavent to activity date
- *
- * @param element message JSON object.
- */
-function activityStatus(message) {
-  var d = new Date(), time = [], i;
-  var currentDateTime = d.getTime()
-  var activityTime = cj("input#activity_date_time_time").val().replace(":", "");
-
-  //chunk the time in bunch of 2 (hours,minutes,ampm)
-  for (i = 0; i < activityTime.length; i += 2) {
-    time.push(activityTime.slice(i, i + 2));
-  }
-  var activityDate = new Date(cj("input#activity_date_time_hidden").val());
-
-  d.setFullYear(activityDate.getFullYear());
-  d.setMonth(activityDate.getMonth());
-  d.setDate(activityDate.getDate());
-  var hours = time['0'];
-  var ampm = time['2'];
-
-  if (ampm == "PM" && hours != 0 && hours != 12) {
-    // force arithmetic instead of string concatenation
-    hours = hours * 1 + 12;
-  }
-  else {
-    if (ampm == "AM" && hours == 12) {
-      hours = 0;
-    }
-  }
-  d.setHours(hours);
-  d.setMinutes(time['1']);
-
-  var activity_date_time = d.getTime();
-
-  var activityStatusId = cj('#status_id').val();
-
-  if (activityStatusId == 2 && currentDateTime < activity_date_time) {
-    if (!confirm(message.completed)) {
-      return false;
-    }
-  }
-  else {
-    if (activity_date_time && activityStatusId == 1 && currentDateTime >= activity_date_time) {
-      if (!confirm(message.scheduled)) {
-        return false;
-      }
-    }
-  }
-}
-
 CRM.strings = CRM.strings || {};
 CRM.validate = CRM.validate || {
   params: {},
diff --git a/sql/civicrm_generated.mysql b/sql/civicrm_generated.mysql
index f87fbadc34e963c8bd601b95a20df3382fd7f98d..947c90ba0508e34db311e4a002cde97f9e04e841 100644
--- a/sql/civicrm_generated.mysql
+++ b/sql/civicrm_generated.mysql
@@ -325,7 +325,7 @@ UNLOCK TABLES;
 
 LOCK TABLES `civicrm_dashboard` WRITE;
 /*!40000 ALTER TABLE `civicrm_dashboard` DISABLE KEYS */;
-INSERT INTO `civicrm_dashboard` (`id`, `domain_id`, `label`, `url`, `permission`, `permission_operator`, `column_no`, `is_minimized`, `fullscreen_url`, `is_fullscreen`, `is_active`, `is_reserved`, `weight`) VALUES (1,1,'CiviCRM News','civicrm/dashlet/blog&reset=1&snippet=5','access CiviCRM',NULL,0,0,'civicrm/dashlet/blog&reset=1&snippet=5&context=dashletFullscreen',1,1,1,0),(2,1,'Activities','civicrm/dashlet/activity&reset=1&snippet=5','access CiviCRM',NULL,0,0,'civicrm/dashlet/activity&reset=1&snippet=5&context=dashletFullscreen',1,1,1,1),(3,1,'My Cases','civicrm/dashlet/myCases&reset=1&snippet=5','access my cases and activities',NULL,0,0,'civicrm/dashlet/myCases&reset=1&snippet=5&context=dashletFullscreen',1,1,1,2),(4,1,'All Cases','civicrm/dashlet/allCases&reset=1&snippet=5','access all cases and activities',NULL,0,0,'civicrm/dashlet/allCases&reset=1&snippet=5&context=dashletFullscreen',1,1,1,3),(5,1,'Case Dashboard Dashlet','civicrm/dashlet/casedashboard&reset=1&snippet=5','access CiviCase',NULL,0,0,'civicrm/dashlet/casedashboard&reset=1&snippet=5&context=dashletFullscreen',1,1,1,4),(6,1,'Donor Summary','civicrm/report/instance/6&reset=1&section=1&snippet=5&charts=barChart','access CiviContribute','AND',0,0,'civicrm/report/instance/6&reset=1&section=1&snippet=5&charts=barChart&context=dashletFullscreen',1,1,0,4),(7,1,'Top Donors','civicrm/report/instance/13&reset=1&section=2&snippet=5','access CiviContribute','AND',0,0,'civicrm/report/instance/13&reset=1&section=2&snippet=5&context=dashletFullscreen',1,1,0,5),(8,1,'Event Income Summary','civicrm/report/instance/25&reset=1&section=1&snippet=5&charts=pieChart','access CiviEvent','AND',0,0,'civicrm/report/instance/25&reset=1&section=1&snippet=5&charts=pieChart&context=dashletFullscreen',1,1,0,6),(9,1,'Membership Summary','civicrm/report/instance/20&reset=1&section=2&snippet=5','access CiviMember','AND',0,0,'civicrm/report/instance/20&reset=1&section=2&snippet=5&context=dashletFullscreen',1,1,0,7);
+INSERT INTO `civicrm_dashboard` (`id`, `domain_id`, `name`, `label`, `url`, `permission`, `permission_operator`, `column_no`, `is_minimized`, `fullscreen_url`, `is_fullscreen`, `is_active`, `is_reserved`, `weight`) VALUES (1,1,'blog','CiviCRM News','civicrm/dashlet/blog&reset=1&snippet=5','access CiviCRM',NULL,0,0,'civicrm/dashlet/blog&reset=1&snippet=5&context=dashletFullscreen',1,1,1,0),(2,1,'activity','Activities','civicrm/dashlet/activity&reset=1&snippet=5','access CiviCRM',NULL,0,0,'civicrm/dashlet/activity&reset=1&snippet=5&context=dashletFullscreen',1,1,1,1),(3,1,'myCases','My Cases','civicrm/dashlet/myCases&reset=1&snippet=5','access my cases and activities',NULL,0,0,'civicrm/dashlet/myCases&reset=1&snippet=5&context=dashletFullscreen',1,1,1,2),(4,1,'allCases','All Cases','civicrm/dashlet/allCases&reset=1&snippet=5','access all cases and activities',NULL,0,0,'civicrm/dashlet/allCases&reset=1&snippet=5&context=dashletFullscreen',1,1,1,3),(5,1,'casedashboard','Case Dashboard Dashlet','civicrm/dashlet/casedashboard&reset=1&snippet=5','access CiviCase',NULL,0,0,'civicrm/dashlet/casedashboard&reset=1&snippet=5&context=dashletFullscreen',1,1,1,4),(6,1,'report/6','Donor Summary','civicrm/report/instance/6&reset=1&section=1&snippet=5&charts=barChart','access CiviContribute','AND',0,0,'civicrm/report/instance/6&reset=1&section=1&snippet=5&charts=barChart&context=dashletFullscreen',1,1,0,4),(7,1,'report/13','Top Donors','civicrm/report/instance/13&reset=1&section=2&snippet=5','access CiviContribute','AND',0,0,'civicrm/report/instance/13&reset=1&section=2&snippet=5&context=dashletFullscreen',1,1,0,5),(8,1,'report/25','Event Income Summary','civicrm/report/instance/25&reset=1&section=1&snippet=5&charts=pieChart','access CiviEvent','AND',0,0,'civicrm/report/instance/25&reset=1&section=1&snippet=5&charts=pieChart&context=dashletFullscreen',1,1,0,6),(9,1,'report/20','Membership Summary','civicrm/report/instance/20&reset=1&section=2&snippet=5','access CiviMember','AND',0,0,'civicrm/report/instance/20&reset=1&section=2&snippet=5&context=dashletFullscreen',1,1,0,7);
 /*!40000 ALTER TABLE `civicrm_dashboard` ENABLE KEYS */;
 UNLOCK TABLES;
 
diff --git a/templates/CRM/Activity/Form/Activity.tpl b/templates/CRM/Activity/Form/Activity.tpl
index 74963be3b522aded5cb638c09a4b59aa7729b84f..73a9f945ba7af84e3c21329b1da80b91cd2dbe76 100644
--- a/templates/CRM/Activity/Form/Activity.tpl
+++ b/templates/CRM/Activity/Form/Activity.tpl
@@ -39,50 +39,7 @@
     <div class="crm-block crm-form-block crm-activity-form-block">
   {/if}
   {* added onload javascript for source contact*}
-  {literal}
-  <script type="text/javascript">
-  var assignee_contact = '';
-
-  {/literal}
-  {if $assignee_contact}
-    var assignee_contact = {$assignee_contact};
-  {/if}
-  {literal}
-
-  //loop to set the value of cc and bcc if form rule.
-  var assignee_contact_id = null;
-  var toDataUrl = "{/literal}{crmURL p='civicrm/ajax/checkemail' q='id=1&noemail=1' h=0 }{literal}"; {/literal}
-  {foreach from=","|explode:"assignee" key=key item=element}
-    {assign var=currentElement value=`$element`_contact_id}
-    {if $form.$currentElement.value }
-      {literal} var {/literal}{$currentElement}{literal} = cj.ajax({ url: toDataUrl + "&cid={/literal}{$form.$currentElement.value}{literal}", async: false }).responseText;{/literal}
-    {/if}
-  {/foreach}
-  {literal}
-
-  if ( assignee_contact_id ) {
-    eval( 'assignee_contact = ' + assignee_contact_id );
-  }
-
-  cj(function( ) {
-    {/literal}
-    {if $source_contact and $admin and $action neq 4}
-      {literal} cj( '#source_contact_id' ).val( "{/literal}{$source_contact}{literal}");{/literal}
-    {/if}
-    {literal}
-
-    var sourceDataUrl = "{/literal}{$dataUrl}{literal}";
-    var tokenDataUrl_assignee  = "{/literal}{$tokenUrl}&context=activity_assignee{literal}";
-    var hintText = "{/literal}{ts escape='js'}Type in a partial or complete name of an existing contact.{/ts}{literal}";
-    cj( "#assignee_contact_id").tokenInput( tokenDataUrl_assignee, { prePopulate: assignee_contact, theme: 'facebook', hintText: hintText });
-    cj( 'ul.token-input-list-facebook, div.token-input-dropdown-facebook' ).css( 'width', '450px' );
-    cj('#source_contact_id').autocomplete( sourceDataUrl, { width : 180, selectFirst : false, hintText: hintText, matchContains: true, minChars: 1, max: {/literal}{crmSetting name="search_autocomplete_count" group="Search Preferences"}{literal}
-    }).result( function(event, data, formatted) { cj( "#source_contact_qid" ).val( data[1] );
-      }).bind( 'click', function( ) { if (!cj("#source_contact_id").val()) { cj( "#source_contact_qid" ).val(''); } });
-  });
-  </script>
-
-  {/literal}
+  {include file="CRM/Activity/Form/ActivityJs.tpl" tokenContext="activity"}
   {if !$action or ( $action eq 1 ) or ( $action eq 2 ) }
   <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div>
   {/if}
diff --git a/templates/CRM/Activity/Form/ActivityJs.tpl b/templates/CRM/Activity/Form/ActivityJs.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..8ee7da8284fa36b078ab9399a0c02e6868e87d5a
--- /dev/null
+++ b/templates/CRM/Activity/Form/ActivityJs.tpl
@@ -0,0 +1,94 @@
+{*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.4                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2013                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+*}
+{* added onload javascript for source contact*}
+{literal}
+<script type="text/javascript">
+  var assignee_contact = '';
+
+  {/literal}
+  {if $assignee_contact}
+  var assignee_contact = {$assignee_contact};
+  {/if}
+
+  {literal}
+  var assignee_contact_id = null;
+  //loop to set the value of cc and bcc if form rule.
+  var toDataUrl = "{/literal}{crmURL p='civicrm/ajax/checkemail' q='id=1&noemail=1' h=0 }{literal}"; {/literal}
+  {foreach from=","|explode:"assignee" key=key item=element}
+  {assign var=currentElement value=`$element`_contact_id}
+  {if $form.$currentElement.value}
+    {literal} var {/literal}{$currentElement}{literal} = cj.ajax({ url: toDataUrl + "&cid={/literal}{$form.$currentElement.value}{literal}", async: false }).responseText;{/literal}
+      {/if}
+    {/foreach}
+    {literal}
+
+  if ( assignee_contact_id ) {
+    eval( 'assignee_contact = ' + assignee_contact_id );
+  }
+
+  cj(function( ) {
+    {/literal}
+    {if $source_contact and $admin and $action neq 4}
+      {literal} cj( '#source_contact_id' ).val( "{/literal}{$source_contact}{literal}");{/literal}
+      {/if}
+      {literal}
+
+    var sourceDataUrl = "{/literal}{$dataUrl}{literal}";
+    var tokenDataUrl_assignee  = "{/literal}{$tokenUrl}&context={$tokenContext}_assignee{literal}";
+
+    var hintText = "{/literal}{ts escape='js'}Start typing a name or email address.{/ts}{literal}";
+    cj( "#assignee_contact_id").tokenInput( tokenDataUrl_assignee, { prePopulate: assignee_contact, theme: 'facebook', hintText: hintText });
+    cj( 'ul.token-input-list-facebook, div.token-input-dropdown-facebook' ).css( 'width', '450px' );
+    cj('#source_contact_id').autocomplete( sourceDataUrl, { width : 180, selectFirst : false, hintText: hintText, matchContains: true, minChars: 1, max: {/literal}{crmSetting name="search_autocomplete_count" group="Search Preferences"}{literal}
+    }).result( function(event, data, formatted) { cj( "#source_contact_qid" ).val( data[1] );
+      }).bind( 'click', function( ) { if (!cj("#source_contact_id").val()) { cj( "#source_contact_qid" ).val(''); } });
+  });
+
+  /**
+   * Function to check activity status in relavent to activity date
+   *
+   * @param element message JSON object.
+   */
+  function activityStatus(message) {
+    var date =  cj("#activity_date_time_display").datepicker('getDate');
+    if (date) {
+      var
+        now = new Date(),
+        time = cj("#activity_date_time_time").timeEntry('getTime') || date,
+        activityStatusId = cj('#status_id').val(),
+        d = date.toString().split(' '),
+        activityDate = new Date(d[0] + ' ' + d[1] + ' ' + d[2] + ' ' + d[3] + ' ' + time.toTimeString());
+      if (activityStatusId == 2 && now < activityDate) {
+        return confirm(message.completed);
+      }
+      else if (activityStatusId == 1 && now >= activityDate) {
+        return confirm(message.scheduled);
+      }
+    }
+  }
+
+</script>
+{/literal}
diff --git a/templates/CRM/Case/Form/Activity.tpl b/templates/CRM/Case/Form/Activity.tpl
index e7077cec99407d8f653b3d0e0c9580f1e03e9b54..3a0220d2280cd17bec134ea41b287caf021a5c61 100644
--- a/templates/CRM/Case/Form/Activity.tpl
+++ b/templates/CRM/Case/Form/Activity.tpl
@@ -41,50 +41,7 @@
   <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div>
 
     {* added onload javascript for source contact*}
-    {literal}
-    <script type="text/javascript">
-    var assignee_contact = '';
-
-    {/literal}
-    {if $assignee_contact}
-    var assignee_contact = {$assignee_contact};
-    {/if}
-
-    {literal}
-    var assignee_contact_id = null;
-    //loop to set the value of cc and bcc if form rule.
-    var toDataUrl = "{/literal}{crmURL p='civicrm/ajax/checkemail' q='id=1&noemail=1' h=0 }{literal}"; {/literal}
-    {foreach from=","|explode:"assignee" key=key item=element}
-      {assign var=currentElement value=`$element`_contact_id}
-      {if $form.$currentElement.value}
-        {literal} var {/literal}{$currentElement}{literal} = cj.ajax({ url: toDataUrl + "&cid={/literal}{$form.$currentElement.value}{literal}", async: false }).responseText;{/literal}
-      {/if}
-    {/foreach}
-    {literal}
-
-    if ( assignee_contact_id ) {
-      eval( 'assignee_contact = ' + assignee_contact_id );
-    }
-
-    cj(function( ) {
-      {/literal}
-      {if $source_contact and $admin and $action neq 4}
-        {literal} cj( '#source_contact_id' ).val( "{/literal}{$source_contact}{literal}");{/literal}
-      {/if}
-      {literal}
-
-      var sourceDataUrl = "{/literal}{$dataUrl}{literal}";
-      var tokenDataUrl_assignee  = "{/literal}{$tokenUrl}&context=case_activity_assignee{literal}";
-
-      var hintText = "{/literal}{ts escape='js'}Type in a partial or complete name or email address of an existing contact.{/ts}{literal}";
-      cj( "#assignee_contact_id").tokenInput( tokenDataUrl_assignee, { prePopulate: assignee_contact, theme: 'facebook', hintText: hintText });
-      cj( 'ul.token-input-list-facebook, div.token-input-dropdown-facebook' ).css( 'width', '450px' );
-      cj( "#source_contact_id").autocomplete( sourceDataUrl, { width : 180, selectFirst : false, matchContains:true
-      }).result( function(event, data, formatted) { cj( "#source_contact_qid" ).val( data[1] );
-        }).bind( 'click', function( ) { cj( "#source_contact_qid" ).val(''); });
-    });
-  </script>
-  {/literal}
+    {include file="CRM/Activity/Form/ActivityJs.tpl" tokenContext="case_activity"}
 
   {/if}
 
diff --git a/templates/CRM/Case/Form/CaseView.tpl b/templates/CRM/Case/Form/CaseView.tpl
index 1b4c0a191a3f7d7b3ec75c7f19828738003e0745..60334a4154f855550e01c0024948276950786be2 100644
--- a/templates/CRM/Case/Form/CaseView.tpl
+++ b/templates/CRM/Case/Form/CaseView.tpl
@@ -781,7 +781,7 @@ function addRole() {
  <div class="crm-accordion-body">
   {assign var="tagExits" value=0}
   {if $tags}
-    <div class="crm-block crm-content-block crm-case-caseview-display-tags">{$tags}</div>
+    <div class="crm-block crm-content-block crm-case-caseview-display-tags">&nbsp;&nbsp;{$tags}</div>
     {assign var="tagExits" value=1}
   {/if}
 
@@ -853,18 +853,15 @@ function addTags() {
           }
         });
 
-        var tagList = '';
-        cj("#manageTags input[name^=case_taglist]").each(function( ) {
-          if (!tagsChecked) {
-            tagsChecked = cj(this).val() + '';
-          }
-          else {
-            tagsChecked = tagsChecked + ',' + cj(this).val();
-          }
+        var tagList = {};
+        cj("#manageTags input[name^=case_taglist]").each(function(){
+          var tsId = cj(this).attr('id').split('_');
+          tagList[tsId[2]] = cj(this).val();
         });
 
         var postUrl = {/literal}"{crmURL p='civicrm/case/ajax/processtags' h=0 }"{literal};
-        var data = 'case_id=' + caseID + '&tag=' + tagsChecked + '&key=' + {/literal}"{crmKey name='civicrm/case/ajax/processtags'}"{literal};
+        var key = {/literal}"{crmKey name='civicrm/case/ajax/processtags'}"{literal};
+        var data = {'case_id': caseID, 'tag': tagsChecked, 'taglist': tagList, 'key': key};
 
         cj.ajax({ type: "POST", url: postUrl, data: data, async: false });
         cj(this).dialog("close");
diff --git a/templates/CRM/common/Tag.tpl b/templates/CRM/common/Tag.tpl
index f16417a6bed3435b0b34db0ca86393e6945b4806..3f7427b5a705bd3d8ac9ebd9869c99f6dc253835 100644
--- a/templates/CRM/common/Tag.tpl
+++ b/templates/CRM/common/Tag.tpl
@@ -63,7 +63,9 @@
                         setVal[x] = valArray[x];
                       }
                     }
-                    CRM.alert('', '{/literal}{ts escape='js'}Removed{/ts}{literal}', 'success');
+                    if (!skipEntityAction) {
+                      CRM.alert('', '{/literal}{ts escape='js'}Removed{/ts}{literal}', 'success');
+                    }
                   }
                   else {
                     CRM.alert('', '{/literal}{ts escape='js'}Saved{/ts}{literal}', 'success');
diff --git a/tests/phpunit/api/v3/DashboardContactTest.php b/tests/phpunit/api/v3/DashboardContactTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..012a98ec25b571bac43141576656f9bb2b150c95
--- /dev/null
+++ b/tests/phpunit/api/v3/DashboardContactTest.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ *  File for the TestActionSchedule class
+ *
+ *  (PHP 5)
+ *
+ *   CiviCRM is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Affero General Public License
+ *   as published by the Free Software Foundation; either version 3 of
+ *   the License, or (at your option) any later version.
+ *
+ *   CiviCRM is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Affero General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Affero General Public
+ *   License along with this program.  If not, see
+ *   <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *  Include class definitions
+ */
+require_once 'CiviTest/CiviUnitTestCase.php';
+
+/**
+ *  Test APIv3 civicrm_action_schedule functions
+ *
+ *  @package CiviCRM_APIv3
+ *  @subpackage API_ActionSchedule
+ */
+
+class api_v3_DashboardContactTest extends CiviUnitTestCase {
+  protected $_params;
+  protected $_params2;
+  protected $_entity = 'dashborad_contact';
+  protected $_apiversion = 3;
+
+  public $_eNoticeCompliant = TRUE;
+  /**
+   *  Test setup for every test
+   *
+   *  Connect to the database, truncate the tables that will be used
+   *  and redirect stdin to a temporary file
+   */
+  public function setUp() {
+    //  Connect to the database
+    parent::setUp();
+  }
+
+  /**
+   * Tears down the fixture, for example, closes a network connection.
+   * This method is called after a test is executed.
+   *
+   * @access protected
+   */
+  function tearDown() {
+    $tablesToTruncate = array(
+      'civicrm_dashboard',
+      'civicrm_dashboard_contact',
+    );
+    $this->quickCleanup($tablesToTruncate, TRUE);
+  }
+  
+  function testDashboardContactCreate() {
+    $dashParams = array(
+      'version' => 3,
+      'label' => 'New Dashlet element',
+      'name' => 'New Dashlet element',
+      'url' => 'civicrm/report/list&compid=99&reset=1&snippet=5',
+      'fullscreen_url' => 'civicrm/report/list&compid=99&reset=1&snippet=5&context=dashletFullscreen',
+    );
+  	$dashresult = $this->callAPISuccess('dashboard', 'create', $dashParams);
+  	$contact = $this->callAPISuccess('contact', 'create', array( 'first_name' => 'abc1',
+      'contact_type' => 'Individual',
+      'last_name' => 'xyz1',
+      'email' => 'abc@abc.com')
+     );
+  	$oldCount = CRM_Core_DAO::singleValueQuery("select count(*) from civicrm_dashboard_contact where contact_id = {$contact['id']} AND is_active = 1 AND dashboard_id = {$dashresult['id']}");
+    $params = array(
+      'version' => 3,
+      'contact_id' => $contact['id'],
+      'dashboard_id' => $dashresult['id'],
+      'is_active' => 1,
+    );
+  	$dashboradContact = $this->callAPISuccess('dashboard_contact', 'create', $params);
+  	$newCount = CRM_Core_DAO::singleValueQuery("select count(*) from civicrm_dashboard_contact where contact_id = {$contact['id']} AND is_active = 1 AND dashboard_id = {$dashresult['id']}");
+  	$this->assertEquals($oldCount+1, $newCount);
+  }
+}
\ No newline at end of file
diff --git a/tests/phpunit/api/v3/DashboardTest.php b/tests/phpunit/api/v3/DashboardTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..baba27c2b1c24044a8c94f2abc48b0186cb6205c
--- /dev/null
+++ b/tests/phpunit/api/v3/DashboardTest.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ *  File for the TestActionSchedule class
+ *
+ *  (PHP 5)
+ *
+ *   CiviCRM is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Affero General Public License
+ *   as published by the Free Software Foundation; either version 3 of
+ *   the License, or (at your option) any later version.
+ *
+ *   CiviCRM is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Affero General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Affero General Public
+ *   License along with this program.  If not, see
+ *   <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *  Include class definitions
+ */
+require_once 'CiviTest/CiviUnitTestCase.php';
+
+/**
+ *  Test APIv3 civicrm_action_schedule functions
+ *
+ *  @package CiviCRM_APIv3
+ *  @subpackage API_ActionSchedule
+ */
+
+class api_v3_DashboardTest extends CiviUnitTestCase {
+  protected $_params;
+  protected $_params2;
+  protected $_entity = 'dashboard';
+  protected $_apiversion = 3;
+
+  public $_eNoticeCompliant = TRUE;
+  /**
+   *  Test setup for every test
+   *
+   *  Connect to the database, truncate the tables that will be used
+   *  and redirect stdin to a temporary file
+  */
+  public function setUp() {
+   //  Connect to the database
+    parent::setUp();
+  }
+
+  /**
+   * Tears down the fixture, for example, closes a network connection.
+   * This method is called after a test is executed.
+   *
+   * @access protected
+   */
+  function tearDown() {
+    $tablesToTruncate = array(
+      'civicrm_dashboard',
+    );
+    $this->quickCleanup($tablesToTruncate, TRUE);
+  }
+
+  function testDashboardCreate() {
+  	$oldCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_dashboard');
+    $params = array(
+      'version' => 3,
+      'label' => 'New Dashlet element',
+      'name' => 'New Dashlet element',
+      'url' => 'civicrm/report/list&reset=1&compid=99&snippet=5',
+      'fullscreen_url' => 'civicrm/report/list&compid=99&reset=1&snippet=5&context=dashletFullscreen',
+    );
+    $dashboard = $this->callAPISuccess('dashboard', 'create', $params);
+    $this->assertTrue(is_numeric($dashboard['id']), "In line " . __LINE__);
+    $this->assertTrue($dashboard['id'] > 0, "In line " . __LINE__);
+    $newCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_dashboard');
+    $this->assertEquals($oldCount+1, $newCount);
+    $this->DashboardDelete($dashboard['id'],$oldCount);
+  }
+
+  function DashboardDelete($id, $oldCount) {
+    $params = array(
+      'version' => 3,
+      'id' => $id,
+    );
+    $dashboardget = $this->callAPISuccess('dashboard', 'get', $params);
+    $this->assertEquals($id, $dashboardget['id']);
+    $dashboard = $this->callAPISuccess('dashboard', 'delete', $params);
+    $newCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_dashboard');
+    $this->assertEquals($oldCount, $newCount);
+  }
+}
\ No newline at end of file
diff --git a/tests/phpunit/api/v3/SyntaxConformanceTest.php b/tests/phpunit/api/v3/SyntaxConformanceTest.php
index 1264e5f840c2886aaf9d046765d45914e74fd145..c3bff44ee9b09de9176c3e8146abbd1808b309a0 100644
--- a/tests/phpunit/api/v3/SyntaxConformanceTest.php
+++ b/tests/phpunit/api/v3/SyntaxConformanceTest.php
@@ -156,7 +156,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase {
  * @return multitype:string |multitype:multitype:string
  */
   public static function toBeSkipped_automock($sequential = FALSE) {
-    $entitiesWithoutGet = array('MailingContact', 'EntityTag', 'Participant', 'ParticipantPayment', 'Setting', 'SurveyRespondant', 'MailingRecipients',  'CustomSearch', 'Extension', 'ReportTemplate', 'System');
+    $entitiesWithoutGet = array('MailingContact', 'EntityTag', 'Participant', 'ParticipantPayment', 'Setting', 'SurveyRespondant', 'MailingRecipients',  'CustomSearch', 'Extension', 'ReportTemplate', 'System', 'DashboardContact');
     if ($sequential === TRUE) {
       return $entitiesWithoutGet;
     }
@@ -235,6 +235,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase {
       'MailSettings',
       'Setting',
       'MailingContact',
+      'DashboardContact',
     );
     if ($sequential === TRUE) {
       return $entitiesWithout;