Index: /sandbox/2.2.0.2/contactcenter/inc/class.so_group.inc.php
===================================================================
--- /sandbox/2.2.0.2/contactcenter/inc/class.so_group.inc.php	(revision 4498)
+++ /sandbox/2.2.0.2/contactcenter/inc/class.so_group.inc.php	(revision 4502)
@@ -569,4 +569,34 @@
 		}		
 		
+		function updateContactGroups($id_defaultconnection, $connections, $groups)
+		{
+			if (is_array($groups) && count($groups) > 0)
+			{
+				$query = "UPDATE phpgw_cc_contact_grps SET id_connection = " . $id_defaultconnection . " WHERE (";
+				$more = false;
+				foreach ($connections as $connection)
+				{
+					if ($more)
+					$query .= " OR ";
+					$query .= "id_connection = " . $connection['id_connection'];
+					$more = true;
+				}
+				$query .= ") AND (";
+				$more = false;
+				foreach ($groups as $group)
+				{
+					if ($more)
+					$query .= " OR ";
+					$query .= "id_group = " . $group['id_group'];
+					$more = true;
+				}
+				$query .= ");";
+				if (!$this->db->query($query))			
+					exit ('Query failed! File: '.__FILE__.' on line'.__LINE__);				
+						 			
+				return true;
+			}
+		}
+		
 		function deleteContactsByGroup($id_group, $contacts = null)
 		{
Index: /sandbox/2.2.0.2/contactcenter/inc/class.bo_group.inc.php
===================================================================
--- /sandbox/2.2.0.2/contactcenter/inc/class.bo_group.inc.php	(revision 4498)
+++ /sandbox/2.2.0.2/contactcenter/inc/class.bo_group.inc.php	(revision 4502)
@@ -127,4 +127,9 @@
 			return $this->so->deleteContactsByGroup($id_group, $contacts_conns);
 		}
+
+		function update_contact_groups($id_defaultconnection, $connections, $groups)
+		{
+			return $this->so->updateContactGroups($id_defaultconnection, $connections, $groups);
+		}
 		
 	}
Index: /sandbox/2.2.0.2/contactcenter/inc/class.bo_connection.inc.php
===================================================================
--- /sandbox/2.2.0.2/contactcenter/inc/class.bo_connection.inc.php	(revision 4502)
+++ /sandbox/2.2.0.2/contactcenter/inc/class.bo_connection.inc.php	(revision 4502)
@@ -0,0 +1,31 @@
+<?php
+/*
+ * Classe responsavel pelas conexoes.
+ * Baseado na classe so_main de Raphael Derosso Pereira
+ * Autor: Luiz Carlos Viana Melo - Prognus
+ * luiz@prognus.com.br
+ */
+
+	class bo_connection
+	{
+		/*!
+			@function get_connection_type_by_conn_id
+			@abstract This function returns the type of a connection.
+			@author Luiz Carlos Viana Melo
+			
+		 */
+		function get_connection_type_by_conn_id($id_connection)
+		{
+			$so_conns = CreateObject('contactcenter.so_contact_conns', $id_connection);
+			$types = $so_conns->get_field('id_typeof_contact_connection');
+			return $types[0];
+		}
+		
+		function get_contact_id_by_connection($id_connection)
+		{
+			$so_conns = CreateObject('contactcenter.so_contact_conns', $id_connection);
+			$id_contact = $so_conns->get_field('id_contact');
+			return $id_contact;
+		}
+	}
+?>
Index: /sandbox/2.2.0.2/contactcenter/inc/class.so_contact_conns.inc.php
===================================================================
--- /sandbox/2.2.0.2/contactcenter/inc/class.so_contact_conns.inc.php	(revision 4502)
+++ /sandbox/2.2.0.2/contactcenter/inc/class.so_contact_conns.inc.php	(revision 4502)
@@ -0,0 +1,65 @@
+<?php
+/*
+ * Classe Storage Object - phpgw_cc_contact_conns
+ * Baseado na classe so_main de Raphael Derosso Pereira
+ * Autor: Luiz Carlos Viana Melo - Prognus
+ * luiz@prognus.com.br
+ */
+
+	include_once("class.so_main.inc.php");
+	
+	class so_contact_conns extends so_main
+	{
+		
+		function so_contact_conns ( $id = false)
+		{
+			$this->init();
+			
+			$this->main_fields = array(
+				'id_connection' => array(
+					'name'  => 'id_connection',
+					'type'  => 'primary',
+					'state' => 'empty',
+					'value' => &$this->id
+				),
+				'id_contact' => array(
+					'name'  => 'id_contact',
+					'type'  => false,
+					'state' => 'empty',
+					'value' => false
+				),
+				'id_typeof_contact_connection' => array(
+					'name'  => 'id_typeof_contact_connection',
+					'type'  => false,
+					'state' => 'empty',
+					'value' => false
+				)
+			);
+
+			$this->db_tables = array(
+				'phpgw_cc_contact_conns' => array(
+					'type'   => 'main',
+					'keys'   => array(
+						'primary' => array(&$this->main_fields['id_connection']),
+						'foreign' => false
+					),
+					'fields' => & $this->main_fields
+				)
+			);
+			
+			if ($id)
+			{
+				if (!$this->checkout($id))
+				{
+					$this->reset_values();
+					$this->state = 'new';
+				}
+			}
+			else
+			{
+				$this->state = 'new';
+			}
+		}
+	}
+
+?>
Index: /sandbox/2.2.0.2/contactcenter/inc/class.bo_people_catalog.inc.php
===================================================================
--- /sandbox/2.2.0.2/contactcenter/inc/class.bo_people_catalog.inc.php	(revision 4498)
+++ /sandbox/2.2.0.2/contactcenter/inc/class.bo_people_catalog.inc.php	(revision 4502)
@@ -1890,5 +1890,6 @@
 				
 			}
-
+			$groups = CreateObject('contactcenter.so_group');
+			
 			foreach ($connections as $id => $type)
 			{
@@ -1897,5 +1898,5 @@
 					return false;
 				}
-				
+				$groups->deleteContactFromGroups($id);
 				if (!($connection->remove()))
 				{
Index: /sandbox/2.2.0.2/contactcenter/inc/class.ui_data.inc.php
===================================================================
--- /sandbox/2.2.0.2/contactcenter/inc/class.ui_data.inc.php	(revision 4500)
+++ /sandbox/2.2.0.2/contactcenter/inc/class.ui_data.inc.php	(revision 4502)
@@ -2029,19 +2029,40 @@
 			$data['contact_in_list'] = $new_tdata[1];
 			$data['id_group'] = $new_tdata[2];
+			$data['old_contacts_in_list'] = $new_tdata[3];
 			
-			$contactWOemail = false; 
-	                         
-			foreach ($data['contact_in_list'] as $id_connection) 
- 			{ 
- 				$boConn = CreateObject('contactcenter.bo_connection'); 
- 				$type = $boConn->get_connection_type_by_conn_id($id_connection); 
- 				if ($type != 1) 
- 				{ 
- 					$contactWOemail = true; 
-					break; 
- 				} 
- 			}
-
-
+			foreach ($data['old_contacts_in_list'] as $id_connection)
+			{
+				$boConn = CreateObject('contactcenter.bo_connection');
+
+				$id_contact = $boConn->get_contact_id_by_connection($id_connection);
+				$contact = CreateObject('contactcenter.so_contact', $id_contact);
+				$contact->set_field("last_status", 'U');
+				$contact->set_field("last_update",time()."000");
+				$contact->commit();
+			}
+						
+			$contactWOemail = false;
+
+			foreach ($data['contact_in_list'] as $id_connection)
+			{
+				$boConn = CreateObject('contactcenter.bo_connection');
+				
+				$id_contact = $boConn->get_contact_id_by_connection($id_connection);
+				$contact = CreateObject('contactcenter.so_contact', $id_contact);
+				$contact->set_field("last_status", 'U');
+				$contact->set_field("last_update",time()."000");
+				$contact->commit();
+				
+				if (!$contactWOemail)
+				{
+					$type = $boConn->get_connection_type_by_conn_id($id_connection);
+					if ($type != 1)
+					{
+						$contactWOemail = true;
+					}
+				}
+			}
+
+ 
                         $acumulatedErrors = '';
 
@@ -2497,5 +2518,6 @@
 			if (!is_null($id) and $id !== '')
 			{
-				$id = $this->bo->catalog->update_single_info($id, $data); 
+				$old_connections = $this->bo->catalog->get_connections($id);
+				$id = $this->bo->catalog->update_single_info($id, $data);
 				$result = array(
 					'msg' => lang('Updated Successfully!'),
@@ -2522,5 +2544,8 @@
 			else
 			{
-				$this->bo->catalog->update_contact_groups($id, $groups);
+				if (isset($old_connections))
+					$this->bo->catalog->update_contact_groups($id, $groups, $old_connections);
+				else
+					$this->bo->catalog->update_contact_groups($id, $groups);
 			}
 
Index: /sandbox/2.2.0.2/contactcenter/js/cc_config.js
===================================================================
--- /sandbox/2.2.0.2/contactcenter/js/cc_config.js	(revision 4502)
+++ /sandbox/2.2.0.2/contactcenter/js/cc_config.js	(revision 4502)
@@ -0,0 +1,175 @@
+  /***************************************************************************\
+  * cc_config.js														      *	
+  * Written by:                                                               *
+  *  - Adriano Pereira da silva - Prognus <adriano@prognus.com.br>            *
+  *  - Airton Bordin Junior - Prognus <airton@prognus.com.br>                 *
+  *  - http://www.prognus.com.br                                              *
+  * ------------------------------------------------------------------------- *
+  *  This program is free software; you can redistribute it and/or modify it  *
+  *  under the terms of the GNU General Public License as published by the    *
+  *  Free Software Foundation; either version 2 of the License, or (at your   *
+  *  option) any later version.                                               *
+  \***************************************************************************/
+
+
+
+	/*
+	 * @function cc_attribute_clear
+	 * @abstract Elimina as tuplas com campos vazios antes de enviar o formulário via POST
+	 * @author Prognus software livre - http://www.prognus.com.br
+	 * @param form
+	 */
+	function cc_attribute_clear(form)
+	{
+
+		var vars = document.getElementsByClassName("cc_attribute");
+		
+		var tupla;
+		var select;
+		var inputs;
+		
+		for (var i=0; i<vars.length; i++) {	
+			tupla = vars[i];
+			inputs = tupla.getElementsByTagName("input");
+			
+			if(inputs[0].value == "" || inputs[1].value == "") 
+			{
+				
+				inputs[0].setAttribute("value", "");
+				inputs[1].setAttribute("value", "");
+				
+				select = tupla.getElementsByTagName("select");
+				select[0].innerHTML = "<option value=\"\" selected=\"selected\"></option>";
+				
+				tupla.style.visible = "hidden";
+				tupla.style.display = "none";
+			}
+		}
+		form.submit();
+	}
+	
+	
+	
+	/*
+	 * @function cc_attribute_add
+	 * @abstract Adiciona uma nova tupla de campos ao final da lista de tuplas 
+	 * @author Prognus software livre - http://www.prognus.com.br
+	 * @param
+	 */
+	function cc_attribute_add()
+	{
+		var strings = document.getElementsByClassName("cc_attribute")[0].getElementsByTagName("label");
+		var stringNome = strings[0].innerHTML + " ";
+		var stringCorrespLdap = " " + strings[1].innerHTML + " ";
+		var stringTipo = " " + strings[2].innerHTML + " ";
+		
+		var stringTexto = document.getElementsByClassName("cc_attribute")[0].getElementsByTagName("select")[0].getElementsByTagName("option")[0].innerHTML;
+		var stringMultivalorado = document.getElementsByClassName("cc_attribute")[0].getElementsByTagName("select")[0].getElementsByTagName("option")[1].innerHTML
+		
+		var numeroAtributo = 0;
+		var vars = document.getElementsByClassName("cc_attribute");
+		
+		var maior = 0;
+		for (var i=0; i<vars.length; i++) {
+			var tupla = vars[i];
+			var linhaIndice = tupla.getElementsByTagName("input")[0];
+			var arrayDeTokens = linhaIndice.getAttribute("name").split("_");
+			
+			numeroAtributo = arrayDeTokens[3];
+			numeroAtributo = numeroAtributo.substr(0, numeroAtributo.length -1);
+			numeroAtributo = parseInt(numeroAtributo);  
+			if (numeroAtributo > maior) { 
+				maior = numeroAtributo;
+			}
+		}
+		
+		maior++;
+		numeroAtributo = maior;
+		
+		var cc_attribute_name = "newsettings[cc_attribute_name_" + numeroAtributo + "]";
+		var cc_attribute_ldapname = "newsettings[cc_attribute_ldapname_" + numeroAtributo + "]";
+		var cc_attribute_type = "newsettings[cc_attribute_type_" + numeroAtributo + "]";
+		
+		var pool = document.getElementById("cc_attribute_fields");
+		var btn = document.getElementById("c_attribute_box_adder"); // nome do id definido no template.
+		
+		var newDiv = document.createElement("div");
+		newDiv.setAttribute("class", "cc_attribute");
+		
+		var labelNome = document.createElement("label");
+		labelNome.appendChild(document.createTextNode(stringNome));
+		
+		var formularioNome = document.createElement("input");
+		formularioNome.setAttribute("type", "text");
+		formularioNome.setAttribute("name", cc_attribute_name);
+		formularioNome.setAttribute("value", "");
+		
+		var labelCorrespondenteLdap = document.createElement("label");
+		labelCorrespondenteLdap.appendChild(document.createTextNode(stringCorrespLdap));
+		
+		var formularioLdap = document.createElement("input");
+		formularioLdap.setAttribute("type", "text");
+		formularioLdap.setAttribute("name", cc_attribute_ldapname);
+		formularioLdap.setAttribute("value", "");
+		
+		var labelTipo = document.createElement("label");
+		labelTipo.appendChild(document.createTextNode(stringTipo));
+		
+		var selectTipos = document.createElement("select");
+		selectTipos.setAttribute("name", cc_attribute_type);
+			var optionTexto = document.createElement("option");
+			optionTexto.setAttribute("value", "text");
+			optionTexto.setAttribute("selected", "selected");
+			optionTexto.innerHTML = stringTexto + " ";
+		
+			var optionMultivalorado = document.createElement("option");
+			optionMultivalorado.setAttribute("value", "multivalues");
+			optionMultivalorado.innerHTML = stringMultivalorado + " ";
+			
+		selectTipos.appendChild(optionTexto);
+		selectTipos.appendChild(optionMultivalorado);
+				
+
+		var imagem = document.createElement("img");
+		imagem.setAttribute("type", "image");
+		imagem.setAttribute("src", "contactcenter/templates/default/images/cc_x.png");
+		imagem.setAttribute("alt", "Excluir Campo ");
+		imagem.setAttribute("style", "width: 15px; height: 14px; cursor: pointer; position: relative; top: 3px;");
+		imagem.setAttribute("onclick", "javascript:cc_attribute_delete(this)");
+				
+		newDiv.appendChild(labelNome);
+		newDiv.appendChild(formularioNome);
+		newDiv.appendChild(labelCorrespondenteLdap);
+		newDiv.appendChild(formularioLdap);
+		newDiv.appendChild(labelTipo);
+		newDiv.appendChild(selectTipos);
+		newDiv.appendChild(document.createTextNode(" "));
+		newDiv.appendChild(imagem);
+
+		pool.appendChild(newDiv);
+	}
+	
+	/*
+	 * @function cc_attribute_clear(form)
+	 * @abstract Exclui uma tupla e de campos, onde e é uma referência ao elemento HTML (div) container da tupla  
+	 * @author Prognus software livre - http://www.prognus.com.br
+	 * @param e
+	 * 
+	 */
+	function cc_attribute_delete(e) 
+	{
+			var tupla = e.parentNode;
+			
+			var inputs = tupla.getElementsByTagName("input");
+
+				inputs[0].value = "";
+				inputs[1].value = "";
+				
+				var select = tupla.getElementsByTagName("select");
+				select[0].innerHTML = "<option value=\"\" selected=\"selected\"></option>";
+				
+			tupla.style.visible = "hidden";
+			tupla.style.display = "none";
+		
+//		e.parentNode.parentNode.removeChild(e.parentNode);
+	}
Index: /sandbox/2.2.0.2/contactcenter/js/ccAddGroup.js
===================================================================
--- /sandbox/2.2.0.2/contactcenter/js/ccAddGroup.js	(revision 4477)
+++ /sandbox/2.2.0.2/contactcenter/js/ccAddGroup.js	(revision 4502)
@@ -37,4 +37,6 @@
 		this.group_id = Element('group_id');
 				
+		this.old_contacts_in_list = new Array();
+		
 		ccAGWinHeight = 'ccAGWinHeightMO';
 
@@ -154,8 +156,11 @@
 		
 		sdata[0] = this.title.value;
-		var contacts = new Array();				
+		var contacts = new Array();
+		var old_contacts = new Array();
 		
 		for (j =0; j < this.contact_in_list.length; j++)
-			contacts[j] = this.contact_in_list.options[j].value;			
+			contacts[j] = this.contact_in_list.options[j].value;
+		for (i = 0; i < this.old_contacts_in_list.length; i++)
+			old_contacts[i] = this.old_contacts_in_list[i];
 		
 		if(!this.title.value) {
@@ -171,5 +176,6 @@
 
 		sdata[1] = contacts;		
-		sdata[2] = this.group_id.value == 'undefined' ? 	sdata[2] = 0 : sdata[2]  = this.group_id.value; 						
+		sdata[2] = this.group_id.value == 'undefined' ? 	sdata[2] = 0 : sdata[2]  = this.group_id.value; 	
+		sdata[3] = old_contacts;
 		var sdata = 'add='+escape(serialize(sdata));
 		Connector.newRequest('cAddGroup.Send', CC_url+'add_group', 'POST', handler, sdata);
@@ -200,4 +206,14 @@
 		this.title.value = '';				
 	}
+	
+	cAddGroup.prototype.openEditWindow = function()
+	{
+		var list_old_contacts = Element('contact_in_list');
+		for (var i = 0; i < list_old_contacts.length; i++)
+		{
+			this.old_contacts_in_list[i] = list_old_contacts.options[i].value;
+		}
+		this.window.open();
+	};
 	
 	/* Função para remover contato da lista */	
Index: /sandbox/2.2.0.2/contactcenter/js/cc.js
===================================================================
--- /sandbox/2.2.0.2/contactcenter/js/cc.js	(revision 4500)
+++ /sandbox/2.2.0.2/contactcenter/js/cc.js	(revision 4502)
@@ -592,5 +592,5 @@
 		}
                 ccAddGroup.setSelectedSourceLevel(ccTree.actualLevel);
-		ccAddGroup.window.open();
+		ccAddGroup.openEditWindow();
 	};
 		
@@ -888,4 +888,9 @@
  * Função que retorna os grupos que foram anteriormente selecionados, adicionados ou removidos pelo
  * usuário. O formato retornado é um array contendo:
+ * ['previous_selected'] {
+ * 	[id_group] {
+ * 		'id_group' 		=> o ID do grupo
+ * 		'title'			=> o título do grupo
+ * 	}
  * ['added'] {
  * 	[id_group] {
@@ -908,4 +913,5 @@
 	var removed_groups = diffContactIDArray(CC_initial_selected_grps, selected_groups);
 	var groups = new Array();
+	groups['previous_selected'] = CC_initial_selected_grps;
 	groups['added'] = added_groups;
 	groups['removed'] = removed_groups;
Index: /sandbox/2.2.0.2/contactcenter/templates/default/contact_details.tpl
===================================================================
--- /sandbox/2.2.0.2/contactcenter/templates/default/contact_details.tpl	(revision 4502)
+++ /sandbox/2.2.0.2/contactcenter/templates/default/contact_details.tpl	(revision 4502)
@@ -0,0 +1,78 @@
+{cc_api}
+
+<input id="cc_contact_details_title" type="hidden" value="{cc_contact_details_title}">
+<input id="cc_contact_details_attr_name" type="hidden" value="{cc_contact_details_attr_name}">
+<input id="cc_contact_details_attr_value" type="hidden" value="{cc_contact_details_attr_value}">
+<input id="cc_contact_details_no_fields" type="hidden" value="{cc_contact_details_no_fields}">
+
+<div id="cc_contact_details_content" style="position: absolute; visibility: hidden">
+	<table border="0"  cellpadding="0" cellspacing="0" width="100%">
+		<tr>
+		<td>
+		<div id="id_cc_contact_details_fields" style="position: center; width:500px;height:270px; border: 1px solid #999;overflow:auto">
+		</div>
+		</td>
+		</tr>
+		<tr>
+		<td>
+		<div id="ccCDFuncitons" style="border: 0px solid black; width: 220px; height: 20px">
+			<input title="{cc_contact_details_close}" type="button" onclick="javascript:closeContactDetails()" value="{cc_contact_details_close}" style="position: absolute; left: 185px; width: 60px" />
+		</div>
+		</td>
+		</tr>
+	</table>
+</div>
+
+<script type="text/javascript">
+<!--
+//	Overloading some methods for fix cursor problem in Firefox.
+	if(!is_ie) { 
+		dJSWin.prototype.close = function() {		
+			dJSWin.state = 0;
+			dd.elements[this.title.id].hide();
+			if ( dd_div = document.getElementById('divScrollMain'))	
+				Element("divScrollMain").style.overflow = 'auto';	
+		}
+		dJSWin.prototype.open = function() {
+			this.moveTo(window.innerWidth/2 + window.pageXOffset - dd.elements[this.title.id].w/2,
+			    window.innerHeight/2 + window.pageYOffset - dd.elements[this.clientArea.id].h/2);
+			dd.elements[this.title.id].maximizeZ();
+			dd.elements[this.title.id].show();
+			if ( dd_div = document.getElementById('divScrollMain'))
+				dd_div.style.overflow = 'hidden';
+		}
+	}	
+		
+	var contactdetails_onload = document.body.onload;
+	var contactdetailsWin;
+
+	__cdWin = function(e)
+	{
+		
+		contactdetailsWin = new dJSWin({'id': 'cc_contact_details_window',
+		             'content_id': 'cc_contact_details_content',
+					 'win_class': 'row_off',
+					 'width': '500px',
+					 'height': '295px',
+					 'title_color': '#3978d6',
+					 'title': Element('cc_contact_details_title').value,
+					 'title_text_color': 'white',
+					 'button_x_img': Element('cc_phpgw_img_dir').value+'/winclose.gif',
+					 'border': true});
+
+		contactdetailsWin.draw();
+
+	};
+
+	if (is_ie) // || is_moz1_6)
+	{
+			
+		document.body.onload = function(e) { setTimeout('__cdWin()', 10); contactdetails_onload ? setTimeout('contactdetails_onload()'): false;};
+	}
+	else
+	{
+//		__cdWin();
+	}
+
+//-->
+</script>
