Index: trunk/rest/setup/default_records.inc.php
===================================================================
--- trunk/rest/setup/default_records.inc.php	(revision 6528)
+++ trunk/rest/setup/default_records.inc.php	(revision 7342)
@@ -15,5 +15,5 @@
 $oProc->query("INSERT INTO rest_client (client_id, client_secret) values (1, '$secret');");
 $dados = array();
-$oProc->query("select * from phpgw_config where config_app='phpgwapi'");
+$oProc->query("SELECT * FROM phpgw_config WHERE config_app='phpgwapi'");
 while ($oProc->next_record())
 {
@@ -38,6 +38,13 @@
 $config['oauth']['client_secret'] = $secret;
 
+$serverID = "001";
+$config['ServersRest-'.$serverID]['serverID'] = $serverID;
+$config['ServersRest-'.$serverID]['serverName'] = $_SERVER['HTTP_HOST'];
+$config['ServersRest-'.$serverID]['serverDescription'] = 'Expresso - ' . $_SERVER['HTTP_HOST'];
+$config['ServersRest-'.$serverID]['serverUrl'] = 'http://' . $_SERVER['HTTP_HOST'] . $dados['webserver_url'];
+$config['ServersRest-'.$serverID]['serverContext'] = '/rest/';
+$config['ServersRest-'.$serverID]['serverStatus'] = 'true';
+
 Config::writeIniFile($config , dirname(__FILE__) . '/../../prototype/config/REST.ini', true);
-    
 
 ?>
Index: trunk/prototype/config/Tonic.srv
===================================================================
--- trunk/prototype/config/Tonic.srv	(revision 7230)
+++ trunk/prototype/config/Tonic.srv	(revision 7342)
@@ -1,4 +1,76 @@
+[/AvailableServers]
+AvailableServersResource = /availableServers/AvailableServersResource.php
+
+[/Catalog/Contacts]
+ContactsResource = /catalog/ContactsResource.php
+
+[/Catalog/ContactPicture]
+ContactPictureResource = /catalog/ContactPictureResource.php
+
+[/Calendar/Events]
+EventsResource = /calendar/EventsResource.php
+
+[/dynamiccontacts]
+DynamicContactsResource = /catalog/DynamicContactsResource.php
+
+[/dynamiccontact/:id]
+DynamicContactResource = /catalog/DynamicContactResource.php
+
+[/ExpressoVersion]
+ExpressoVersionResource = /core/ExpressoVersionResource.php
+
+[/groups]
+GroupsResource = /catalog/GroupsResource.php
+
+[/group/:id]
+GroupResource = /catalog/GroupResource.php
+
+[/Login]
+LoginResource = /core/LoginResource.php
+
+[/Logout]
+LogoutResource = /core/LogoutResource.php
+
+[/Mail/AddFolder]
+AddFolderResource = /mail/AddFolderResource.php
+
+[/Mail/Attachment]
+AttachmentResource = /mail/AttachmentResource.php
+
+[/Mail/CleanTrash]
+CleanTrashResource = /mail/CleanTrashResource.php
+
+[/Mail/DelFolder]
+DelFolderResource = /mail/DelFolderResource.php
+
+[/Mail/DelMessage]
+DelMessageResource = /mail/DelMessageResource.php
+
+[/Mail/Folders]
+FoldersResource = /mail/FoldersResource.php
+
+[/Mail/RenameFolder]
+RenameFolderResource = /mail/RenameFolderResource.php
+
+[/Mail/Messages]
+MessagesResource = /mail/MessagesResource.php
+
+[/Mail/Send]
+SendResource = /mail/SendResource.php
+
+[/Mail/SendSupportFeedback]
+SendSupportFeedbackResource = /mail/SendSupportFeedbackResource.php
+
+[/personalContact]
+PersonalContactResource = /catalog/PersonalContactResource.php
+
+[/personalContact/:id]
+PersonalContactResource = /catalog/PersonalContactResource.php
+
 [/token]
 TokenResource = /oauth/TokenResource.php
+
+[/usercontacts]
+UserContactsResource = /catalog/UserContactsResource.php
 
 [/usersldap]
@@ -8,28 +80,7 @@
 UserResource = /user/UserResource.php
 
-[/personalContact]
-PersonalContactResource = /catalog/PersonalContactResource.php
-
-[/personalContact/:id]
-PersonalContactResource = /catalog/PersonalContactResource.php
-
 [/sharedcontact/:id]
 SharedContactResource = /catalog/SharedContactResource.php
 
-[/groups]
-GroupsResource = /catalog/GroupsResource.php
-
-[/group/:id]
-GroupResource = /catalog/GroupResource.php
-
 [/sharedgroup/:id]
 SharedGroupResource = /catalog/SharedGroupResource.php
-
-[/dynamiccontacts]
-DynamicContactsResource = /catalog/DynamicContactsResource.php
-
-[/dynamiccontact/:id]
-DynamicContactResource = /catalog/DynamicContactResource.php
-
-[/usercontacts]
-UserContactsResource = /catalog/UserContactsResource.php
Index: trunk/prototype/config/Errors.tsv
===================================================================
--- trunk/prototype/config/Errors.tsv	(revision 7342)
+++ trunk/prototype/config/Errors.tsv	(revision 7342)
@@ -0,0 +1,41 @@
+# Errors from -32000 to -32099 => Server error: Reserved for implementation-defined server-errors.
+
+-32700		E_PARSE_ERROR					Parse error
+-32600		E_INVALID_REQUEST				Invalid Request
+-32601		E_METHOD_NOT_FOUND				Method not found
+-32602		E_INVALID_PARAMS				Invalid params
+-32603		E_INTERNAL_ERROR				Internal error
+404			E_HTTP_NOT_FOUND				A resource matching URI '%1' was not found
+500			E_UNKNOWN_ERROR					HTTP Unknown error
+
+# Errors inherited from Expresso Application.
+1			LOGIN_SUCCESS_LOGOUT			You have been successfully logged out
+2			LOGIN_SESSION_EXPIRED			Sorry, your login has expired
+3			LOGIN_NOT_LOGGED_IN				You are not logged in
+4			LOGIN_COOKIES_REQUIRED			Cookies are required to login to this site.
+5			LOGIN_BADLOGIN					bad login or password
+6			LOGIN_PASSWORD_EXPIRED			Your password has expired, and you do not have access to change it
+7			LOGIN_AUTH_INVALID				Your auth is invalid
+10			LOGIN_SESSION_NOT_VERIFIED		Your session could not be verified.
+98			LOGIN_ACCOUNT_EXPIRED			Account is expired
+99			LOGIN_LOGIN_BLOCKED				Blocked, too many attempts!
+200			LOGIN_INVALID_LOGIN				Bad login or password
+
+1001		CATALOG_MIN_ARGUMENT_SEARCH		Your search argument must be longer than %1 characters.
+1002		MAIL_NOT_SENT					Your mail could not be sent.
+1003		MAIL_TRASH_NOT_CLEANED			Your trash folder could not be cleaned.
+1004		MAIL_MESSAGE_NOT_FOUND			Message not found in folder %1.
+1005		MAIL_INVALID_NEW_FOLDER_NAME	Invalid folder name.
+1006 		MAIL_INVALID_OLD_FOLDER			Invalid old folder.
+1007 		MAIL_INVALID_FOLDER				Invalid folder.
+1008		MAIL_CANNOT_DEL_DEFAULT_FOLDER	Cannot delete a default folder.
+1009		MAIL_FOLDER_NOT_EMPTY			The folder is not empty.
+1010		MAIL_FOLDER_NOT_RENAMED			The folder could not be renamed.
+1011		MAIL_FOLDER_NOT_ADDED			The folder could not be added.
+1012		MAIL_FOLDER_NOT_DELETED			The folder could not be deleted.
+1013		MAIL_FOLDER_LIMIT_REACHED		Folder limit has been reached.
+1014		CALENDAR_INVALID_START_DATE		Invalid start date.
+1015		CALENDAR_INVALID_END_DATE		Invalid end date.
+1016		MAIL_INVALID_MESSAGE			Message does not exists.
+1017		MAIL_TRASH_FOLDER_NOT_EXISTS	Trash folder does not exists.
+1018		MAIL_NOT_SENT_LIMIT_EXCEEDED	The size of this message has exceeded  the limit (%1B).
Index: trunk/prototype/config/user.ini
===================================================================
--- trunk/prototype/config/user.ini	(revision 6599)
+++ trunk/prototype/config/user.ini	(revision 7342)
@@ -56,2 +56,7 @@
 gidNumber = gidNumber
 telephoneNumber=telephoneNumber
+
+[Applications.mapping]
+mail = expressoMail1_2
+catalog = contactcenter
+calendar = calendar
Index: trunk/prototype/rest/mail/RenameFolderResource.php
===================================================================
--- trunk/prototype/rest/mail/RenameFolderResource.php	(revision 7342)
+++ trunk/prototype/rest/mail/RenameFolderResource.php	(revision 7342)
@@ -0,0 +1,41 @@
+<?php
+
+class RenameFolderResource extends MailAdapter {
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);
+
+		if($this-> isLoggedIn())
+		{
+			$old_id   = $this->getParam('folderID');
+			$new_name = $this->getParam('folderName');
+
+			if(!$this->getImap()->folder_exists($old_id))
+				Errors::runException("MAIL_INVALID_OLD_FOLDER");
+
+			$default_folders = array_keys($this->defaultFolders);
+			if(in_array($old_id, $default_folders))
+				Errors::runException("MAIL_INVALID_OLD_FOLDER");
+
+			if(empty($new_name) || preg_match('/[\/\\\!\@\#\$\%\&\*\(\)]/', $new_name))
+				Errors::runException("MAIL_INVALID_NEW_FOLDER_NAME");
+
+			$old_id_arr = explode($this->getImap()->imap_delimiter, $old_id);
+
+			$new_id     = implode($this->getImap()->imap_delimiter, array_slice($old_id_arr, 0, count($old_id_arr) - 1)) . $this->getImap()->imap_delimiter . $new_name;
+
+			$params['current'] = $old_id;
+			$params['rename']  = $new_id;
+
+			$result = $this->getImap()->ren_mailbox($params);
+			if($result != 'Ok')
+				Errors::runException("MAIL_FOLDER_NOT_RENAMED");
+		}
+
+		$this->setResult(array('folderID' => $new_id));
+
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();
+	}
+
+}
Index: trunk/prototype/rest/mail/AddFolderResource.php
===================================================================
--- trunk/prototype/rest/mail/AddFolderResource.php	(revision 7342)
+++ trunk/prototype/rest/mail/AddFolderResource.php	(revision 7342)
@@ -0,0 +1,41 @@
+<?php
+
+class AddFolderResource extends MailAdapter {
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);
+
+		if($this-> isLoggedIn())
+		{
+			$parent_id = $this->getParam('parentFolderID');
+			$parent_id = empty($parent_id) ? 'INBOX' : $parent_id;
+			$new_name  = $this->getParam('folderName');
+
+			$all_folders = $this->getImap()->get_folders_list();
+			if(!$all_folders){
+				return $this->getResponse();
+			}
+
+			$max_folders = $this->getImap()->prefs['imap_max_folders'];
+			if(count($all_folders) == $max_folders)
+				Errors::runException("MAIL_FOLDER_LIMIT_REACHED");
+
+			if(empty($new_name) || preg_match('/[\/\\\!\@\#\$\%\&\*\(\)]/', $new_name))
+				Errors::runException("MAIL_INVALID_NEW_FOLDER_NAME");
+
+			$new_id = $parent_id . $this->getImap()->imap_delimiter . $new_name;
+
+			$params['newp'] = $new_id;
+
+			$result = $this->getImap()->create_mailbox($params);
+			if($result != 'Ok')
+				Errors::runException("MAIL_FOLDER_NOT_ADDED");
+		}
+
+		$this->setResult(array('folderID' => $new_id));
+
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();
+	}
+
+}
Index: trunk/prototype/rest/mail/CleanTrashResource.php
===================================================================
--- trunk/prototype/rest/mail/CleanTrashResource.php	(revision 7342)
+++ trunk/prototype/rest/mail/CleanTrashResource.php	(revision 7342)
@@ -0,0 +1,21 @@
+<?php
+
+class CleanTrashResource extends MailAdapter {
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);
+
+		if($this-> isLoggedIn())
+		{
+			$params['clean_folder'] = 'imapDefaultTrashFolder';
+			if(!$this -> getImap() -> empty_folder($params))
+				Errors::runException("MAIL_TRASH_NOT_CLEANED");
+		}
+
+		$this->setResult(true);
+
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();
+	}
+
+}
Index: trunk/prototype/rest/mail/MessagesResource.php
===================================================================
--- trunk/prototype/rest/mail/MessagesResource.php	(revision 7342)
+++ trunk/prototype/rest/mail/MessagesResource.php	(revision 7342)
@@ -0,0 +1,176 @@
+<?php
+
+class MessagesResource extends MailAdapter {	
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);	
+ 		$imap_msgs = null;
+ 		$all_msgs = array();
+		
+		if($this-> isLoggedIn()) 
+		{					
+			$max_email_per_page = intval($this->getParam('resultsPerPage') ? $this->getParam('resultsPerPage') :
+					$this->getImap()->prefs['max_email_per_page']);
+
+			if($this->getParam('folderID') && $this->getParam('msgID') > 0) {
+				$msg = $this->getMessage();
+				if(!$msg){
+					Errors::runException("MAIL_MESSAGE_NOT_FOUND", $this->getParam('folderID'));
+				}
+				else{
+					$result = array ('messages' => array($msg));
+					$this->setResult($result) ;
+					return $this->getResponse();
+				}
+			}
+	
+			elseif($this->getParam('search') != "") {
+				$imap = $this->getImap();
+				$condition = array();
+				$imap_folders =  $imap->get_folders_list();
+
+				if($this->getExpressoVersion() == "2.2") {
+
+					foreach ($imap_folders as $i => $imap_folder) {
+						if(is_int($i)) {
+							$folder = mb_convert_encoding($imap_folder['folder_id'],'UTF8','ISO-8859-1');
+							$condition[] = "$folder##ALL <=>".$this->getParam('search')."##";
+						}
+					}
+
+					$params = array(
+							'condition' => implode(",",$condition),							
+							'page' 		=> ($this->getParam('page') ? intval($this->getParam('page')) - 1 : 0),
+							'sort_type' => "SORTDATE"
+						);
+
+					$this->getImap()->prefs['preview_msg_subject'] = "1";
+					$imap_msgs = $this->getImap()->search_msg($params);
+
+					if(!$imap_msgs){
+						return $this->getResponse();
+					}
+					if($imap_msgs['num_msgs'] > 0) {
+						foreach($imap_msgs['data'] as $imap_msg) {
+							$msg = array();
+							$msg['msgID'] = $imap_msg['uid'];
+							$msg['folderID'] = $imap_msg['boxname'];
+							$msg['msgDate']	= $imap_msg['udate']." 00:00";
+							$msg['msgSubject'] = mb_convert_encoding($imap_msg['subject'],"UTF8", "ISO_8859-1");
+							$msg['msgSize'] = $imap_msg['size'];
+							$msg['msgFrom']	= array('fullName' => mb_convert_encoding($imap_msg['from'],"UTF8", "ISO_8859-1"), 'mailAddress' => "");							
+							$msg['msgFlagged']	= strpos($imap_msg['flag'],"F") !== false ? "1" : "0";
+							$msg['msgSeen']		= strpos($imap_msg['flag'],"U") !== false ? "0" : "1";
+							$msg['msgHasAttachments'] = strpos($imap_msg['flag'],"T") !== false ? "1" : "0";							
+							$msg['msgForwarded'] = (strpos($imap_msg['flag'],"A") !== false && strpos($imap_msg['flag'],"X") !== false) ? "1" : "0";
+							$msg['msgAnswered'] = $msg['msgForwarded'] != "1" && strpos($imap_msg['flag'],"A") !== false  ? "1" : "0";
+							$msg['msgDraft'] 	= $msg['msgForwarded'] != "1" && strpos($imap_msg['flag'],"X") !== false ? "1" : "0";
+							//$msg['msgTo'] = array();
+							//$msg['ContentType']	= "";
+							//$msg['msgBodyResume'] = "";
+							$all_msgs[] = $msg;
+						}
+					}
+
+				}
+				else{
+					// TODO: Implementar a pesquisa de mensagens para versão 2.4
+				}
+			}
+			else{
+				$current_page = intval($this->getParam('page') ? $this->getParam('page') : 1);
+	
+				$msg_range_begin = ($max_email_per_page * ($current_page - 1)) + 1;
+				$msg_range_end = $msg_range_begin + ($max_email_per_page  - 1);
+	
+				$this->getImap()->prefs['preview_msg_subject'] = "1";
+	
+	
+				$imap_msgs = $this->getImap()-> get_range_msgs2(
+					array(	"folder"			=> $this->getParam('folderID'),
+							"msg_range_begin" 	=> $msg_range_begin,
+							"msg_range_end"	 	=> $msg_range_end,
+							"search_box_type"	=> "ALL",
+							"sort_box_reverse"	=> "1",
+							"sort_box_type"		=> "SORTARRIVAL"
+					));
+				if(!$imap_msgs){
+					return $this->getResponse();
+				}
+	
+				foreach($imap_msgs as $i => $imap_msg) {
+					if(!is_int($i)) {
+						continue;
+					}
+					$msg = array();
+					$msg['msgID'] = $imap_msg['msg_number'];
+					$msg['folderID'] =  $imap_msgs['folder'];
+					$msg['msgDate']	= gmdate('d/m/Y H:i', $imap_msg['timestamp']);
+					$msg['msgFrom']['fullName'] = mb_convert_encoding($imap_msg['from']['name'],"UTF8", "ISO_8859-1");
+					$msg['msgFrom']['mailAddress'] = $imap_msg['from']['email'];
+					$msg['msgTo'] = array();
+					if($this->getExpressoVersion() != "2.2") {
+						foreach($imap_msg['to'] as $to){
+							$msg['msgTo'][] = array('fullName' => mb_convert_encoding($to['name'],"UTF8", "ISO_8859-1"), 'mailAddress' => $to['email']);
+						}
+					}else{
+						$msg['msgTo'][] = array('fullName' => mb_convert_encoding($to['name'],"UTF8", "ISO_8859-1"), 'mailAddress' => $imap_msg['to']['email']);
+					}
+					$msg['msgReplyTo'][0] = $this->formatMailObject($imap_msg['reply_toaddress']);
+					$msg['msgSubject']  = mb_convert_encoding($imap_msg['subject'],"UTF8", "ISO_8859-1");
+	
+					if($this->getExpressoVersion() != "2.2") {
+						$msg['msgHasAttachments'] = $imap_msg['attachment'] ? "1" : "0";
+					}
+					else{
+						$msg['msgHasAttachments'] = $imap_msg['attachment']['number_attachments'] ? "1" : "0";
+					}
+	
+					$msg['msgFlagged'] 	= $imap_msg['Flagged'] == "F" ? "1" : "0";
+					$msg['msgForwarded']= $imap_msg['Forwarded'] == "F" ? "1" : "0";
+					$msg['msgAnswered'] = $imap_msg['Answered'] == "A" ? "1" : "0";
+					$msg['msgDraft']	= $imap_msg['Draft'] == "X" ? "1" : "0";
+					$msg['msgSeen'] 	= $imap_msg['Unseen'] == "U" ? "0" : "1";
+	
+					$msg['ContentType']	= $imap_msg['ContentType'];
+					$msg['msgSize'] 	= $imap_msg['Size'];
+	
+					$msg['msgBodyResume'] = $imap_msg['msg_sample']['body'];
+	
+					if($this->getExpressoVersion() != "2.2") {
+						$msg['msgBodyResume'] =  base64_decode($msg['msgBodyResume']);
+					}
+
+					$msg['msgBodyResume'] = substr($msg['msgBodyResume'], 2);
+					$msg['msgBodyResume'] = str_replace("\r\n", "", $msg['msgBodyResume']);
+					$msg['msgBodyResume'] = str_replace(chr(160)," ", $msg['msgBodyResume']);
+					$msg['msgBodyResume'] = preg_replace('/\s\s+/', '', $msg['msgBodyResume']);
+					$msg['msgBodyResume'] = mb_convert_encoding($msg['msgBodyResume'],"UTF8", "ISO_8859-1");
+
+					$all_msgs[] = $msg;
+				}
+			}
+		}
+		$num_msgs  = 0;
+		$num_pages = 1;		
+		$num_msgs = intval($imap_msgs['num_msgs']);
+		if($num_msgs > $max_email_per_page) {
+			$num_pages = $num_msgs / $max_email_per_page;
+			if($num_pages > intval($num_pages))
+				$num_pages = intval($num_pages) + 1;
+		}
+		
+		$result = array (
+				'messages' 	  => $all_msgs,
+				'numMessages' => $num_msgs,
+				'numPages'	  => $num_pages,
+				'timeZone'	  => $imap_msgs['offsetToGMT'] ? $imap_msgs['offsetToGMT'] : "",
+				'totalUnseen' => $imap_msgs['tot_unseen'] ? $imap_msgs['tot_unseen'] : ""
+		);
+			
+		$this->setResult($result);	
+		
+		//	to Send Response (JSON RPC format)
+		return $this->getResponse();		
+	}
+}
Index: trunk/prototype/rest/mail/AttachmentResource.php
===================================================================
--- trunk/prototype/rest/mail/AttachmentResource.php	(revision 7342)
+++ trunk/prototype/rest/mail/AttachmentResource.php	(revision 7342)
@@ -0,0 +1,40 @@
+<?php
+
+class AttachmentResource extends MailAdapter {	
+	public function post($request){		
+		// to Receive POST Params (use $this->params)		
+ 		parent::post($request); 		
+ 		$folderID 		= $this->getParam('folderID');
+ 		$msgID 			= $this->getParam('msgID');
+ 		$attachmentID 	= $this->getParam('attachmentID');
+ 		
+		if($this-> isLoggedIn()) {
+								
+			if( $folderID && $msgID && $attachmentID) {				
+				$dir = PHPGW_INCLUDE_ROOT."/expressoMail1_2/inc";
+				
+				if($this->getExpressoVersion() != "2.2"){
+					$_GET['msgFolder'] = $folderID;
+					$_GET['msgNumber'] = $msgID;
+					$_GET['indexPart'] = $attachmentID;
+					include("$dir/get_archive.php");
+					
+				}else{
+					$_GET['msg_folder'] = $folderID;
+					$_GET['msg_number'] = $msgID;
+					$_GET['msg_part'] = $attachmentID;
+					$_GET['idx_file']	= $this->getParam('attachmentIndex');
+					$_GET['newfilename']= $this->getParam('attachmentName');
+					$_GET['encoding']	= $this->getParam('attachmentEncoding');
+					include("$dir/gotodownload.php");
+				}
+				// Dont modify header of Response Method to 'application/json'
+				$this->setCannotModifyHeader(true);
+				return $this->getResponse();
+			}
+			else{
+				Errors::runException("MAIL_ATTACHMENT_NOT_FOUND");
+			}
+		}
+	}
+}
Index: trunk/prototype/rest/mail/DelMessageResource.php
===================================================================
--- trunk/prototype/rest/mail/DelMessageResource.php	(revision 7342)
+++ trunk/prototype/rest/mail/DelMessageResource.php	(revision 7342)
@@ -0,0 +1,47 @@
+<?php
+
+class DelMessageResource extends MailAdapter {
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);
+
+		if($this-> isLoggedIn())
+		{
+			
+			$msgID = $this->getParam('msgID');
+			$folderID = $this->getParam('folderID');
+
+			if(!$this->getImap()->folder_exists($folderID))
+				Errors::runException("MAIL_INVALID_FOLDER");
+				
+			if ($msgID == "") {
+				Errors::runException("MAIL_INVALID_MESSAGE");
+			}
+			
+			if (!$this->messageExists($folderID,$msgID)) {
+				Errors::runException("MAIL_INVALID_MESSAGE");
+			}
+			
+			$trash_folder = array_search(3,$this->defaultFolders);
+			$params = array();
+			$params['folder'] = $folderID;
+			$params['msgs_number'] = $msgID;
+			
+			if (($folderID != $trash_folder) && ($this->getImap()->prefs['save_deleted_msg'])) {
+				
+				if ($trash_folder == "") 
+					Errors::runException("MAIL_TRASH_FOLDER_NOT_EXISTS");
+				
+				$params['new_folder'] = $trash_folder;
+				$this->getImap()->move_messages($params);
+			} else {
+				$this->getImap()->delete_msgs($params);
+			}
+			
+			$this->setResult(true);
+		}
+
+		return $this->getResponse();
+	}
+
+}
Index: trunk/prototype/rest/mail/SendResource.php
===================================================================
--- trunk/prototype/rest/mail/SendResource.php	(revision 7342)
+++ trunk/prototype/rest/mail/SendResource.php	(revision 7342)
@@ -0,0 +1,81 @@
+<?php
+
+class SendResource extends MailAdapter {
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);
+
+		if($this-> isLoggedIn())
+		{
+			// parametros recuperados conforme draft
+			$msgForwardTo		= $this->getParam("msgForwardTo");
+			$originalMsgID		= $this->getParam("originalMsgID");
+			$originalUserAction	= $this->getParam("originalUserAction");
+
+			$params['input_subject']	= $this->getParam("msgSubject");
+			$params['input_to']			= $this->getParam("msgTo");
+			$params['input_cc']			= $this->getParam("msgCcTo");
+			$params['input_cco']		= $this->getParam("msgBccTo");
+			$params['input_replyto']	= $this->getParam("msgReplyTo");
+			$params['body']				= $this->getParam("msgBody");
+			$params['type']				= $this->getParam("msgType") ? $this->getParam("msgType") : "plain";
+			$params['folder'] =	
+				$_SESSION['phpgw_info']['user']['preferences']['expressoMail']['save_in_folder'] == "-1" ? "null" :
+				$_SESSION['phpgw_info']['user']['preferences']['expressoMail']['save_in_folder'];
+
+			if(count($_FILES))
+			{
+				$files = array();
+				$totalSize = 0;
+				foreach( $_FILES as $name => $file )
+				{
+					$files[$name] = array('name' => $file['name'],
+							'type' => $file['type'],
+							'source' => base64_encode(file_get_contents( $file['tmp_name'], $file['size'])),
+							'size' => $file['size'],
+							'error' => $file['error']
+					);
+					$totalSize += $file['size'];
+				}
+				
+				$uploadMaxFileSize = str_replace("M","",$_SESSION['phpgw_info']['user']['preferences']['expressoMail']['max_attachment_size']) * 1024 * 1024;
+				if($totalSize > $uploadMaxFileSize){
+					Errors::runException("MAIL_NOT_SENT_LIMIT_EXCEEDED", $_SESSION['phpgw_info']['user']['preferences']['expressoMail']['max_attachment_size']);
+				}
+
+				if($this->getExpressoVersion() != "2.2")
+				{
+					require_once (__DIR__.'/../../../prototype/api/controller.php');
+					Controller::addFallbackHandler( 0, function($e){
+						throw $e;
+					} );
+				
+					$result = array();
+					$attachments_ids = array();
+						
+					foreach($files as $key => $value){
+						$value['disposition']  = isset($value['disposition']) ?
+							$value['disposition'] : 'attachment';
+						try{
+							$attachment = Controller::put( array( 'concept' =>  "mailAttachment" ), $value );
+							$attachments_ids[] = $attachment[0]['id'];
+						}catch(Exception $e){
+							Errors::runException($e->getMessage());
+						}
+					}
+					$params['attDisposition1'] 	= 'attachment';
+					$params['attachments'] 		= json_encode($attachments_ids);
+				}
+			}
+			$returncode = $this->getImap()->send_mail($params);
+			if (!$returncode || !(is_array($returncode) && $returncode['success'] == true))
+				Errors::runException("MAIL_NOT_SENT");
+		}
+
+		$this->setResult(true);
+
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();
+	}
+
+}
Index: trunk/prototype/rest/mail/SendSupportFeedbackResource.php
===================================================================
--- trunk/prototype/rest/mail/SendSupportFeedbackResource.php	(revision 7342)
+++ trunk/prototype/rest/mail/SendSupportFeedbackResource.php	(revision 7342)
@@ -0,0 +1,40 @@
+<?php
+
+class SendSupportFeedbackResource extends MailAdapter {
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);
+
+		if($this-> isLoggedIn())
+		{
+			$msgBody = $this->getParam("message");
+
+			$params['input_to'] = $GLOBALS['phpgw_info']['server']['sugestoes_email_to'];
+			$params['input_cc'] = $GLOBALS['phpgw_info']['server']['sugestoes_email_cc'];
+			$params['input_cc'] = $GLOBALS['phpgw_info']['server']['sugestoes_email_bcc'];
+			$params['input_subject'] = lang("Suggestions");
+			$params['body'] = $msgBody;
+			$params['type'] = 'textplain';
+
+			$GLOBALS['phpgw']->preferences->read_repository();
+			$_SESSION['phpgw_info']['expressomail']['user'] = $GLOBALS['phpgw_info']['user'];
+			$boemailadmin   = CreateObject('emailadmin.bo');
+			$emailadmin_profile = $boemailadmin->getProfileList();
+			$_SESSION['phpgw_info']['expressomail']['email_server'] = $boemailadmin->getProfile($emailadmin_profile[0]['profileID']);
+			$_SESSION['phpgw_info']['expressomail']['server'] = $GLOBALS['phpgw_info']['server'];
+			$_SESSION['phpgw_info']['expressomail']['user']['email'] = $GLOBALS['phpgw']->preferences->values['email'];
+
+			$expressoMail = CreateObject('expressoMail1_2.imap_functions');
+			$returncode   = $expressoMail->send_mail($params);
+
+			if (!$returncode || !(is_array($returncode) && $returncode['success'] == true))
+				Errors::runException("MAIL_NOT_SENT");
+		}
+
+		$this->setResult(true);
+
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();
+	}
+
+}
Index: trunk/prototype/rest/mail/FoldersResource.php
===================================================================
--- trunk/prototype/rest/mail/FoldersResource.php	(revision 7342)
+++ trunk/prototype/rest/mail/FoldersResource.php	(revision 7342)
@@ -0,0 +1,79 @@
+<?php
+
+class FoldersResource extends MailAdapter {	
+	public function post($request){
+		// to Receive POST Params (use $this->params)		
+ 		parent::post($request);	 		
+ 		
+		if($this-> isLoggedIn()) 
+		{	
+			$imap_folders =  $this->getImap()->get_folders_list();
+		}
+		if(!$imap_folders){
+			return $this->getResponse();
+		}
+			
+		$all_folders    = array();
+		$user_folders   = array();
+		$shared_folders = array();
+		
+		foreach ($imap_folders as $i => $imap_folder) {
+			if(is_int($i)) {
+				$folder = array();
+				$folder['folderName'] 	  = mb_convert_encoding($imap_folder['folder_name'], "UTF8", "ISO_8859-1");
+				 if(strtoupper($folder['folderName']) == 'INBOX') {				
+					$folder['folderName'] = $this->getImap()->functions->getLang("Inbox");
+				}
+				$folder['folderParentID'] = mb_convert_encoding($imap_folder['folder_parent'],'UTF8','ISO-8859-1');
+				$folder['folderHasChildren'] = $imap_folder['folder_hasChildren'];
+				$folder['qtdUnreadMessages'] = $imap_folder['folder_unseen'];
+				$folder['qtdMessages'] = $this->getImap()->get_num_msgs(array("folder" => $imap_folder['folder_id']));
+				$folder['folderID'] = mb_convert_encoding($imap_folder['folder_id'],'UTF8','ISO-8859-1');
+		
+				if(substr($folder['folderID'], 0, 4) == 'user'){
+					$folder['folderType'] = "6";
+					$shared_folders[] = $folder;
+				}else if(array_key_exists($folder['folderID'], $this->defaultFolders) !== false) {
+					$folder_type = $this->defaultFolders[$folder['folderID']];
+					$folder['folderType'] = $folder_type;
+					$default_folders[] = $folder;
+				}
+				else{
+					$folder['folderType'] = "5";
+					$user_folders[] = $folder;
+				}
+			}
+		}
+		
+		$all_folders = array_merge($default_folders, $user_folders, $shared_folders);
+		$quota_folders = $this->getImap()->get_quota_folders();
+		$search = $this->getParam('search') ? mb_convert_encoding($this->getParam('search'),"ISO_8859-1", "UTF8") : null;
+		foreach($all_folders as $i => $folder){
+			$folder_name = mb_convert_encoding($folder['folderName'],"ISO_8859-1", "UTF8");
+			$folder_id   = mb_convert_encoding($folder['folderID'],"ISO_8859-1", "UTF8");
+			if($folder_id == 'INBOX') {
+				$j = $this->getImap()->functions->getLang("Inbox");
+			}else {
+				$j = str_replace("INBOX".$this->getImap()->imap_delimiter,"",$folder_id);
+			}
+			$all_folders[$i]['diskSizeUsed'] 	= $quota_folders[$j]['quota_used'];
+			$all_folders[$i]['diskSizePercent'] = $quota_folders[$j]['quota_percent']/100;
+			if($search != null && stristr($folder_name, $search) == null){
+				unset($all_folders[$i]);
+			}
+		}
+		
+		$result = array (
+				'folders' => array_values($all_folders),
+				'diskSizeUsed'     => $quota_folders['quota_root']['quota_used']*1024,
+				'diskSizeLimit'    => $quota_folders['quota_root']['quota_limit']*1024,
+				'diskSizePercent'  => $quota_folders['quota_root']['quota_percent']/100
+		);			
+		
+		$this->setResult($result);
+		
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();		
+	}	
+
+}
Index: trunk/prototype/rest/mail/DelFolderResource.php
===================================================================
--- trunk/prototype/rest/mail/DelFolderResource.php	(revision 7342)
+++ trunk/prototype/rest/mail/DelFolderResource.php	(revision 7342)
@@ -0,0 +1,45 @@
+<?php
+
+class DelFolderResource extends MailAdapter {
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);
+
+		if($this-> isLoggedIn())
+		{
+			$params['del_past'] = $folder_id = $this->getParam('folderID');
+
+			if(!$this->getImap()->folder_exists($folder_id))
+				Errors::runException("MAIL_INVALID_FOLDER");
+
+			$default_folders = array_keys($this->defaultFolders);
+			if(in_array($folder_id, $default_folders))
+				Errors::runException("MAIL_CANNOT_DEL_DEFAULT_FOLDER");
+
+			$personal_folders = $this->getImap()->get_folders_list(array('noSharedFolders' => true, 'folderType' => 'personal'));
+			if(!$personal_folders){
+				return $this->getResponse();
+			}
+			foreach($personal_folders AS $personal_folder){
+				if($personal_folder['folder_id'] == $folder_id && $personal_folder['folder_hasChildren'])
+					Errors::runException("MAIL_FOLDER_NOT_EMPTY");
+			}
+
+			if($this->getImap()->get_num_msgs(array('folder' => $folder_id)) > 0)
+				Errors::runException("MAIL_FOLDER_NOT_EMPTY");
+
+			// TODO: verificar o que ocorre com o objeto imap nas validaÃ§Ãµes acima. Por algum motivo, recriando o objeto, o mÃ©todo delete_mailbox funciona, mas sem recriar, nÃ£o funciona.
+			$this->imap = null;
+
+			$result = $this->getImap()->delete_mailbox($params);
+			if($result != 'Ok')
+				Errors::runException("MAIL_FOLDER_NOT_DELETED");
+		}
+
+		$this->setResult(true);
+
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();
+	}
+
+}
Index: trunk/prototype/rest/mail/MailLastResource.php
===================================================================
--- trunk/prototype/rest/mail/MailLastResource.php	(revision 6528)
+++ 	(revision )
@@ -1,99 +1,0 @@
-<?php
- 
-use prototype\api\Config as Config;
-
-class MailLastResource extends Resource {
- 
-    /**
-    * Busca as Ãºltimas 20 menssagens nÃ£o lidas do usuÃ¡rio
-    *
-    * @license    http://www.gnu.org/copyleft/gpl.html GPL
-    * @author     ConsÃ³rcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
-    * @sponsor    Caixa EconÃŽmica Federal
-    * @author     Cristiano CorrÃªa Schmidt
-    * @return     Lista das ultimas 10 menssagens do usuÃ¡rio nÃ£o lidas
-    * @access     public
-    **/
-    function get($request) 
-    {
-	$this->secured();
-	
-        $response = new Response($request);
-        $response->code = Response::OK;
-        $response->addHeader('Content-type', 'aplication/json');
-		
-	$cyrus = Config::service('Cyrus', 'config');
-	$options = ($cyrus['tlsEncryption']) ? '/tls/novalidate-cert' : '/notls/novalidate-cert'; 
-	$mbox = imap_open( '{'.$cyrus['host'].":".$cyrus['port'].$options.'}INBOX' , Config::me('uid') , Config::me('password') );
-	
-	$msgIds = imap_sort( $mbox , SORTDATE , 1 , null , "UNSEEN" , 'UTF-8');
-	$msgIds = array_splice($msgIds , 0 , 20);
-	
-	$return = array();
-	
-	foreach ($msgIds as $key => &$value) 
-	{    
-	      $header = imap_headerinfo( $mbox, $value );
-	      $return[$key]['subject'] = ( isset($header->subject) && trim($header->subject) !== '' ) ?  self::decodeMimeString($header->subject) : 'No Subject';
-	      $return[$key]['date'] =  $header->udate;
-	      $return[$key]['from'] =  (isset( $header->from[0] )) ? self::formatMailObject( $header->from[0] ) : array( 'name' => '' , 'mail' => '');
-	}
-
-	$response->body = json_encode($return);
-	
-	imap_close($mbox);
-	return $response;
-    }
-
-    
-    
-    /**
-    *  Decodifica os tokens encontrados na funÃ§Ã£o decodeMimeString
-    * 
-    * @license    http://www.gnu.org/copyleft/gpl.html GPL
-    * @author     ConsÃ³rcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
-    * @sponsor    Caixa EconÃ³mica Federal
-    * @author     Cristiano CorrÃªa Schmidt
-    * @return     bool
-    * @access     public
-    */
-    static private function decodeMimeStringCallback( $mathes )
-    {
-       $str = (strtolower($mathes[2]) == 'q') ?  quoted_printable_decode(str_replace('_','=20',$mathes[3])) : base64_decode( $mathes[3]) ;
-       return ( strtoupper($mathes[1]) == 'ISO-8859-1' ) ? mb_convert_encoding(  $str , 'UTF-8' , 'ISO-8859-1') : $str;
-    }
-
-    /**
-    *  Decodifica uma string no formato mime RFC2047
-    *
-    * @license    http://www.gnu.org/copyleft/gpl.html GPL
-    * @author     ConsÃ³rcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
-    * @sponsor    Caixa EconÃ³mica Federal
-    * @author     Cristiano CorrÃªa Schmidt
-    * @return     bool
-    * @access     public
-    */
-    static private function decodeMimeString( $string )
-    {
-      $string =  preg_replace('/\?\=(\s)*\=\?/', '?==?', $string);
-      return preg_replace_callback( '/\=\?([^\?]*)\?([qb])\?([^\?]*)\?=/i' ,array( 'self' , 'decodeMimeStringCallback'), $string);
-    }
-    
-     /**
-    *  Formata um mailObject para um array com name e email
-    *
-    * @license    http://www.gnu.org/copyleft/gpl.html GPL
-    * @author     ConsÃ³rcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
-    * @sponsor    Caixa EconÃ³mica Federal
-    * @author     Cristiano CorrÃªa Schmidt
-    * @return     bool
-    * @access     public
-    */
-    static private function formatMailObject( $obj )
-    {
-	$return = array();
-	$return['mail'] = self::decodeMimeString($obj->mailbox) . (( isset( $obj->host) && $obj->host != ('unspecified-domain') &&  $obj->host !=  '.SYNTAX-ERROR.')? '@'. $obj->host : '');
-	$return['name'] = ( isset( $obj->personal ) && trim($obj->personal) !== '' ) ? self::decodeMimeString($obj->personal) :  $return['mail'];
-	return $return;
-    }
-}
Index: trunk/prototype/rest/dispatch.php
===================================================================
--- trunk/prototype/rest/dispatch.php	(revision 6528)
+++ trunk/prototype/rest/dispatch.php	(revision 7342)
@@ -1,7 +1,14 @@
 <?php
 // load Tonic library
-require_once __DIR__ . '/../library/tonic/lib/tonic.php';
-require_once __DIR__ . '/../api/controller.php';
-require_once ROOTPATH . '/rest/oauth/OAuth2StorageUserCredential.php';
+require_once(__DIR__ . '/../library/tonic/lib/tonic.php');
+require_once(__DIR__.'/../library/utils/Errors.php');
+require_once(__DIR__ . '/../api/controller.php');
+require_once(ROOTPATH . '/rest/oauth/OAuth2StorageUserCredential.php');
+
+// load adapters
+require_once(__DIR__."/../adapters/ExpressoAdapter.php");
+require_once(__DIR__."/../adapters/MailAdapter.php");
+require_once(__DIR__."/../adapters/CatalogAdapter.php");
+require_once(__DIR__."/../adapters/CalendarAdapter.php");
 
 //Retrieveing the mapping of the URIs and his respectives classNames and classPath
@@ -18,9 +25,10 @@
 $classpath = array();
 
-foreach( $config as $uri => $classFile ){
+foreach( $config as $uri => $classFile )
+{
     foreach( $classFile as $className => $filePath )
     {
-	$autoload[ $uri ] = $className;
-	$classpath[ $className ] = $filePath;
+		$autoload[ $uri ] = $className;
+		$classpath[ $className ] = $filePath;
     }
 }
@@ -49,13 +57,28 @@
 
 } catch (ResponseException $e) {
-    switch ($e->getCode()) {
-    case Response::UNAUTHORIZED:
-        $response = $e->response($request);
-        $response->addHeader('WWW-Authenticate', 'Basic realm="Tonic"');
-        break;
-    default:
-        $response = $e->response($request);
+    switch ($e->getCode())
+    {
+	    case Response::UNAUTHORIZED:
+	        $response = $e->response($request);
+	        $response->addHeader('WWW-Authenticate', 'Basic realm="Tonic"');
+	        break;
+	    
+		default:
+			$response = new Response($request);
+			$response->code = Response::OK;
+			$response->addHeader('content-type', 'application/json');
+			if($request->id)
+			{
+				$body['id']	= $request->id;
+			}
+			$body['error'] = array("code" => "".$e->getCode(), "message" => $e->getMessage());
+			
+			$response->body = json_encode($body);
+			
+			//$response = $e->response($request);
     }
 }
+
 $response->output();
 
+?>
Index: trunk/prototype/rest/core/LoginResource.php
===================================================================
--- trunk/prototype/rest/core/LoginResource.php	(revision 7342)
+++ trunk/prototype/rest/core/LoginResource.php	(revision 7342)
@@ -0,0 +1,55 @@
+<?php
+
+class LoginResource extends ExpressoAdapter {
+
+	private function getUserProfile(){
+		if($this->getExpressoVersion() != "2.2") {
+			$_SESSION['wallet']['user']['uidNumber'] = $GLOBALS['phpgw_info']['user']['account_id'];
+		}
+	
+		return array(
+				'contactID'			=> $GLOBALS['phpgw_info']['user']['account_dn'],
+				'contactMails' 		=> array($GLOBALS['phpgw_info']['user']['email']),
+				'contactPhones' 	=> array($GLOBALS['phpgw_info']['user']['telephonenumber']),
+				'contactFullName'	=> $GLOBALS['phpgw_info']['user']['fullname'],
+				'contactApps'		=> $this->getUserApps()
+		);
+	}
+	
+	private function getUserApps(){
+		// Load Granted Apps for Web Service
+		$config = parse_ini_file( __DIR__ . '/../../config/user.ini',true);
+		$apps 	= $config['Applications.mapping'];
+	
+		// Load Granted Apps for User
+		$contactApps = array();
+		$acl 	= CreateObject('phpgwapi.acl');
+		$user_id = $GLOBALS['phpgw_info']['user']['account_id']['acl'];
+		foreach($acl->get_user_applications($user_id) as $app => $value){
+			$enabledApp = array_search($app, $apps);
+			if($enabledApp !== FALSE)
+				$contactApps[] = $enabledApp;
+		}
+	
+		return $contactApps;
+	}
+	
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);
+		if($sessionid = $GLOBALS['phpgw']->session->create($this->getParam('user'), $this->getParam('password')))
+		{
+			$result = array(
+				'auth' 			=> $sessionid.":".$GLOBALS['phpgw']->session->kp3,
+				'profile' 		=> array($this->getUserProfile())
+			);
+			$this->setResult($result);
+		}
+		else
+		{
+			Errors::runException($GLOBALS['phpgw']->session->cd_reason);
+		}
+		return $this->getResponse();
+	}	
+
+}
Index: trunk/prototype/rest/core/LogoutResource.php
===================================================================
--- trunk/prototype/rest/core/LogoutResource.php	(revision 7342)
+++ trunk/prototype/rest/core/LogoutResource.php	(revision 7342)
@@ -0,0 +1,29 @@
+<?php
+class LogoutResource extends ExpressoAdapter {
+
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+		parent::post($request);
+		
+		if($this-> isLoggedIn())
+		{	if ($_SESSION['phpgw_session']['session_id'] && file_exists($GLOBALS['phpgw_info']['server']['temp_dir'].SEP.$_SESSION['phpgw_session']['session_id']))	
+			{
+				$dh = opendir($GLOBALS['phpgw_info']['server']['temp_dir']. SEP . $_SESSION['phpgw_session']['session_id']);
+				while ($file = readdir($dh)) 
+				{
+					if ($file != '.' && $file != '..') 
+					{
+						unlink($GLOBALS['phpgw_info']['server']['temp_dir'].SEP.$_SESSION['phpgw_session']['session_id'].SEP.$file);
+					}
+				}
+				rmdir($GLOBALS['phpgw_info']['server']['temp_dir'].SEP.$_SESSION['phpgw_session']['session_id']);
+			}
+			$GLOBALS['phpgw']->hooks->process('logout');
+			$GLOBALS['phpgw']->session->destroy($_SESSION['phpgw_session']['session_id'], $GLOBALS['kp3']);
+			$this->setResult(true);
+		}
+		
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();
+	}	
+}
Index: trunk/prototype/rest/core/ExpressoVersionResource.php
===================================================================
--- trunk/prototype/rest/core/ExpressoVersionResource.php	(revision 7342)
+++ trunk/prototype/rest/core/ExpressoVersionResource.php	(revision 7342)
@@ -0,0 +1,16 @@
+<?php
+
+class ExpressoVersionResource extends ExpressoAdapter {		
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request); 		 
+ 		
+		$result = array('expressoVersion' =>  $this->getExpressoVersion(),
+						'apiVersion' => '1.0');
+ 		$this->setResult($result);
+
+		//to Send Response (JSON RPC format)
+		return $this->getResponse(); 		
+	}
+
+}
Index: trunk/prototype/rest/calendar/EventsResource.php
===================================================================
--- trunk/prototype/rest/calendar/EventsResource.php	(revision 7342)
+++ trunk/prototype/rest/calendar/EventsResource.php	(revision 7342)
@@ -0,0 +1,134 @@
+<?php
+
+class EventsResource extends CalendarAdapter {
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);
+
+		if($this-> isLoggedIn())
+		{
+			$user_id     = $this->getUserId();
+			$tz_offset   = $this->getTimezoneOffset();
+			$date_start  = $this->getParam('dateStart');
+			$date_end    = $this->getParam('dateEnd');
+			$split_event = $this->getParam('splitEvent');	// Boolean 1 or 0 - if you want to split the events that last for more than 1 day
+
+			// check the dates parameters formats (ex: 31/12/2012 23:59:59, but the time is optional)
+			$regex_date  = '/^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/([12][0-9]{3})( ([01][0-9]|2[0-3])(:[0-5][0-9]){2})?$/';
+
+			if(!preg_match($regex_date, $date_start))
+				Errors::runException("CALENDAR_INVALID_START_DATE");
+
+			if(!preg_match($regex_date, $date_end))
+				Errors::runException("CALENDAR_INVALID_END_DATE");
+
+			// get the start timestamp UNIX from the parameter
+			$start_arr      = explode(' ', $date_start);
+			$start_date_arr = explode('/', $start_arr[0]);
+			$start_time_arr = !empty($start_arr[1]) ? explode(':', $start_arr[1]) : array('00', '00', '00');
+			$datetime       = mktime($start_time_arr[0],$start_time_arr[1],$start_time_arr[2],$start_date_arr[1],$start_date_arr[0],$start_date_arr[2]) - ($tz_offset);
+
+			// get the end timestamp UNIX from the parameter
+			$end_arr        = explode(' ', $date_end);
+			$end_date_arr   = explode('/', $end_arr[0]);
+			$end_time_arr   = !empty($end_arr[1]) ? explode(':', $end_arr[1]) : array('23', '59', '59');
+			$edatetime      = mktime($end_time_arr[0],$end_time_arr[1],$end_time_arr[2],$end_date_arr[1],$end_date_arr[0],$end_date_arr[2]) - ($tz_offset);
+
+			$sql  =  'SELECT DISTINCT '
+					.'phpgw_cal.cal_id, '
+					.'phpgw_cal.datetime, '
+					.'phpgw_cal.edatetime, '
+					.'phpgw_cal.title, '
+					.'phpgw_cal.description, '
+					.'phpgw_cal.location '
+					.'FROM phpgw_cal_user, phpgw_cal '
+					.'WHERE (phpgw_cal_user.cal_id = phpgw_cal.cal_id) ';
+
+			// user clauses
+			$sql .= ' AND (phpgw_cal_user.cal_login = ' . $user_id . ' OR (phpgw_cal.owner = ' . $user_id . ')) ';
+
+			// date range clauses
+			$sql .= ' AND ( '
+						.'   ( (phpgw_cal.datetime >= '.$datetime.') AND (phpgw_cal.edatetime <= '.$edatetime.') ) '
+						.'OR ( (phpgw_cal.datetime <= '.$datetime.') AND (phpgw_cal.edatetime >= '.$edatetime.') ) '
+						.'OR ( (phpgw_cal.datetime >= '.$datetime.') AND (phpgw_cal.datetime <= '.$edatetime.') AND (phpgw_cal.edatetime >= '.$edatetime.') ) '
+						.'OR ( (phpgw_cal.datetime <= '.$datetime.') AND (phpgw_cal.edatetime >= '.$datetime.') AND (phpgw_cal.edatetime <= '.$edatetime.') ) '
+					.') ';
+
+			$sql .= ' ORDER BY phpgw_cal.datetime ASC, phpgw_cal.edatetime ASC ';
+
+			if (!$this->getDb()->query($sql))
+				return false;
+
+			$events = array();
+			while($this->getDb()->next_record()) {
+				$row   = $this->getDb()->row();
+				$id    = $row['cal_id'];
+				$sdate = $row['datetime']  + ($tz_offset);
+				$edate = $row['edatetime'] + ($tz_offset);
+				$datetime  += ($tz_offset);
+				$edatetime += ($tz_offset);
+
+				$association_arr = array(
+							'eventID'          => 'cal_id',
+							'eventName'        => 'title',
+							'eventDescription' => 'description',
+							'eventLocation'    => 'location'
+						);
+
+				// if the event starts and ends in the same day OR the user does not want to split the event,
+				// return the event in only one register
+				if(date('d/m/Y', $sdate) == date('d/m/Y', $edate) || !$split_event){
+					foreach($association_arr AS $k => $v)
+						$events[$id][$k] = mb_convert_encoding($row[$v],"UTF8", "ISO_8859-1");
+
+					$events[$id]['eventStartDate'] = date('d/m/Y H:i', $sdate);
+					$events[$id]['eventEndDate']   = date('d/m/Y H:i', $edate);
+					$events[$id]['eventAllDay']    = '0';
+				}
+				// if the event lasts for more than one day AND the user wants it splitted day by day,
+				// return the event splitted into as many parts of the array as the days remaining
+				else{
+					// walk through the event date range, adding one register for each day
+					$step_date     = $sdate;
+					$step_date_ymd = date('Ymd', $step_date);
+					while($step_date_ymd <= date('Ymd', $edate) && $step_date_ymd <= date('Ymd', $edatetime)){
+						if($step_date_ymd >= date('Ymd', $datetime) && $step_date_ymd <= date('Ymd', $edatetime)){
+							foreach($association_arr AS $k => $v)
+								$events_tmp[$k] = $row[$v];
+
+							// the first day of the event
+							if($step_date == $sdate){
+								$events_tmp['eventStartDate'] = date('d/m/Y H:i',   $sdate);
+								$events_tmp['eventEndDate']   = date('d/m/Y 23:59', $sdate);
+								$events_tmp['eventAllDay']    = '0';
+							}
+							// the last day of the event
+							elseif($step_date_ymd == date('Ymd', $edate)){
+								$events_tmp['eventStartDate'] = date('d/m/Y 00:00', $edate);
+								$events_tmp['eventEndDate']   = date('d/m/Y H:i',   $edate);
+								$events_tmp['eventAllDay']    = '0';
+							}
+							// the other days
+							else{
+								$events_tmp['eventStartDate'] = date('d/m/Y 00:00', $step_date);
+								$events_tmp['eventEndDate']   = date('d/m/Y 23:59', $step_date);
+								$events_tmp['eventAllDay']    = '1';
+							}
+							$events[$id.$step_date_ymd] = $events_tmp;
+						}
+						$step_date     = strtotime("+1 day", $step_date);
+						$step_date_ymd = date('Ymd', $step_date);
+					}
+ 				}
+			}
+
+			$result = array ('events' => array_values($events));
+
+			$this->setResult($result);
+		}
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();
+	}
+
+}
Index: trunk/prototype/rest/calendar/CalendarLastResource.php
===================================================================
--- trunk/prototype/rest/calendar/CalendarLastResource.php	(revision 6528)
+++ 	(revision )
@@ -1,53 +1,0 @@
-<?php
-
-use prototype\api\Config as Config;
-
-class CalendarLastResource extends Resource{
-
-    
-    /**
-    * Busca os eventos contidos nas agendas assinas do usuÃ¡rio
-    *
-    * @license    http://www.gnu.org/copyleft/gpl.html GPL
-    * @author     ConsÃ³rcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
-    * @sponsor    Caixa EconÃŽmica Federal
-    * @author     Adriano Coutinho da Silva
-    * @return     Lista dos ultimos 10 eventos do usuÃ¡rio
-    * @access     public
-    **/
-    function GET($request){
-	$this->secured();
-
-	$calendar = Controller::find( array( 'concept' => 'calendarSignature' ), array('calendar'), array( 'filter' => array( '=', 'user',  Config::me("uidNumber") ) ) );
-
-	
-	
-	
-	if($calendar){
-	    $calendars = array();
-	    $timezones = array();
-
-	    foreach($calendar as $key => $value)
-		array_push($calendars, $value['calendar']);
-
-	    $calendarTimezone = Controller::find( array( 'concept' => 'calendar' ), array('id', 'timezone'), array( 'filter' => array( 'IN', 'id',  $calendars ) ) );
-
-	    foreach($calendarTimezone as $key => $value)
-		$timezones[ $value['id'] ] = $value['timezone'];
-
-
-	    $schedulables = Controller::find( array( 'concept' => 'schedulable' ), false, 
-		    array( 'filter' => array('AND', array('>=','rangeStart', (time() - 86400).'000'), array('<=','rangeEnd', (time() + 2592000).'000') ,array( 'IN', 'calendar', $calendars )), 'deepness' => 2, 'timezones' => $timezones) );
-
-	}
-	
-	$response = new Response($request);
-	$response->code = Response::OK;
-	$response->addHeader('Content-type', 'aplication/json');
-
-	$response->body = json_encode(( isset($schedulables) && $schedulables) ?  $schedulables : array());
-	return $response;
-    }
-}
-
-?>
Index: trunk/prototype/rest/availableServers/AvailableServersResource.php
===================================================================
--- trunk/prototype/rest/availableServers/AvailableServersResource.php	(revision 7342)
+++ trunk/prototype/rest/availableServers/AvailableServersResource.php	(revision 7342)
@@ -0,0 +1,64 @@
+<?php
+/**
+ * @uri /AvailableServers
+ */
+class AvailableServersResource extends Resource {
+
+	function post($request){
+		return $this->get($request);
+	}
+	
+	function get($request){
+		$error = null;		
+		parse_str($request->data, &$data);
+				
+		if( file_exists(__DIR__ . '/../../config/REST.ini') )
+		{
+			$restServers = parse_ini_file( __DIR__ . '/../../config/REST.ini', true );
+			
+			foreach( $restServers as $key => $value)
+			{
+				if(substr( $key, 0, 11 ) == "ServersRest")
+				{
+					$servers[] = $value;
+				}
+			}
+		}
+		else{
+			$error = array("code" => "001", "message" => "The servers list was not found.");
+		}
+
+		function cmp($a, $b)
+		{
+			return strcmp(strtolower($a["serverName"]), strtolower($b["serverName"]));
+		}
+	
+		if(count($servers) > 0){
+			usort($servers, "cmp");
+		}
+
+		$response = new Response($request);
+		$response->code = Response::OK;
+		$response->addHeader('content-type', 'application/json');
+				
+		$body = array();
+		
+		if($data['id']){
+			$body['id'] = $data['id']; 
+		}
+		if($servers){
+			$body['result'] = array( "servers" => $servers);
+		}
+		elseif($error){
+			$body['error'] = $error;
+		}
+		else{
+			$body['error'] = "OBJETO SEM RESULT E SEM ERRO REPORTADO.";
+		}
+						
+		$response->body = json_encode($body);
+			
+		return $response;
+	}		
+
+}
Index: trunk/prototype/rest/catalog/ContactPictureResource.php
===================================================================
--- trunk/prototype/rest/catalog/ContactPictureResource.php	(revision 7342)
+++ trunk/prototype/rest/catalog/ContactPictureResource.php	(revision 7342)
@@ -0,0 +1,46 @@
+<?php
+
+class ContactPictureResource extends CatalogAdapter {	
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);	
+		
+		if($this-> isLoggedIn()) 
+		{								
+			$contact = array();
+			$contactID = $this->getParam('contactID');
+			// User Contact
+			if($this->getParam('contactType') == 1 && $contactID != null){
+				$query = 'select A.id_contact, A.photo from phpgw_cc_contact A where A.id_contact='.$contactID.' and A.id_owner='.$this -> getUserId();
+				if (!$this->getDb()->query($query))
+					return false;
+				if($this->getDb()->next_record()) {
+					$row = $this->getDb()->row();
+					if($row['photo'] != null) {
+						$contact[] = array(
+								'contactID'		=> $row['id_contact'],
+								'contactImagePicture'	=> ($row['photo'] != null ? base64_encode($row['photo']) : "")
+						);
+					}
+				}
+			}
+			// Global Catalog
+			elseif($this->getParam('contactType') == 2){
+				if(!$contactID){
+					$contactID = $GLOBALS['phpgw_info']['user']['account_dn'];
+				}
+				$photo = $this->getUserLdapPhoto(urldecode($contactID));
+				$contact[] = array(
+						'contactID'		=> $contactID,
+						'contactImagePicture'	=> ($photo != null ? base64_encode($photo[0]) : "")
+				);
+	
+			}
+			$result = array ('contacts' => $contact);
+			$this->setResult($result);			
+		}
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();		
+	}	
+
+}
Index: trunk/prototype/rest/catalog/ContactsResource.php
===================================================================
--- trunk/prototype/rest/catalog/ContactsResource.php	(revision 7342)
+++ trunk/prototype/rest/catalog/ContactsResource.php	(revision 7342)
@@ -0,0 +1,70 @@
+<?php
+
+class ContactsResource extends CatalogAdapter {	
+	public function post($request){
+		// to Receive POST Params (use $this->params)
+ 		parent::post($request);	
+		
+		if($this-> isLoggedIn()) 
+		{			
+			
+			if($this->getParams()) {
+				$search = trim($this->getParam('search'));
+				$search = ($search ? mb_convert_encoding($search,"ISO_8859-1", "UTF8") : "");
+				
+				if($this->getParam('contactType') == 1) {
+					if($search != "") {
+						$query_contact = "(A.alias ilike '%$search%' or A.names_ordered ilike '%$search%' or C.connection_value ilike '%$search%') and";
+					}
+					elseif($this->getParam('contactID') > 0){
+						$query_contact = 'A.id_contact='.$this->getParam('contactID').' and';
+					}
+				}
+				elseif($this->getParam('contactType') == 2){
+					if($this-> getMinArgumentSearch() <= strlen($search))
+						return $this->getGlobalContacts($search, $this->getParam('contactID'));
+					else{
+						Errors::runException("CATALOG_MIN_ARGUMENT_SEARCH", $this-> getMinArgumentSearch());
+					}
+				}
+			}
+		
+			$query = 'select B.id_typeof_contact_connection, A.photo, A.id_contact, A.alias, A.given_names, A.family_names, A.names_ordered, A.birthdate, A.notes, C.connection_value from phpgw_cc_contact A, '.
+					'phpgw_cc_contact_conns B, phpgw_cc_connections C where A.id_contact = B.id_contact and B.id_connection = C.id_connection '.
+					' and '.$query_contact.' A.id_owner='.$this -> getUserId().' group by '.
+					' B.id_typeof_contact_connection, A.photo, A.id_contact, A.alias, A.given_names, A.family_names,A.names_ordered,A.birthdate, A.notes,C.connection_value	order by lower(A.names_ordered)';
+		
+			if (!$this->getDb()->query($query))
+				return false;
+		
+			$contacts = array();
+			while($this->getDb()->next_record()) {
+				$row = $this->getDb()->row();
+				$id = $row['id_contact'];
+				$contactType = ($row['id_typeof_contact_connection'] == 2 ? 'contactPhones' : 'contactMails');
+		
+				if($contacts[$id] != null){
+					$contacts[$id][$contactType][] = $row['connection_value'];
+				}
+				else{
+					$contacts[$id] = array(
+							'contactID'		=> $row['id_contact'],
+							$contactType	=> array($row['connection_value']),
+							'contactAlias' => ($row['alias'] != null ?  mb_convert_encoding($row['alias'],"UTF8", "ISO_8859-1") : ""),
+							'contactFirstName'	=> ($row['given_names'] != null ?  mb_convert_encoding($row['given_names'],"UTF8", "ISO_8859-1") : ""),
+							'contactLastName' 	=> ($row['family_names'] != null ?  mb_convert_encoding($row['family_names'],"UTF8", "ISO_8859-1") : ""),
+							'contactFullName' 	=> ($row['names_ordered'] != null ? mb_convert_encoding($row['names_ordered'],"UTF8", "ISO_8859-1") : ""),
+							'contactBirthDate'	=> ($row['birthdate'] != null ? $row['birthdate'] : ""),
+							'contactNotes' 		=> ($row['notes'] != null ?  mb_convert_encoding($row['notes'],"UTF8", "ISO_8859-1") : ""),
+							'contactHasImagePicture' => ($row['photo'] != null ? 1 : 0),
+					);
+				}
+			}
+			$result = array ('contacts' => array_values($contacts));
+			$this->setResult($result);
+		}
+		//to Send Response (JSON RPC format)
+		return $this->getResponse();		
+	}	
+
+}
