+
+  // updateGroup updates group information with new data.
+  function updateGroup($fields) {
+    $mdb2 = getConnection();
+
+    $group_id = $fields['group_id'];
+    if ($group_id && !$this->isGroupValid($group_id)) return false;
+    if (!$group_id) $group_id = $this->getGroup();
+
+    if (isset($fields['name'])) $name_part = ', name = '.$mdb2->quote($fields['name']);
+    if (isset($fields['description'])) $description_part = ', description = '.$mdb2->quote($fields['description']);
+    if (isset($fields['currency'])) $currency_part = ', currency = '.$mdb2->quote($fields['currency']);
+    if (isset($fields['lang'])) $lang_part = ', lang = '.$mdb2->quote($fields['lang']);
+    if (isset($fields['decimal_mark'])) $decimal_mark_part = ', decimal_mark = '.$mdb2->quote($fields['decimal_mark']);
+    if (isset($fields['date_format'])) $date_format_part = ', date_format = '.$mdb2->quote($fields['date_format']);
+    if (isset($fields['time_format'])) $time_format_part = ', time_format = '.$mdb2->quote($fields['time_format']);
+    if (isset($fields['week_start'])) $week_start_part = ', week_start = '.(int) $fields['week_start'];
+    if (isset($fields['tracking_mode'])) {
+      $tracking_mode_part = ', tracking_mode = '.(int) $fields['tracking_mode'];
+      $project_required_part = ' , project_required = '.(int) $fields['project_required'];
+      $task_required_part = ' , task_required = '.(int) $fields['task_required'];
+    }
+    if (isset($fields['record_type'])) $record_type_part = ', record_type = '.(int) $fields['record_type'];
+    if (isset($fields['bcc_email'])) $bcc_email_part = ', bcc_email = '.$mdb2->quote($fields['bcc_email']);
+    if (isset($fields['allow_ip'])) $allow_ip_part = ', allow_ip = '.$mdb2->quote($fields['allow_ip']);
+    if (isset($fields['plugins'])) $plugins_part = ', plugins = '.$mdb2->quote($fields['plugins']);
+    if (isset($fields['config'])) $config_part = ', config = '.$mdb2->quote($fields['config']);
+    if (isset($fields['lock_spec'])) $lock_spec_part = ', lock_spec = '.$mdb2->quote($fields['lock_spec']);
+    if (isset($fields['workday_minutes'])) $workday_minutes_part = ', workday_minutes = '.$mdb2->quote($fields['workday_minutes']);
+    $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($this->id);
+
+    $parts = trim($name_part.$description_part.$currency_part.$lang_part.$decimal_mark_part.$date_format_part.
+      $time_format_part.$week_start_part.$tracking_mode_part.$task_required_part.$project_required_part.$record_type_part.
+      $bcc_email_part.$allow_ip_part.$plugins_part.$config_part.$lock_spec_part.$workday_minutes_part.$modified_part, ',');
+
+    $sql = "update tt_groups set $parts where id = $group_id and org_id = $this->org_id";
+    $affected = $mdb2->exec($sql);
+    if (is_a($affected, 'PEAR_Error')) return false;
+
+    return true;
+  }
+
+  // markUserDeleted marks a user in group as deleted.
+  function markUserDeleted($user_id) {
+    if (!$this->can('manage_users') || $this->id == $user_id)
+      return false;
+
+    // Make sure we operate on a legit user.
+    $user_details = $this->getUserDetails($user_id);
+    if (!$user_details) return false;
+
+    $mdb2 = getConnection();
+    $group_id = $this->getGroup();
+    $org_id = $this->org_id;
+
+    // Mark user to project binds as deleted.
+    $sql = "update tt_user_project_binds set status = NULL where user_id = $user_id".
+      " and group_id = $group_id and org_id = $org_id";
+    $affected = $mdb2->exec($sql);
+    if (is_a($affected, 'PEAR_Error'))
+      return false;
+
+    // Mark user favorite reports as deleted.
+    $sql = "update tt_fav_reports set status = NULL where user_id = $user_id".
+      " and group_id = $group_id and org_id = $org_id";
+    $affected = $mdb2->exec($sql);
+    if (is_a($affected, 'PEAR_Error'))
+      return false;
+
+    // Mark user as deleted.
+    $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($this->id);
+    $sql = "update tt_users set status = null $modified_part where id = $user_id".
+      " and group_id = $group_id and org_id = $org_id";
+    $affected = $mdb2->exec($sql);
+    if (is_a($affected, 'PEAR_Error'))
+      return false;
+
+    return true;
+  }
+
+  // enablePlugin either enables or disables a specific plugin for group.
+  function enablePlugin($plugin, $enable = true)
+  {
+    if (!$this->can('manage_advanced_settings'))
+      return false; // Note: enablePlugin is currently only used on week_view.php.
+                    // So, it's not really a plugin we are enabling, but rather week view display options.
+                    // Therefore, a check for manage_advanced_settings, not manage_features.
+
+    $plugin_array = explode(',', $this->plugins);
+    if ($enable && !in_array($plugin, $plugin_array))
+      $plugin_array[] = $plugin; // Add plugin to array.
+
+    if (!$enable && in_array($plugin, $plugin_array)) {
+      $key = array_search($plugin, $plugin_array);
+      if ($key !== false)
+        unset($plugin_array[$key]); // Remove plugin from array.
+    }
+
+    $plugins = implode(',', $plugin_array);
+    if ($plugins != $this->plugins) {
+      if (!$this->updateGroup(array('plugins' => $plugins)))
+        return false;
+      $this->plugins = $plugins;
+    }
+
+    return true;
+  }
+
+  // isUserValid determines if a user is valid for on behalf work.
+  function isUserValid($user_id) {
+    if ($user_id == $this->id)
+      return true;
+    return ($this->getUserDetails($user_id) != null);
+  }
+
+  // isGroupValid determines if a group is valid for user.
+  function isGroupValid($group_id) {
+    if ($group_id == $this->group_id)
+      return true;
+    else
+      return $this->isSubgroupValid($group_id);
+  }
+
+  // isSubgroupValid determines if a subgroup is valid for user.
+  // A subgroup is valid if:
+  //   - user can manage_subgroups;
+  //   - subgroup is either a direct child of user group, or "on the path"
+  //   to it (grand-child, etc.).
+  function isSubgroupValid($subgroup_id) {
+    if (!$this->can('manage_subgroups')) return false; // User cannot manage subgroups.
+
+    $current_group_id = $subgroup_id;
+    while ($parent_group_id = ttGroupHelper::getParentGroup($current_group_id)) {
+      if ($parent_group_id == $this->group_id) {
+        return true; // Found it.
+      }
+      $current_group_id = $parent_group_id;
+    }
+    return false;
+  }
+
+  // getMaxRankForGroup determines effective user rank for a user in a given group.
+  // For home group it is the existing user rank (as per role) minus 1.
+  // For subgroups, if user can "manage_subgroups", it is MAX_RANK.
+  function getMaxRankForGroup($group_id) {
+
+    $max_rank = 0; // Start safely.
+    if ($this->group_id == $group_id) {
+      $max_rank = $this->rank - 1;
+      return $max_rank;
+    }
+
+    if ($this->isSubgroupValid($group_id))
+      $max_rank = MAX_RANK;
+
+    return $max_rank;
+  }
+
+  // getUserPartForHeader constructs a string for user to display on pages header.
+  // It changes with "on behalf" attributes for both user and group.
+  function getUserPartForHeader() {
+    global $i18n;
+    if (!$this->id) return null;
+
+    $user_part = htmlspecialchars($this->name);
+    $user_part .= ' - '.htmlspecialchars($this->role_name);
+    if ($this->behalf_id) {
+      $user_part .= ' <span class="onBehalf">'.$i18n->get('label.on_behalf').' '.htmlspecialchars($this->behalf_name).'</span>';
+    }
+    if ($this->behalf_group_id) {
+      $user_part .= ',  <span class="onBehalf">'.htmlspecialchars($this->behalf_group_name).'</span>';
+    } else {
+      if ($this->group_name) // Note: we did not require group names in the past.
+        $user_part .= ', '.$this->group_name;
+    }
+    return $user_part;
+  }
+
+  // setOnBehalfGroup sets on behalf group for the user in both the object and the session.
+  function setOnBehalfGroup($group_id) {
+
+    // Unset things first.
+    $this->behalf_group_id = null;
+    $this->behalf_group_name = null;
+    $this->behalf_id = null;
+    $this->behalf_name = null;
+    unset($this->behalfGroup);
+    unset($_SESSION['behalf_group_id']);
+    unset($_SESSION['behalf_group_name']);
+    unset($_SESSION['behalf_id']);
+    unset($_SESSION['behalf_name']);
+
+    // Destroy report bean if it was set in session.
+    $form = new Form('dummyForm');
+    $bean = new ActionForm('reportBean', $form, $request);
+    if ($bean->isSaved()) {
+      $bean->destroyBean();
+    }
+
+    // Do not do anything if we don't have rights.
+    if (!$this->can('manage_subgroups')) return;
+
+    // No need to set if group is our home group.
+    if ($group_id == $this->group_id) return;
+
+    // No need to set if subgroup is not valid.
+    if (!$this->isSubgroupValid($group_id)) return;
+
+    // We are good to set on behalf group.
+    $onBehalfGroupName = ttGroupHelper::getGroupName($group_id);
+    $_SESSION['behalf_group_id'] = $group_id;
+    $_SESSION['behalf_group_name'] = $onBehalfGroupName;
+    $this->behalf_group_id = $group_id;
+    $this->behalf_group_name = $onBehalfGroupName;
+
+    $this->behalfGroup = new ttGroup($this->behalf_group_id, $this->org_id);
+
+    // Adjust on behalf user to first found user in subgroup.
+    $this->adjustBehalfId();
+    return;
+  }
+
+  // setOnBehalfUser sets on behalf user both the object and the session.
+  function setOnBehalfUser($user_id) {
+
+    // Unset things first.
+    $this->behalf_id = null;
+    $this->behalf_name = null;
+    unset($this->behalfUser);
+    unset($_SESSION['behalf_id']);
+    unset($_SESSION['behalf_name']);
+
+    // No need to set if user is us.
+    if ($user_id == $this->id) return;
+
+    // No need to set if user id is not valid.
+    if (!$this->isUserValid($user_id)) return;
+
+    // We are good to set on behalf user.
+    $onBehalfUserName = ttUserHelper::getUserName($user_id);
+    $_SESSION['behalf_id'] = $user_id;
+    $_SESSION['behalf_name'] = $onBehalfUserName;
+    $this->behalf_id = $user_id;
+    $this->behalf_name = $onBehalfUserName;
+
+    $this->behalfUser = new ttBehalfUser($this->behalf_id, $this->org_id);
+    return;
+  }
+
+  // The exists() function determines if an active user exists in context of a page.
+  // If we are working as self, true.
+  // If we are working in a subgroup with active users, true.
+  // If we are working in a subgroup without active users, false.
+  function exists() {
+    if (!$this->behalfGroup)
+      return true; // Working as self.
+    else if ($this->behalfGroup->active_users)
+      return true; // Subgroup has users.
+
+    return false;
+  }