Index: trunk/prototype/services/ImapServiceAdapter.php
===================================================================
--- trunk/prototype/services/ImapServiceAdapter.php	(revision 5826)
+++ trunk/prototype/services/ImapServiceAdapter.php	(revision 5959)
@@ -2,6 +2,4 @@
 
 include_once ROOTPATH."/../expressoMail1_2/inc/class.imap_functions.inc.php";
-require_once ROOTPATH.'/library/uuid/class.uuid.php';
-
 
 class ImapServiceAdapter extends imap_functions/* implements Service*/
@@ -19,5 +17,4 @@
     public function find( $URI, $justthese = false, $criteria = false )
 	{ 
-		//require_once dirname(__FILE__) . '/../api/controller.php';
 		$context = $justthese['context'];
 		$URI = $URI['concept'];
@@ -63,8 +60,55 @@
 
 				$start = $limit * $page - $limit;
-
 				// do not put $limit*($page - 1)
 				//end: for grid
-
+				
+				
+				/**
+				 * Trata o caso específico de retorno do atributo messageId
+				 *
+				 * TODO - refazer todo a operação find do conceito message, uma vez que esta 
+				 * foi desenvolvida quando a nova API ainda era muito imatura e se encontra 
+				 * muito acoplada à estrutura de retorno esperada pelo plugin jqGrid
+				 */
+				if ( $justthese ) 
+				{
+					if ($justthese[0] == 'messageId') {
+						$map = array(
+							'folderName' => array(),
+							'messageNumber' => array()
+						);
+						
+						self::parseFilter($criteria["filter"], &$map);
+						
+						if (count($map['folderName']) == 0) {
+							$folders = $this->get_folders_list();
+							foreach ($folders as $folder)
+								if (isset($folder['folder_id'])) 
+									$map['folderName'][] = $folder['folder_id'];
+						}
+						
+						$result = array();
+						foreach ($map['folderName'] as $folder) {
+							$this->mbox = $this->open_mbox($folder);
+
+							/**
+							 * Se não foi passado messageNumber no filtro, 
+							 * busca todas as mensagens de cada pasta
+							 */
+							$messages = empty($map['messageNumber']) ? '1:*' : implode(',', $map['messageNumber']);
+							$sequenceType = empty($map['messageNumber']) ? 0 : FT_UID;
+
+							$headers = imap_fetch_overview($this->mbox, $messages, $sequenceType);
+							foreach ($headers as $h) {
+								$result[] = array ( 'messageId' => $h->message_id );
+							}
+														
+							imap_close($this->mbox);
+							$this->mbox = false;
+						}
+						return $result;
+					}
+				}
+				
 				if( $filter )
 				{
@@ -94,5 +138,6 @@
 
 					foreach( $result as $i => $val )
-						$result[$i] = unserialize( $val );
+					$result[$i] = unserialize( $val );
+
 				}
 				else
@@ -110,19 +155,19 @@
 				}
 				//return var_export($result);
-				
+
 				$response = array( "page" => $page, "total" => $total_pages, "records" => $count );
-								
+				
 				for ($i=0; $i<count($result); $i++)
 				{
-					$flags_enum = array('Unseen'=> 1,  'Answered'=> 1, 'Forwarded'=> 1, 'Flagged'=> 1, 'Recent'=> 1, 'Draft'=> 1 );
+					$flags_enum = array('Recent', 'Unseen',  'Answered',  'Draft',  'Deleted', 'Flagged');
 
 					foreach ($flags_enum as $key => $flag)
 					{
-						if ( !isset($result[$i][$key]) || !trim($result[$i][$key]) || trim($result[$i][$key]) == '') 
-							$flags_enum[$key] = 0;
-							//unset($flags_enum[$key]);
+						if ( !isset($result[$i][$flag]) || !trim($result[$i][$flag]) || trim($result[$i][$flag]) == '') 
+							unset($flags_enum[$key]);
 
 						unset($result[$i][$flag]);
-					}					
+					}
+
 					if (array_key_exists($i, $result))
 					{
@@ -131,10 +176,9 @@
 						$response["rows"][$i]['flags'] = implode(',', $flags_enum);
 						$response["rows"][$i]['size'] = $response["rows"][$i]['Size'];
-						$response["rows"][$i]['folder'] = $folder_name;
-						
 						//$response["rows"][$i]['udate'] = ( $result[$i]['udate'] + $this->functions->CalculateDateOffset()  * 1000 );
 						unset($response["rows"][$i]['Size']);
 					}
-				 }					 
+				 }
+
 				return $this->to_utf8($response);
 			}
@@ -214,67 +258,94 @@
 			
 			case 'followupflagged':
-			{
-			
+			{			
 				$result = array ( );
-				if (isset($criteria["filter"]) && is_array($criteria['filter'])) {
-					//TODO - melhorar o tratamento do filter com a lista de todos os labelIds dado pelo interceptor
-					$map = array(
-						'id' => array(),
-						'folderName' => array(),
-						'messageNumber' => array()
-					);
-					
-					self::parseFilter($criteria["filter"], &$map);
-					
-					if (empty($map['folderName'])) {
-						$folders = $this->get_folders_list();
-						foreach ($folders as $folder)
-							if (isset($folder['folder_id'])) 
-								$map['folderName'][] = $folder['folder_id'];
-					}
-
-					foreach ($map['folderName'] as $folder) {
-						$this->mbox = $this->open_mbox($folder);
-						
-						/**
-						 * Caso não tenha sido passado id no filtro
-						 */
-						if (!$map['id']) {
-							$messagesFlaggeds = imap_search($this->mbox, 'UNDELETED KEYWORD "$Followupflagged"', SE_UID);
-
-							foreach ($messagesFlaggeds as $messageFlagged) {
-								if (count($map['messageNumber']) > 0 && !in_array($messageFlagged, $map['messageNumber']))
-									continue;
-									
-								$result[] = array (
-									'folderName' => $folder,
-									'messageNumber' => $messageFlagged
-								);
-							}
-							
-						} else {
-							foreach ($map['id'] as $followupflagged) {
-								$messagesFlaggeds = imap_search($this->mbox, 'UNDELETED KEYWORD "$Followupflag'.$followupflagged.'"', SE_UID);
-								
-								foreach ($messagesFlaggeds as $messageFlagged) {
-									if (count($map['messageNumber']) > 0 && !in_array($messageFlagged, $map['messageNumber']))
-										continue;
-										
-									$result[] = array (
-										'id' => $folder . '/' . $messageFlagged . '#' . $followupflagged, 
-										'folderName' => $folder,
-										'messageNumber' => $messageFlagged
-									);
-								}
+
+				$map = array(
+					//'id' => array(),
+					'folderName' => array(),
+					'messageNumber' => array(),
+					'messageId' => array()
+				);
+				
+				self::parseFilter($criteria["filter"], &$map);
+	
+				if (empty($map['folderName'])) {
+					$folders = $this->get_folders_list();
+					foreach ($folders as $folder)
+						if (isset($folder['folder_id'])) 
+							$map['folderName'][] = $folder['folder_id'];
+				}
+				
+				$messagesIds = $map['messageId'];
+
+				foreach ($map['folderName'] as $folder) {
+					$messages = array();
+					
+					$this->mbox = $this->open_mbox($folder);
+				
+					/**
+					 * Se é uma busca por messageId
+					 */
+					if (!empty($map['messageId'])) {
+							
+						foreach ($messagesIds as $k => $v) {
+							$r = imap_search($this->mbox, 'UNDELETED KEYWORD "$Followupflagged" TEXT "'.$v.'"', SE_UID);
+
+							if ($r) {
+								$messages = $messages + $r;
+								unset($messagesIds[$k]);	
 							}
 						}
-						
-						imap_close($this->mbox);
-						$this->mbox = false;
-					}
-				}
-						
-				return $result;				
-			}
+
+					/**
+					 * Se é uma busca por messageNumber.
+					 * Lembrando que, neste caso, só deve ser suportada uma única pasta no filtro.
+					 */
+					} else {
+						$messages = imap_search($this->mbox, 'UNDELETED KEYWORD "$Followupflagged"', SE_UID);
+					}
+
+					/**
+					 * Se é uma busca por messageId, deve ser comparado com os messageNumbers 
+					 * passados no filtro, se houverem.
+					 */
+					if (!empty($map['messageNumber'])) {
+						foreach ($messages as $k => $m)
+							if (!in_array($m, $map['messageNumber']))
+								unset($messages[$k]);
+					}
+
+					/**
+					 * Adicionar demais atributos às mensagens para retorno
+					 */
+					foreach ($messages as $k => $m) {
+						$headers = imap_fetch_overview($this->mbox, $m, FT_UID);
+							
+						$result[] = array (
+							'messageId' => $headers[0]->message_id,
+							'messageNumber' => $m,
+							'folderName' => $folder
+						);
+					}
+
+					imap_close($this->mbox);
+					$this->mbox = false;
+					
+					/**
+					 * Se é uma busca por messageId e todos os messageIds foram econstrados:
+					 * Stop searching in all folders
+					 */
+					if (!empty($map['messageId']) && empty($messagesIds))
+						break;
+				}
+				
+				if ($this->mbox) {
+					imap_close($this->mbox);
+					$this->mbox = false;
+				}
+
+				return $result;
+				
+			} //CASE 'followupflag'
 		}
     }
@@ -324,26 +395,75 @@
 			case 'followupflagged':
 			{
-				/**
-				 * id looks like 'folder/subfolder/subsubfolder/65#13', meaning messageId#followupflaggedId
+			
+				/** 
+				 * identifica se o formato de ID é "folder/subfolder/subsubfolder/<messageNumber>" ou "<message-id>"
 				 */
-				list($messageId, $followupflaggedId) = explode('#', $URI['id']);
-				$folderName = dirname($messageId);
-				$messageNumber = basename($messageId);
-				
+				$folderName = $messageNumber = false;
+				if(!($messageHasId = preg_match('/<.*>/', $URI['id']))) {
+					$folderName = dirname($URI['id']);
+					$messageNumber = basename($URI['id']);
+				}
+
 				$result = array();
-
-				if ($folderName && $messageNumber && $followupflaggedId) {
+				if ($folderName && $messageNumber) {
+
 					$this->mbox = $this->open_mbox($folderName);
-					$messagesFlaggeds = imap_search($this->mbox, 'UNDELETED KEYWORD "$Followupflag'.$followupflaggedId.'"', SE_UID);
-					
-					if (in_array($messageNumber, $messagesFlaggeds)) {
+					$r = imap_search($this->mbox, 'UNDELETED KEYWORD "$Followupflagged"', SE_UID);
+
+					if (in_array($messageNumber, $r)) {
+						$headers = imap_fetch_overview($this->mbox, $messageNumber, FT_UID);
+							
 						$result = array (
-							'id' => $URI['id'], 
-							'folderName' => $folderName,
-							'messageNumber' => $messageNumber
+							'messageId' => $headers[0]->message_id,
+							'messageNumber' => $messageNumber,
+							'folderName' => $folderName
 						);
 					}
+					
 					imap_close($this->mbox);
 					$this->mbox = false;
+				
+				} else {
+					/**
+					 * Busca pela mensagem com o messageId dado. Se uma pasta foi passada, busca nela,
+					 * senão busca em todas.
+					 */
+					
+					$folders = array ();
+					if ($folderName) {
+						$folders = array ($folderName);
+					} else {
+						$folder_list = $this->get_folders_list();
+						foreach ($folder_list as $folder)
+							if (isset($folder['folder_id'])) 
+								$folders[] = $folder['folder_id'];
+					}
+					
+					foreach ($folders as $folder) {
+						
+						$this->mbox = $this->open_mbox($folder);
+						
+						if ($messages = imap_search($this->mbox, 'UNDELETED KEYWORD "$Followupflagged" TEXT "'.$URI['id'].'"', SE_UID)) {
+				
+							$result = array (
+								'messageId' => $URI['id'],
+								'messageNumber' => $messages[0],
+								'folderName' => $folder
+							);
+							
+							/**
+							 * Stop searching in all folders
+							 */
+							break;
+						}
+						
+						imap_close($this->mbox);
+						$this->mbox = false;
+					}
+				}
+				
+				if ($this->mbox) {
+					imap_close($this->mbox);
+					$this->mbox = false;
 				}
 				
@@ -353,5 +473,5 @@
     }
 
-    public function create( $URI, $data)
+    public function create($URI, &$data)
     {               
 		switch( $URI['concept'] )
@@ -372,11 +492,15 @@
 			case 'followupflagged':
 			{
-				//deve ser gravado no banco primeiro, obtido o id e, depois, gravado no imap passando o id no parametro $data
-				if (isset($data['folderName']) && isset($data['messageNumber']) && isset($data['id'])) {
-					list($messageId, $followupflaggedId) = explode('#', $data['id']);
+				//deve ser gravado primeiro no imap, obtido o message-id e, depois gravado no banco
+				
+				if (isset($data['folderName']) && isset($data['messageNumber'])) {
 					
 					$this->mbox = $this->open_mbox($data['folderName']);
-					$s = imap_setflag_full($this->mbox, $data['messageNumber'], '$Followupflagged $Followupflag' . $followupflaggedId, ST_UID);
-										
+					$s = imap_setflag_full($this->mbox, $data['messageNumber'], '$Followupflagged', ST_UID);
+					
+					$headers = imap_fetch_overview($this->mbox, $data['messageNumber'], FT_UID);
+					
+					$data['messageId'] = $headers[0]->message_id;
+							
 					imap_close($this->mbox);
 					$this->mbox = false;
@@ -384,4 +508,38 @@
 					return ($s) ? $data : array();
 
+				} else if (isset($data['messageId'])) {
+					/**
+					 * Busca pela mensagem com o messageId dado. Se uma pasta foi passada, busca nela,
+					 * senão busca em todas.
+					 */
+					$folders = array ();
+					if (isset($data['folderName'])) {
+						$folders = array ($data['folderName']);
+					} else {
+						$folder_list = $this->get_folders_list();
+						foreach ($folder_list as $folder)
+							if (isset($folder['folder_id'])) 
+								$folders[] = $folder['folder_id'];
+					}
+					
+					foreach ($folders as $folder) {
+						
+						$this->mbox = $this->open_mbox($folder);
+						if ($messages = imap_search($this->mbox, 'TEXT "'.$data['messageId'].'"', SE_UID)) {
+							
+							$s = imap_setflag_full($this->mbox, $messages[0], '$Followupflagged', ST_UID);
+							
+							imap_close($this->mbox);
+							$this->mbox = false;
+							
+							/**
+							 * Stop searching in all folders
+							 */
+							return $data;
+						}
+						
+						imap_close($this->mbox);
+						$this->mbox = false;
+					}
 				}
 				return array ();
@@ -390,108 +548,108 @@
 			case 'message':
 			{
+				require_once ROOTPATH.'/library/uuid/class.uuid.php';
+				
 				$GLOBALS['phpgw_info']['flags'] = array( 'noheader' => true, 'nonavbar' => true,'currentapp' => 'expressoMail1_2','enable_nextmatchs_class' => True );
-                                $return = array();
-				
-                                require_once dirname(__FILE__) . '/../../services/class.servicelocator.php';
-                                $mailService = ServiceLocator::getService('mail');
-
-                                $msg_uid = $data['msg_id'];
-                                $body = $data['body'];
-                                $body = str_replace("%nbsp;","&nbsp;",$body);
-                                $body = html_entity_decode ( $body, ENT_QUOTES , 'ISO-8859-1' );					
-
-                                $folder = mb_convert_encoding($data['folder'], "UTF7-IMAP","ISO-8859-1, UTF-8");
-                                $folder = @eregi_replace("INBOX[/.]", "INBOX".$this->imap_delimiter, $folder);
+				$return = array();
+
+				require_once dirname(__FILE__) . '/../../services/class.servicelocator.php';
+				$mailService = ServiceLocator::getService('mail');
+
+				$msg_uid = $data['msg_id'];
+				$body = $data['body'];
+				$body = str_replace("%nbsp;","&nbsp;",$body);
+				$body = preg_replace("/\n/"," ",$body);
+				$body = preg_replace("/\r/","" ,$body);
+				$body = html_entity_decode ( $body, ENT_QUOTES , 'ISO-8859-1' );					
+
+				$folder = mb_convert_encoding($data['folder'], "UTF7-IMAP","ISO-8859-1, UTF-8");
+				$folder = @eregi_replace("INBOX[/.]", "INBOX".$this->imap_delimiter, $folder);
 
 				/**
-				 * Gera e preenche o field Message-Id do header
-				 */
+				* Gera e preenche o field Message-Id do header
+				*/
 				$mailService->addHeaderField('Message-Id', UUID::generate( UUID::UUID_RANDOM, UUID::FMT_STRING ) . '@Draft');
-								
-                                $mailService->addTo(mb_convert_encoding(($data['input_to']), 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
-                                $mailService->addCc( mb_convert_encoding(($data['input_cc']), 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
-                                $mailService->addBcc(mb_convert_encoding(($data['input_cco']), 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
-                                $mailService->setSubject(mb_convert_encoding(($data['input_subject']), 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
-				
-                                if(isset($data['input_important_message']))
-                                        $mailService->addHeaderField('Importance','High');
-
-                                if(isset($data['input_return_receipt']))
-                                        $mailService->addHeaderField('Disposition-Notification-To', Config::me('mail'));
-
-                                $isHTML = ( isset($data['type']) && $data['type'] == 'html' )?  true : false;
-                                                                  
-                                if (!$body) $body = ' ';
-                                
-
-                                $mbox_stream = $this->open_mbox($folder);
-
-                                $attachment = json_decode($data['attachments'],TRUE);
-                                
-
-                                foreach ($attachment as &$value) 
-                                {
-
-                                    if((int)$value > 0) //BD attachment
-                                    {
-                                         $att = Controller::read(array('id'=> $value , 'concept' => 'mailAttachment'));
-                                         
-                                         
-                                         if($att['disposition'] == 'embedded')
-                                         {
-                                             $body = str_replace('"../prototype/getArchive.php?mailAttachment='.$att['id'].'"', $att['name'], $body);
-                                             $mailService->addStringImage(base64_decode($att['source']), $att['type'], $att['name']);
-                                         }
-                                         else
-                                             $mailService->addStringAttachment(base64_decode($att['source']), $att['name'], $att['type'], 'base64', isset($att['disposition']) ? $att['disposition'] :'attachment' );
-                                         
-                                         unset($att);
-                                    }
-                                    else
-                                    {
-                                        $value = json_decode($value, true);
-                                        
-                                        switch ($value['type']) {
-                                            case 'imapPart':
-                                                    $att = $this->getForwardingAttachment($value['folder'],$value['uid'], $value['part']);
-                                                    if(strstr($body,'<img src="./inc/get_archive.php?msgFolder='.$value['folder'].'&msgNumber='.$value['uid'].'&indexPart='.$value['part'].'" />') !== false)//Embeded IMG
-                                                    {    
-                                                        $body = str_ireplace('<img src="./inc/get_archive.php?msgFolder='.$value['folder'].'&msgNumber='.$value['uid'].'&indexPart='.$value['part'].'" />' , '<img src="'.$att['name'].'" />', $body);
-                                                        $mailService->addStringImage($att['source'], $att['type'], $att['name']);
-                                                    }
-                                                    else
-                                                        $mailService->addStringAttachment($att['source'], $att['name'], $att['type'], 'base64', isset($att['disposition']) ? $att['disposition'] :'attachment' );
-                                                    unset($att);
-                                                break;
-                                              case 'imapMSG':
-                                                    $sub =  $value['name'] ? $value['name'].'.eml' :'no title.eml';
-                                                    $mbox_stream = $this->open_mbox($value['folder']);
-                                                    $rawmsg = $this->getRawHeader($value['uid']) . "\r\n\r\n" . $this->getRawBody($value['uid']);
-                                                    $mailService->addStringAttachment($rawmsg, $sub, 'message/rfc822', '7bit', 'attachment' );
-                                                    unset($rawmsg);
-                                                break;
-
-                                            default:
-                                                break;
-                                        }
-                                    }
-
-                                }
-                                
-                                if($isHTML) $mailService->setBodyHtml($body); else $mailService->setBodyText($body);
-  
-                                if(imap_append($mbox_stream, "{".$this->imap_server.":".$this->imap_port."}".$folder, $mailService->getMessage(), "\\Seen \\Draft"))
-                                {
-                                    $status = imap_status($mbox_stream, "{".$this->imap_server.":".$this->imap_port."}".$folder, SA_UIDNEXT);
-                                    $return['id'] = $status->uidnext - 1;
-                                        
-                                    if($data['uidsSave'] )
-                                        $this->delete_msgs(array('folder'=> $folder , 'msgs_number' => $data['uidsSave']));
-                       
-                                }
-                 
-                                if($mbox_stream) imap_close($mbox_stream);
-
-                                return $return;
+
+				$mailService->addTo($data['input_to']);
+				$mailService->addCc( $data['input_cc']);
+				$mailService->addBcc($data['input_cco']);
+				$mailService->setSubject($data['input_subject']);
+				if(isset($data['input_important_message']))
+					$mailService->addHeaderField('Importance','High');
+
+				if(isset($data['input_return_receipt']))
+					$mailService->addHeaderField('Disposition-Notification-To', Config::me('mail'));
+
+				$isHTML = ( ( array_key_exists( 'type', $data ) && in_array( strtolower( $data[ 'type' ] ), array( 'html', 'plain' ) ) ) ? strtolower( $data[ 'type' ] ) != 'plain' : true );
+
+				if (!$body) $body = ' ';
+
+
+				$mbox_stream = $this->open_mbox($folder);
+
+				$attachment = json_decode($data['attachments'],TRUE);
+
+
+				foreach ($attachment as &$value) 
+				{
+					if((int)$value > 0) //BD attachment
+					{
+						$att = Controller::read(array('id'=> $value , 'concept' => 'mailAttachment'));
+
+						if($att['disposition'] == 'embedded')
+						{
+							$body = str_replace('"../prototype/getArchive.php?mailAttachment='.$att['id'].'"', $att['name'], $body);
+							$mailService->addStringImage(base64_decode($att['source']), $att['type'], $att['name']);
+						}
+						else
+							$mailService->addStringAttachment(base64_decode($att['source']), $att['name'], $att['type'], 'base64', isset($att['disposition']) ? $att['disposition'] :'attachment' );
+
+						unset($att);
+					}
+					else
+					{
+						$value = json_decode($value, true);
+
+						switch ($value['type']) {
+							case 'imapPart':
+								$att = $this->getForwardingAttachment($value['folder'],$value['uid'], $value['part']);
+								if(strstr($body,'<img src="./inc/get_archive.php?msgFolder='.$value['folder'].'&msgNumber='.$value['uid'].'&indexPart='.$value['part'].'" />') !== false)//Embeded IMG
+								{    
+									$body = str_ireplace('<img src="./inc/get_archive.php?msgFolder='.$value['folder'].'&msgNumber='.$value['uid'].'&indexPart='.$value['part'].'" />' , '<img src="'.$att['name'].'" />', $body);
+									$mailService->addStringImage($att['source'], $att['type'], $att['name']);
+								}
+								else
+									$mailService->addStringAttachment($att['source'], $att['name'], $att['type'], 'base64', isset($att['disposition']) ? $att['disposition'] :'attachment' );
+								unset($att);
+								break;
+							case 'imapMSG':
+								$sub =  $value['name'] ? $value['name'].'.eml' :'no title.eml';
+								$mbox_stream = $this->open_mbox($value['folder']);
+								$rawmsg = $this->getRawHeader($value['uid']) . "\r\n\r\n" . $this->getRawBody($value['uid']);
+								$mailService->addStringAttachment($rawmsg, $sub, 'message/rfc822', '7bit', 'attachment' );
+								unset($rawmsg);
+								break;
+
+							default:
+							break;
+						}
+					}
+
+				}
+
+				if($isHTML) $mailService->setBodyHtml($body); else $mailService->setBodyText($body);
+
+				if(imap_append($mbox_stream, "{".$this->imap_server.":".$this->imap_port."}".$folder, $mailService->getMessage(), "\\Seen \\Draft"))
+				{
+					$status = imap_status($mbox_stream, "{".$this->imap_server.":".$this->imap_port."}".$folder, SA_UIDNEXT);
+					$return['id'] = $status->uidnext - 1;
+
+					if($data['uidsSave'] )
+					$this->delete_msgs(array('folder'=> $folder , 'msgs_number' => $data['uidsSave']));
+				}
+
+				if($mbox_stream) imap_close($mbox_stream);
+
+				return $return;
 			}
 		}
@@ -518,23 +676,67 @@
 			case 'followupflagged':
 			{
-				list($messageId, $followupflaggedId) = explode('#', $URI['id']);
-				
-				$folderName = dirname($messageId);
-				$messageNumber = basename($messageId);
 			
-				if ($folderName && $messageNumber && $followupflaggedId) {
+				/** 
+				 * identifica se o formato de ID é "folder/subfolder/subsubfolder/<messageNumber>" ou "<message-id>"
+				 */
+				$folderName = $messageNumber = false;
+				if(!($messageHasId = preg_match('/<.*>/', $URI['id']))) {
+					$folderName = dirname($URI['id']);
+					$messageNumber = basename($URI['id']);
+				}
+				
+				/**
+				 * TODO - efetuar o parsing do $criteria e obter a pasta passada
+				 */
+				$map = array(
+					'folderName' => array(),
+					'messageNumber' => array(),
+					'messageId' => array()
+				);
+			
+				if ($folderName && $messageNumber) {
 
 					$this->mbox = $this->open_mbox($folderName);
-					$f1 = imap_clearflag_full($this->mbox, $messageNumber, '$Followupflag' . $followupflaggedId, ST_UID);
-
-					/**
-					 * implementa a possibilidade de listar todas as mensagens sinalizadas através da busca
-					 */
-					$f2 = imap_clearflag_full($this->mbox, $messageNumber, '$Followupflagged', ST_UID);
+					$s = imap_clearflag_full($this->mbox, $messageNumber, '$Followupflagged', ST_UID);
 
 					imap_close($this->mbox, CL_EXPUNGE);
 					$this->mbox = false;
 					
-					return ($f1 && $f2);
+					return $s;
+				} else {
+					/**
+					 * Busca pela mensagem com o messageId dado. Se uma pasta foi passada, busca nela,
+					 * senão busca em todas.
+					 */
+					
+					$folders = array ();
+					if (isset($map['folderName'])) {
+						$folders = $map['folderName'];
+					} else {
+						$folder_list = $this->get_folders_list();
+						foreach ($folder_list as $folder)
+							if (isset($folder['folder_id'])) 
+								$folders[] = $folder['folder_id'];
+					}
+					
+					foreach ($folders as $folder) {
+						
+						$this->mbox = $this->open_mbox($folder);
+						if ($messages = imap_search($this->mbox, 'TEXT "'.$URI['id'].'"', SE_UID)) {
+							
+							$s = imap_clearflag_full($this->mbox, $messages[0], '$Followupflagged', ST_UID);
+							
+							imap_close($this->mbox, CL_EXPUNGE);
+							$this->mbox = false;
+							
+							/**
+							 * Stop searching in all folders
+							 */
+							return $s;
+						}
+						
+						imap_close($this->mbox);
+						$this->mbox = false;
+					}
 				}
 				
@@ -552,5 +754,5 @@
     {
 		/**
-		 * Os únicos atributos que podem ser alterados no IMAP são folderName e messageId,
+		 * Os únicos atributos da sinalização presentes no IMAP são folderName, messageNumber e messageId,
 		 * porém a operação de update desses atributos não faz sentido para o usuário da DataLayer,
 		 * pois na prática elas são executadas através das operações de CREATE e DELETE.
Index: trunk/prototype/config/followupflagged.ini
===================================================================
--- trunk/prototype/config/followupflagged.ini	(revision 5817)
+++ trunk/prototype/config/followupflagged.ini	(revision 5959)
@@ -2,38 +2,23 @@
 PostgreSQL.concept = expressomail_message_followupflag
 
+[PostgreSQL.before.create]
+doImapCreate = modules/mail/interceptors/Helpers.php
+
+[PostgreSQL.after.read]
+doImapRead = modules/mail/interceptors/Helpers.php
+
+[PostgreSQL.after.delete]
+doImapDelete = modules/mail/interceptors/Helpers.php
 
 [PostgreSQL.before.find]
-clearFilterAtFind = modules/mail/interceptors/Helpers.php
+reFilterFind = modules/mail/interceptors/Helpers.php
 
 [PostgreSQL.after.find]
 doImapFind = modules/mail/interceptors/Helpers.php
 
-[after.find]
-deepnessFollowupflaggeds = modules/mail/interceptors/Helpers.php
-
-[Imap.before.create]
-letFollowupflaggedKeepUnique = modules/mail/interceptors/Helpers.php
-
-[PostgreSQL.after.create]
-doImapCreate = modules/mail/interceptors/Helpers.php
-
-[PostgreSQL.before.read]
-stripURIAttrs = modules/mail/interceptors/Helpers.php
-
-[PostgreSQL.after.read]
-doImapRead = modules/mail/interceptors/Helpers.php
-
-[PostgreSQL.before.delete]
-doImapDelete = modules/mail/interceptors/Helpers.php
-
-
-[PostgreSQL.before.update]
-stripURIAttrs = modules/mail/interceptors/Helpers.php
-;doImapUpdate = modules/mail/interceptors/Helpers.php
-
-
 [PostgreSQL.mapping]
-id = id
+id = id 
 followupflagId = followupflag_id
+messageId = message_id
 alarmDeadline = alarm_deadline
 doneDeadline = done_deadline
@@ -44,7 +29,7 @@
 
 [Imap.mapping]
-id = id
-followupflagId = followupflag_id
+;id = id
 folderName = folder_name
-messageNumber = message_id
-
+messageNumber = message_number
+messageId = message_id
+;TODO - modificar o nome de atributo de message_id para "Message-Id", que é como aparece no header da mensagem
Index: trunk/prototype/modules/mail/interceptors/Helpers.php
===================================================================
--- trunk/prototype/modules/mail/interceptors/Helpers.php	(revision 5909)
+++ trunk/prototype/modules/mail/interceptors/Helpers.php	(revision 5959)
@@ -69,4 +69,13 @@
 	}
 	
+	//label:before.create
+	public function verifyNameLabel(&$uri , &$params , &$criteria , $original){
+		$nameLabel = $params['name'];
+		$Labels = Controller::find(array('concept' => 'label'), false, array('filter' => array('i=', 'name', $nameLabel) ));
+		if($Labels){
+			Throw new Exception('JÃ¡ existe um marcador com esse nome.');
+		}
+	}
+		
 	public static function in_arrayr($needle, $haystack) {
 		//if(!is_array($haystack)) return false;
@@ -78,5 +87,4 @@
 		return false;
 	} 
-		
 	
 /**
@@ -84,66 +92,87 @@
  */ 
 
- 	//followupflag:before.find
-	public function addDefaultElementsFilter (&$uri , &$params , &$criteria , $original ){
-		//if (!self::in_arrayr('id', $criteria['filter'])) {
-			$defaultsFilter = array( 'IN' , 'id' , array('1','2','3','4','5','6') );
-			
-			if (isset($criteria['filter']) && $criteria['filter']!=NULL && count($criteria['filter']) != 0)
-				$criteria['filter'] = array( 'OR', $criteria['filter'], $defaultsFilter );
-			else
-				$criteria['filter'] =  $defaultsFilter;
-		//}
-	}
-	
-	//followupflagged:after.find
-	public function deepnessFollowupflaggeds( &$uri , &$result , &$criteria , $original ){                
-
-		if(isset($original['criteria']['deepness']))
-		{
-			foreach ($result as $i => $v)
-			{
-				if(isset($v['followupflagId']))
-				{
-					$followupflags = Controller::find(array('concept' => 'followupflag'), false, array('filter' => array('=', 'id', $v['followupflagId']) ));
-					
-					/**
-					 * Devido hÃ¡ inconsistencias na chamada do interceptor addDefaultElementsFilter (followupflag:before.find)
-					 * os followupflag defaults sÃ£o inseridos no retorno, por isso Ã© necessÃ¡rio procurar o objeto correto
-					 * atravÃ©s do id
-					 */
-					foreach ($followupflags as $followupflag) {
-						if ($v['followupflagId'] == $followupflag['id']) {
-							$result[$i]['followupflag'] = $followupflag;
-							break;
-						}
-					}
-				}
-				
-				if(isset($v['messageNumber']) && isset($v['folderName']))
-				{
-					$details = $original['criteria']['deepness'] == '1' ? 'headers' : 'all';
-					
-					$imapService = new imap_functions();
-					$message = $imapService->getMessages(array('messages' => array($v['folderName'] => array($v['messageNumber'])), 'details' => $details));
-					$result[$i]['message'] = $message[$v['folderName']][0];				
-				}     
-			}
-		}
-
+	//Remove as dependencias de uma followupflag 
+	public function clearAllFlaggedOfFollowupflag( &$uri , &$result , &$criteria , $original ){
+		//remove apenas se vier o id da Followupflag
+		if(isset($uri['id']))
+			Controller::deleteALL(array('concept' => 'followupflagged'), null , array('filter' => array('=' , 'followupflagId' , $uri['id'])));
+
+	}
+
+
+	//followupflagged:PostgreSQL.before.delete
+	public function doImapDelete( &$uri , &$params , &$criteria , $original ) {
+	
+		$imap_uri = $uri;
+		$imap_uri['service'] = 'Imap';
+		list($messageId, $uri['id']) = explode('#', $uri['id']);
+
+		$result = Controller::delete($imap_uri, $params, $imap_criteria);
+
+		if (!$result)
+			return false;
+	}
+	
+
+	
+		
+
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	//followupflagged:PostgreSQL.before.create
+	public function doImapCreate( &$uri , &$params , &$criteria , $original ) {	
+		
+		$imap_uri = $uri;
+		$imap_uri['service'] = 'Imap';
+
+		$params = Controller::create($imap_uri, $params);
+		
+		if (!$params)
+			return false;	
+	}
+	
+	//followupflagged:PostgreSQL.after.read
+	public function doImapRead( &$uri , &$result , &$criteria , $original ) {
+
+		if ($reusult) {
+			$imap_result = Controller::read(
+				array('concept' => 'followupflagged', 'service' => 'Imap'), 
+				false, 
+				array('filter' => array('=', 'messageId', $result['messageId']))
+			);
+		}
+
+		if (!$imap_result) {
+			/**
+			 * TODO - deletar do banco se nÃ£o existe no imap 
+			 */
+			 return false;
+		}
+		
+		$result = $result + $imap_result;
+		
 		return $result;
-	}	
-	
-	//followupflagged:PostgreSQL.before.find
-	public function clearFilterAtFind( &$uri , &$params , &$criteria , $original ) {
-	
-		if ($criteria['filter'] && 
-				(self::in_arrayr('messageNumber', $criteria['filter']) || self::in_arrayr('folderName', $criteria['filter'])) ) {
-			unset($criteria['filter']);
-		}
-		
-		/**
-		 * TODO - fazer parse do $criteria['filter'] para fazer strip no id composto
-		 */
-	}
+	}
+	
 	
 	/**
@@ -153,25 +182,9 @@
 	//followupflagged:PostgreSQL.after.find
 	public function doImapFind( &$uri , &$result , &$criteria , $original ){
-		/**
-		 * TODO - ver implicaÃ§Ãµes de busca com id no filtro 
-		 */
-
-		if ($result) {
-			$list = array();
-			foreach ($result as $followupflagged)
-				$list[] = $followupflagged['id'];
-				
-			$filter = array( 'IN' , 'id' , $list );
-			
-			if (isset($original['criteria']['filter']) && $original['criteria']['filter']!=NULL && count($original['criteria']['filter']) != 0)
-				$criteria['filter'] = array( 'AND', $original['criteria']['filter'], $filter );
-			else
-				$criteria['filter'] =  $filter;
-		}
-		
+
 		$imap_uri = $uri;
 		$imap_uri['service'] = 'Imap';
-		$imap_result = Controller::find($imap_uri, $result, $criteria);
-		
+		$imap_result = Controller::find($imap_uri, false, $original['criteria']);
+
 		/**
 		 * Mescla os dados vindos do PostgreSQL com os dados vindos do Imap
@@ -179,13 +192,9 @@
 		$merge_result = array ();
 		foreach ($imap_result as $ir) {
-			list($messageId, $flagId) = explode('#', $ir['id']);
-			
+		
 			foreach($result as $r) {
-				if ($r['id'] == $flagId) {
-					$r['id'] = $ir['id'];
-					$r['messageNumber'] = $ir['messageNumber'];
-					$r['folderName'] = $ir['folderName'];
-					
-					$merge_result[] = $r;
+				if ($r['messageId'] == $ir['messageId']) {			
+					$merge_result[] = $r + $ir;
+					break;
 				}
 			}
@@ -195,119 +204,22 @@
 	}
 
-	//followupflagged:Imap.before.create
-	public function letFollowupflaggedKeepUnique (&$uri , &$params , &$criteria , $original ){
-
-		if (isset($params['folderName']) && isset($params['messageNumber'])) {
-			$filter = array ('AND', array('=', 'folderName', $params['folderName']), array('=', 'messageNumber', $params['messageNumber']));
-			$toClearURI = array('concept' => 'followupflagged', 'service' => 'Imap');
-
-			//ObtÃ©m do banco um possÃ­vel sinalizador existente
-			$imap_result = Controller::find($toClearURI, false, array('filter' => $filter));
-			
-			//Se existe um sinalizador nesta mensagem, deleta-o
-			foreach ($imap_result as $r) {
-				/**
-				 * TODO - deletar sem id
-				 */
+	//followupflagged:PostgreSQL.before.find
+	public function reFilterFind (&$uri , &$params , &$criteria , $original ){
+		/**
+		 * Se p filtor incluir atributos da mensagem que o banco de dados nÃ£o conhece,  
+		 * deve-se obter os messageId dos itens do resultado e passÃ¡los num novo filtro
+		 * que o banco conheÃ§a
+		 */
+		if (self::in_arrayr('messageNumber', $criteria) || self::in_arrayr('folderName', $criteria)) {
+			$result = Controller::find(array('concept' => 'message'), array('messageId'), array('filter' => $criteria['filter']));
+			$idList = array();
+			foreach ($result as $message)
+				$idList[] = $message['messageId'];
 				
-				//deleta no Imap
-				$toClearURI['id'] = $r['id'];
-				Controller::delete($toClearURI, false, false);
-				
-				//deleta no PostgreSQL
-				list($messageId, $toClearURI['id']) = explode('#', $r['id']);
-				$toClearURI['service'] = 'PostgreSQL';
-				Controller::delete($toClearURI, false, false);
-			}
-		}
-
-	}
-
-	//Remove as dependencias de uma followupflag 
-	public function clearAllFlaggedOfFollowupflag( &$uri , &$result , &$criteria , $original ){
-		//remove apenas se vier o id da Followupflag
-		if(isset($uri['id']))
-			Controller::deleteALL(array('concept' => 'followupflagged'), null , array('filter' => array('=' , 'followupflagId' , $uri['id'])));
-
-	}
-	
-
-	//followupflagged:PostgreSQL.after.create
-	public function doImapCreate( &$uri , &$result , &$criteria , $original ) {	
-		/**
-		 * Se nÃ£o consegue salvar no banco, ele retorna objeto vÃ¡lido, porÃ©m sem id
-		 */
-		if (!isset($result['id'])) return false;
-		
-		$imap_uri = $original['URI'];;
-		$imap_uri['service'] = 'Imap';
-
-		$imap_params = array_merge($original['properties'], $result);
-		
-		$result = array();
-		if ($imap_params['folderName'] && $imap_params['messageNumber'] && $imap_params['id']) {
-			$imap_params['id'] = $imap_params['folderName'] . '/' . $imap_params['messageNumber'] . '#' . $imap_params['id']; 
-			$result = Controller::create($imap_uri, $imap_params);
-		}
-
-		if (!$result) {
-			//TODO - rollback
-		}
-	}
-	
-	//followupflagged:PostgreSQL.after.read
-	public function doImapRead( &$uri , &$result , &$criteria , $original ) {
-		
-		$imap_uri = $original['URI'];
-		$imap_uri['service'] = 'Imap';
-
-		$imap_result = Controller::read($imap_uri, $params, $imap_criteria);
-		
-		if (!$imap_result)
-			return false;		
-		
-		$result = array_merge($result, $imap_result);
-
-	}
-	
-	//followupflagged:PostgreSQL.before.<...>
-	public function stripURIAttrs( &$uri , &$params , &$criteria , $original ) {
-		list($messageId, $uri['id']) = explode('#', $uri['id']);
-		$params['id'] = $uri['id'];
-	}
-
-	//followupflagged:PostgreSQL.before.delete
-	public function doImapDelete( &$uri , &$params , &$criteria , $original ) {
-	
-		$imap_uri = $uri;
-		$imap_uri['service'] = 'Imap';
-		list($messageId, $uri['id']) = explode('#', $uri['id']);
-
-		$result = Controller::delete($imap_uri, $params, $imap_criteria);
-
-		if (!$result)
-			return false;
-	}
-	
-	//followupflagged:PostgreSQL.before.update
-	public function doImapUpdate( &$uri , &$params , &$criteria , $original ) {
-		/**
-		 * Para os conceitos "labeled" e "followupflagged", sÃ³ faz sentido o update de 
-		 * atributos gravados no banco de dados e nunca no IMAP.
-		 */
-		//$imap_uri = $uri;
-		//$imap_uri['service'] = 'Imap';
-		//$result = Controller::update($imap_uri, $params, $criteria);
-	}
-	
-		
-	//label:before.create
-	public function verifyNameLabel(&$uri , &$params , &$criteria , $original){
-		$nameLabel = $params['name'];
-		$Labels = Controller::find(array('concept' => 'label'), false, array('filter' => array('i=', 'name', $nameLabel) ));
-		if($Labels){
-			Throw new Exception('JÃ¡ existe um marcador com esse nome.');
-		}
-	}
+			$filter = array( 'IN' , 'messageId' , $idList );
+
+			$criteria['filter'] =  $filter;
+		}	
+	}	
 
 }
