--- ../devel-roundcube_svn/program/include/rcube_ldap.php	2011-12-04 20:27:01.000000000 +0100
+++ program/include/rcube_ldap.php	2011-12-31 14:44:32.000000000 +0100
@@ -486,7 +486,7 @@
         }
 
         // fetch group members recursively
-        if ($this->group_id && $this->group_data['dn'])
+        if ($this->group_id && $this->group_data['dn'] && ($this->group_id != 'UNGROUPED'))
         {
             $entries = $this->list_group_members($this->group_data['dn']);
 
@@ -525,6 +525,27 @@
                 $entries = ldap_get_entries($this->conn, $this->ldap_result);
             }
 
+            // if the ungrouped group is selected
+            if ($this->group_id && ($this->group_id == 'UNGROUPED'))
+            {
+                $groups = $this->list_groups();
+
+                $grouped_dns = array();
+                foreach ($groups as $group)
+                {
+                    $grouped_members = $this->list_group_members($group['dn']);
+                    foreach ($grouped_members as $grouped_member)
+                        $grouped_dns[$grouped_member['dn']] = 1;
+                }
+
+                $ungrouped_entries = array();
+                foreach ($entries as $entry)
+                    if ($entry['dn'] and ($grouped_dns[$entry['dn']] != 1))
+                        $ungrouped_entries[] = $entry;
+
+                $entries = $ungrouped_entries;
+                $entries['count'] = sizeof($ungrouped_entries);
+            }
         }  // end else
 
         // start and end of the page
@@ -1511,6 +1534,7 @@
         $email_attr = $this->prop['groups']['email_attr'] ? $this->prop['groups']['email_attr'] : 'mail';
         $sort_attrs = $this->prop['groups']['sort'] ? (array)$this->prop['groups']['sort'] : array($name_attr);
         $sort_attr = $sort_attrs[0];
+        $ungrouped = $this->prop['groups']['ungrouped'];
 
         $this->_debug("C: Search [$filter][dn: $base_dn]");
 
@@ -1585,6 +1609,18 @@
         if (!$this->prop['groups']['vlv'])
             array_multisort($group_sortnames, SORT_ASC, SORT_STRING, $groups);
 
+        // add ungrouped on top position if groups exists
+        if ($groups and $ungrouped)
+        {
+            $group_id = 'UNGROUPED';
+            $ungroup[$group_id]['ID'] = $group_id;
+            $ungroup[$group_id]['dn'] = '';
+            $ungroup[$group_id]['name'] = $ungrouped;
+            $ungroup[$group_id]['member_attr'] = '';
+
+            $groups = $ungroup + $groups;
+        }
+
         // cache this
         $this->cache->set('groups', $groups);
 
@@ -1652,6 +1688,9 @@
      */
     function delete_group($group_id)
     {
+        if ($group_id == 'UNGROUPED')
+            return false;
+            
         if (($group_cache = $this->cache->get('groups')) === null)
             $group_cache = $this->_fetch_groups();
 
@@ -1685,6 +1724,9 @@
      */
     function rename_group($group_id, $new_name, &$new_gid)
     {
+        if ($group_id == 'UNGROUPED')
+            return false;
+            
         if (($group_cache = $this->cache->get('groups')) === null)
             $group_cache = $this->_fetch_groups();
 
@@ -1719,6 +1761,9 @@
      */
     function add_to_group($group_id, $contact_ids)
     {
+        if ($group_id == 'UNGROUPED')
+            return 0;
+
         if (($group_cache = $this->cache->get('groups')) === null)
             $group_cache = $this->_fetch_groups();
 
@@ -1759,6 +1804,9 @@
      */
     function remove_from_group($group_id, $contact_ids)
     {
+        if ($group_id == 'UNGROUPED')
+            return 0;
+
         if (($group_cache = $this->cache->get('groups')) === null)
             $group_cache = $this->_fetch_groups();
 
