Index: /contrib/psync/src/main/sql/postgresql/create_schema.sql
===================================================================
--- /contrib/psync/src/main/sql/postgresql/create_schema.sql	(revision 1103)
+++ /contrib/psync/src/main/sql/postgresql/create_schema.sql	(revision 1545)
@@ -1,8 +1,8 @@
-ALTER TABLE phpgw_cal ALTER title TYPE character varying(255);
-ALTER TABLE phpgw_cal ADD COLUMN last_status char(1) DEFAULT 'N'::bpchar;
-ALTER TABLE phpgw_cal ADD COLUMN last_update int8 DEFAULT (date_part('epoch'::text, ('now'::text)::timestamp(3) with time zone) * (1000)::double precision);
+--ALTER TABLE phpgw_cal ALTER title TYPE character varying(255);
+--ALTER TABLE phpgw_cal ADD COLUMN last_status char(1) DEFAULT 'N'::bpchar;
+--ALTER TABLE phpgw_cal ADD COLUMN last_update int8 DEFAULT (date_part('epoch'::text, ('now'::text)::timestamp(3) with time zone) * (1000)::double precision);
 
-ALTER TABLE phpgw_cc_contact ADD COLUMN last_status char(1) DEFAULT 'N'::bpchar;
-ALTER TABLE phpgw_cc_contact ADD COLUMN last_update int8 DEFAULT (date_part('epoch'::text, ('now'::text)::timestamp(3) with time zone) * (1000)::double precision);
-ALTER TABLE phpgw_cc_contact ADD COLUMN category character varying(20);
+--ALTER TABLE phpgw_cc_contact ADD COLUMN last_status char(1) DEFAULT 'N'::bpchar;
+--ALTER TABLE phpgw_cc_contact ADD COLUMN last_update int8 DEFAULT (date_part('epoch'::text, ('now'::text)::timestamp(3) with time zone) * (1000)::double precision);
+--ALTER TABLE phpgw_cc_contact ADD COLUMN category character varying(20);
 
Index: /contrib/psync/src/main/sql/postgresql/drop_schema.sql
===================================================================
--- /contrib/psync/src/main/sql/postgresql/drop_schema.sql	(revision 1009)
+++ /contrib/psync/src/main/sql/postgresql/drop_schema.sql	(revision 1545)
@@ -1,6 +1,6 @@
-ALTER TABLE public.phpgw_cal DROP COLUMN last_status;
-ALTER TABLE public.phpgw_cal DROP COLUMN last_update;
+--ALTER TABLE public.phpgw_cal DROP COLUMN last_status;
+--ALTER TABLE public.phpgw_cal DROP COLUMN last_update;
 
-ALTER TABLE public.phpgw_cc_contact DROP COLUMN last_status;
-ALTER TABLE public.phpgw_cc_contact DROP COLUMN last_update;
-ALTER TABLE public.phpgw_cc_contact DROP COLUMN category;
+--ALTER TABLE public.phpgw_cc_contact DROP COLUMN last_status;
+--ALTER TABLE public.phpgw_cc_contact DROP COLUMN last_update;
+--ALTER TABLE public.phpgw_cc_contact DROP COLUMN category;
Index: /contrib/psync/src/main/java/br/com/prognus/psync/items/dao/PIMContactDAO.java
===================================================================
--- /contrib/psync/src/main/java/br/com/prognus/psync/items/dao/PIMContactDAO.java	(revision 1103)
+++ /contrib/psync/src/main/java/br/com/prognus/psync/items/dao/PIMContactDAO.java	(revision 1545)
@@ -32,12 +32,18 @@
 import br.com.prognus.psync.exception.PIMDBAccessException;
 import br.com.prognus.psync.items.model.ContactWrapper;
+import br.com.prognus.psync.util.Country;
 import br.com.prognus.psync.util.Def;
-
+import br.com.prognus.psync.util.TypeAddress;
+
+import com.funambol.common.pim.common.Property;
+import com.funambol.common.pim.contact.Address;
 import com.funambol.common.pim.contact.BusinessDetail;
 import com.funambol.common.pim.contact.Contact;
 import com.funambol.common.pim.contact.Email;
 import com.funambol.common.pim.contact.Name;
+import com.funambol.common.pim.contact.Note;
 import com.funambol.common.pim.contact.PersonalDetail;
 import com.funambol.common.pim.contact.Phone;
+import com.funambol.common.pim.contact.Photo;
 import com.funambol.framework.security.Sync4jPrincipal;
 import com.funambol.framework.server.store.NotFoundException;
@@ -55,5 +61,5 @@
 			+ "WHERE id_owner = ?";
 
-	private static final String SQL_GET_CONTACT_BY_ID_USER = "SELECT id_contact, id_owner, last_update, last_status, given_names, family_names, birthdate, category FROM phpgw_cc_contact WHERE id_contact = ? AND id_owner = ? LIMIT 1";
+	private static final String SQL_GET_CONTACT_BY_ID_USER = "SELECT id_contact, id_owner, last_update, last_status, given_names, family_names, birthdate, category, photo, notes, alias FROM phpgw_cc_contact WHERE id_contact = ? AND id_owner = ? LIMIT 1";
 
 	private static final String SQL_GET_CONTACT_ITEM_BY_ID = "SELECT connection_name, connection_value, id_typeof_contact_connection FROM phpgw_cc_connections AS CO LEFT JOIN phpgw_cc_contact_conns AS CC ON CO.id_connection = CC.id_connection WHERE id_contact = ?";
@@ -73,6 +79,6 @@
 
 	private static final String SQL_INSERT_INTO_FNBL_PIM_CONTACT = "INSERT INTO phpgw_cc_contact "
-			+ "(id_contact, id_owner, id_status, given_names, family_names, names_ordered, birthdate, category, last_update, last_status ) "
-			+ "VALUES " + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ";
+			+ "(id_contact, id_owner, id_status, given_names, family_names, names_ordered, birthdate, category, photo, notes, alias, last_update, last_status ) "
+			+ "VALUES " + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ";
 
 	private static final String SQL_INSERT_INTO_CONTACT_ITEM = "INSERT INTO phpgw_cc_connections "
@@ -87,5 +93,28 @@
 
 	private static final String SQL_UPDATE_FNBL_PIM_CONTACT_END = " WHERE id_contact = ? AND id_owner = ? ";
-
+	
+	
+	private static final String SQL_GET_CONTACT_ADDRESS_ITEM = " select ad.complement, ad.address1, ad.postal_code, ca.id_typeof_contact_address, city_name, state_name, cy.id_country from phpgw_cc_addresses AS ad JOIN phpgw_cc_contact_addrs AS ca ON ad.id_address=ca.id_address, phpgw_cc_city AS cy JOIN phpgw_cc_state AS st ON cy.id_state=st.id_state where cy.id_city=ad.id_city and ad.id_address in (select min(ca.id_address) from phpgw_cc_contact AS cc JOIN phpgw_cc_contact_addrs AS ca ON cc.id_contact=ca.id_contact JOIN phpgw_cc_addresses AS ad ON ca.id_address=ad.id_address where cc.id_contact = ? AND cc.id_owner = ? and ca.id_typeof_contact_address = ? )";
+
+	private static final String SQL_GET_STATE_ITEM = "SELECT id_state, id_country, state_name, state_symbol FROM phpgw_cc_state ";
+	
+	private static final String SQL_GET_CITY_ITEM = "SELECT id_city, id_state, id_country, city_timezone, city_geo_location, city_name FROM phpgw_cc_city ";
+
+	private static final String SQL_INSERT_STATE = "INSERT INTO phpgw_cc_state(id_state, id_country, state_name, state_symbol) VALUES (?, ?, ?, ?)";
+	
+	private static final String SQL_INSERT_CITY = "INSERT INTO phpgw_cc_city(id_city, id_state, id_country, city_timezone, city_geo_location, city_name) VALUES (?, ?, ?, ?, ?, ?)";
+	
+	private static final String SQL_INSERT_ADDRESS = "INSERT INTO phpgw_cc_addresses(id_address, id_city, id_state, id_country, address1, complement, postal_code, address_is_default) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
+	
+	private static final String SQL_INSERT_CONTACT_ADDRESS = "INSERT INTO phpgw_cc_contact_addrs(id_contact, id_address, id_typeof_contact_address) VALUES (?, ?, ?)";
+
+	private static final int SQL_ADDRESS_DIM = 60;
+	
+	private static final String SQL_ID_MAX_ADDRESS = "select max(id_address) FROM phpgw_cc_addresses";
+	
+	private static final String SQL_ID_MAX_STATE = "select max(id_state) FROM phpgw_cc_state";
+	
+	private static final String SQL_ID_MAX_CITY = "select max(id_city) FROM phpgw_cc_city";
+	
 	private static final String SQL_EQUALS_QUESTIONMARK = " = ?";
 
@@ -111,4 +140,8 @@
 
 	protected static final String SQL_FIELD_CATEGORY = "category";
+	
+	protected static final String SQL_FIELD_PHOTO = "photo";
+	
+	protected static final String SQL_FIELD_NOTES = "notes";
 
 	protected static final int SQL_FIRSTNAME_DIM = 49;
@@ -121,4 +154,6 @@
 
 	protected static final int SQL_CATEGORY_DIM = 20;
+	
+	protected static final int SQL_NICK_DIM = 30;
 
 	protected static final String TYPE_EMAIL_1_ADDRESS = "Principal";
@@ -159,4 +194,22 @@
 
 	protected static final String SQL_FIELD_ITEM_TYPE = "id_typeof_contact_connection";
+	
+	protected static final String SQL_FIELD_TYPEOF = "id_typeof_contact_address";
+	
+	protected static final String SQL_FIELD_COMPLEMENT = "complement";
+	
+	protected static final String SQL_FIELD_ADDRESS1 = "address1";
+		
+	protected static final String SQL_FIELD_POSTALCODE = "postal_code";
+	
+	protected static final String SQL_FIELD_CITY_NAME = "city_name";
+	
+	protected static final String SQL_FIELD_STATE_NAME = "state_name";
+	
+	protected static final String SQL_FIELD_COUNTRY_ID = "id_country";
+	
+	protected static final String SQL_FIELD_STATE_ID = "id_state";
+	
+	protected static final String SQL_FIELD_CITY_ID = "id_city";
 
 	private Sync4jPrincipal principal = null;
@@ -193,4 +246,5 @@
 	 * @see ContactWrapper
 	 */
+	@SuppressWarnings("unchecked")
 	public void addItem(ContactWrapper cw) throws PIMDBAccessException {
 
@@ -223,4 +277,7 @@
 		StringBuffer fullName = null;
 		Date anniversary = null;
+		byte[] imagePhoto = null;
+		String note = null;
+		String alias = null;
 
 		try {
@@ -232,4 +289,15 @@
 			Timestamp lastUpdate = cw.getLastUpdate();
 
+			try {
+				List<Note> notes = c.getNotes();
+				int i = notes.size() - 1;
+				note = notes.get(i).getPropertyValueAsString();
+			} catch (Exception e) {
+//				log.error(e.getMessage(),e);
+			}
+			if(note==null) {
+				note="";
+			}
+			
 			personalDetail = c.getPersonalDetail();
 			businessDetail = c.getBusinessDetail();
@@ -244,4 +312,5 @@
 				birthday = personalDetail.getBirthday();
 				category = stringFrom(c.getCategories());
+				imagePhoto = personalDetail.getPhotoObject().getImage();
 			}
 
@@ -254,4 +323,5 @@
 				firstName = stringFrom(name.getFirstName());
 				lastName = stringFrom(name.getLastName());
+				alias = stringFrom(name.getNickname());
 			}
 
@@ -297,6 +367,9 @@
 			ps.setDate(7, anniversary); // birthdate
 			ps.setString(8, truncate(category, SQL_CATEGORY_DIM)); // category
-			ps.setLong(9, lastUpdate.getTime()); // last_update
-			ps.setString(10, String.valueOf(Def.PIM_STATE_NEW)); // last_status
+			ps.setBytes(9, imagePhoto); // photo
+			ps.setString(10, note); // note
+			ps.setString(11, truncate(alias, SQL_NICK_DIM)); // alias
+			ps.setLong(12, lastUpdate.getTime()); // last_update
+			ps.setString(13, String.valueOf(Def.PIM_STATE_NEW)); // last_status
 			ps.executeUpdate();
 
@@ -483,4 +556,9 @@
 		String category = null;
 		Date anniversary = null;
+		byte[] imagePhoto = null;
+		String note = null;
+		String alias = null;
+		Address persoAddress = null;
+		Address businAddress = null;
 
 		try {
@@ -495,4 +573,15 @@
 			Contact c = cw.getContact();
 
+			try {
+				List<Note> notes = c.getNotes();
+				int i = notes.size() - 1;
+				note = notes.get(i).getPropertyValueAsString();
+			} catch (Exception e) {
+//				log.error(e.getMessage(),e);
+			}
+			if(note==null) {
+				note="";
+			}
+			
 			personalDetail = c.getPersonalDetail();
 			businessDetail = c.getBusinessDetail();
@@ -505,4 +594,6 @@
 				birthday = personalDetail.getBirthday();
 				category = stringFrom(c.getCategories());
+				imagePhoto = personalDetail.getPhotoObject().getImage();
+				persoAddress = personalDetail.getAddress();
 			}
 
@@ -510,4 +601,5 @@
 				emails.addAll(businessDetail.getEmails());
 				phones.addAll(businessDetail.getPhones());
+				businAddress = businessDetail.getAddress();
 			}
 
@@ -515,4 +607,5 @@
 				firstName = stringFrom(name.getFirstName());
 				lastName = stringFrom(name.getLastName());
+				alias = stringFrom(name.getNickname());
 			}
 
@@ -525,4 +618,7 @@
 			if (category != null && category.length() > SQL_CATEGORY_DIM) {
 				category = category.substring(0, SQL_CATEGORY_DIM);
+			}
+			if (alias != null && alias.length() > SQL_NICK_DIM) {
+				alias = alias.substring(0, SQL_NICK_DIM);
 			}
 
@@ -563,4 +659,10 @@
 			queryUpdateFunPimContact.append(SQL_FIELD_CATEGORY
 					+ SQL_EQUALS_QUESTIONMARK_COMMA);
+			queryUpdateFunPimContact.append(SQL_FIELD_PHOTO
+					+ SQL_EQUALS_QUESTIONMARK_COMMA);
+			queryUpdateFunPimContact.append(SQL_FIELD_NOTES
+					+ SQL_EQUALS_QUESTIONMARK_COMMA);
+			queryUpdateFunPimContact.append(SQL_FIELD_NICK
+					+ SQL_EQUALS_QUESTIONMARK_COMMA);
 			queryUpdateFunPimContact
 					.append(SQL_FIELD_STATUS + SQL_EQUALS_QUESTIONMARK
@@ -575,7 +677,10 @@
 			ps.setDate(5, anniversary); // birthdate
 			ps.setString(6, category); // category
-			ps.setString(7, String.valueOf(Def.PIM_STATE_UPDATED)); // last_status
-			ps.setLong(8, id_contact); // id_contact
-			ps.setLong(9, Long.parseLong(userId)); // id_owner
+			ps.setBytes(7, imagePhoto); // photo
+			ps.setString(8, note); // notes
+			ps.setString(9, alias); // alias
+			ps.setString(10, String.valueOf(Def.PIM_STATE_UPDATED)); // last_status
+			ps.setLong(11, id_contact); // id_contact
+			ps.setLong(12, Long.parseLong(userId)); // id_owner
 			ps.executeUpdate();
 
@@ -730,4 +835,88 @@
 			}
 
+			
+			// endereco
+			boolean syncAddress = true;
+			if(syncAddress) {
+			// Apaga os contatos na tabela phpgw_cc_addresses
+			ps = con
+					.prepareStatement("DELETE FROM phpgw_cc_addresses WHERE id_address IN (SELECT id_address FROM phpgw_cc_contact_addrs WHERE id_contact = ?)");
+			ps.setLong(1, id_contact);
+			ps.executeUpdate();
+		
+			// Apaga os contatos na tabela phpgw_cc_contact_addrs
+			ps = con
+					.prepareStatement("DELETE FROM phpgw_cc_contact_addrs WHERE id_contact = ?");
+			ps.setLong(1, id_contact);
+			ps.executeUpdate();
+			
+			// Para cadas tipo de endereco RESIDENCIAL | COMERCIAL
+			for (TypeAddress typeAddress: TypeAddress.values()) {
+				
+				Address address = null;
+				boolean defaultAddress = false;
+				
+				// se ambos sao nulos não faz nada aqui
+				if (persoAddress == null && businAddress == null) {
+					break;
+				}
+				
+				if (typeAddress.equals(TypeAddress.RESIDENCIAL)) {
+					address=persoAddress;
+					defaultAddress = true;
+				} else if (typeAddress.equals(TypeAddress.COMERCIAL)) {
+					address=businAddress;
+				}
+				
+				// Pula para o proximo
+				if(address == null) {
+					continue;
+				}
+				
+				String addressValue = address.getStreet().getPropertyValueAsString();
+				addressValue  = truncate(addressValue, SQL_ADDRESS_DIM);
+	
+				if (addressValue != null && addressValue.length() != 0) {
+
+					// Verifica o id maximo da tabela phpgw_cc_addresses
+					ps = con.prepareStatement(SQL_ID_MAX_ADDRESS);
+					rs = ps.executeQuery();
+					long id_address = 0;
+					
+					if (rs.next()) {
+						long id = rs.getInt(1);
+						id_address = (id == 0) ? 1 : ++id;
+					}
+
+					// Insere o endereco do contato na tabela
+					String idCountry;
+					try {
+						idCountry = Country.getCountryByName(address
+								.getCountry().getPropertyValueAsString()).getCode();
+					} catch (Exception e) {
+						idCountry = "BR";
+					}
+					long idState = searchStateId(con, address.getState().getPropertyValueAsString(), idCountry);
+					long idCity = searchCityId(con, address.getCity().getPropertyValueAsString(), idState, idCountry);
+					
+					ps = con.prepareStatement(SQL_INSERT_ADDRESS);
+					ps.setLong(1, id_address);
+					ps.setLong(2, idCity);
+					ps.setLong(3, idState);
+					ps.setString(4, idCountry);
+					ps.setString(5, addressValue);
+					ps.setString(6, address.getExtendedAddress().getPropertyValueAsString());
+					ps.setString(7, address.getPostalCode().getPropertyValueAsString());
+					ps.setBoolean(8, defaultAddress);
+					ps.executeUpdate();
+
+					ps = con.prepareStatement(SQL_INSERT_CONTACT_ADDRESS);
+					ps.setLong(1, id_contact);
+					ps.setLong(2, id_address);
+					ps.setInt(3, typeAddress.getId());
+					ps.executeUpdate();
+				}
+			}
+			}
 			con.commit();
 			con.setAutoCommit(true);
@@ -743,4 +932,99 @@
 
 		return Long.toString(id_contact);
+	}
+
+
+	private long searchStateId(Connection con, String stateName, String idCountry) throws Exception {
+		
+		PreparedStatement ps = null;
+		ResultSet rs = null;
+		long stateId = 0;
+		
+		try {
+			String SQL_GET_STATE = SQL_GET_STATE_ITEM + " where upper("
+					+ SQL_FIELD_STATE_NAME + ")" + SQL_EQUALS_QUESTIONMARK
+					+ " and " + SQL_FIELD_COUNTRY_ID + SQL_EQUALS_QUESTIONMARK;
+			ps = con.prepareStatement(SQL_GET_STATE);
+			ps.setString(1, stateName.toUpperCase());
+			ps.setString(2, idCountry);
+			rs = ps.executeQuery();
+			if (rs.next()) {
+				stateId = rs.getInt(SQL_FIELD_STATE_ID);
+				return stateId;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+		ps = con.prepareStatement(SQL_ID_MAX_STATE);
+		rs = ps.executeQuery();
+		
+		if (rs.next()) {
+			long id = rs.getInt(1);
+			stateId = (id == 0) ? 1 : ++id;
+		}
+		else {
+			return 0;
+		}
+		
+		ps = con.prepareStatement(SQL_INSERT_STATE);
+		ps.setLong(1, stateId);
+		ps.setString(2, idCountry);
+		ps.setString(3, stateName);
+		ps.setString(4, stateName.substring(0, 2));
+		if(ps.executeUpdate() > 0) {
+			return stateId;
+		}
+		
+		return 0;
+	}
+
+	private long searchCityId(Connection con, String cityName, long idState, String idCountry) throws Exception {
+		
+		PreparedStatement ps = null;
+		ResultSet rs = null;
+		long cityId = 0;
+		
+		try {
+			String SQL_GET_CITY = SQL_GET_CITY_ITEM + " where "
+					+ SQL_FIELD_STATE_ID + SQL_EQUALS_QUESTIONMARK + " and "
+					+ SQL_FIELD_COUNTRY_ID + SQL_EQUALS_QUESTIONMARK
+					+ " and upper(" + SQL_FIELD_CITY_NAME + ")"
+					+ SQL_EQUALS_QUESTIONMARK;
+			ps = con.prepareStatement(SQL_GET_CITY);
+			ps.setLong(1, idState);
+			ps.setString(2, idCountry);
+			ps.setString(3, cityName.toUpperCase());
+			rs = ps.executeQuery();
+			if (rs.next()) {
+				cityId = rs.getInt(SQL_FIELD_CITY_ID);
+				return cityId;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		ps = con.prepareStatement(SQL_ID_MAX_CITY);
+		rs = ps.executeQuery();
+		
+		if (rs.next()) {
+			long id = rs.getInt(1);
+			cityId = (id == 0) ? 1 : ++id;
+		}
+		else {
+			return 0;
+		}
+		
+		ps = con.prepareStatement(SQL_INSERT_CITY);
+		ps.setLong(1, cityId);
+		ps.setLong(2, idState);
+		ps.setString(3, idCountry);
+		ps.setNull(4, 0);
+		ps.setString(5, null);
+		ps.setString(6, cityName);
+		if(ps.executeUpdate() > 0) {
+			return cityId;
+		}
+		
+		return 0;
 	}
 
@@ -954,4 +1238,30 @@
 								.getSQLState());
 			}
+			
+			try {
+				ps = con.prepareStatement(SQL_GET_CONTACT_ADDRESS_ITEM);
+				ps.setLong(1, Long.parseLong(uid));
+				ps.setLong(2, Long.parseLong(userId));
+				ps.setInt(3, TypeAddress.RESIDENCIAL.getId());
+				rs = ps.executeQuery();
+				
+				Address address = c.getContact().getPersonalDetail().getAddress();
+				addAddress(address, rs);
+			} catch (Exception e) {
+				throw new SQLException("\nError while adding personal address information");
+			}
+
+			try {
+				ps = con.prepareStatement(SQL_GET_CONTACT_ADDRESS_ITEM);
+				ps.setLong(1, Long.parseLong(uid));
+				ps.setLong(2, Long.parseLong(userId));
+				ps.setInt(3, TypeAddress.COMERCIAL.getId());
+				rs = ps.executeQuery();
+				
+				Address address = c.getContact().getBusinessDetail().getAddress();
+				addAddress(address, rs);
+			} catch (Exception e) {
+				throw new SQLException("\nError while adding business address information");
+			}
 
 		} catch (Exception e) {
@@ -963,4 +1273,46 @@
 
 		return c;
+	}
+	
+	
+	private static void addAddress(Address address, ResultSet rs) throws Exception {
+		
+		ResultSetMetaData rsmd = rs.getMetaData();
+
+		String column = null;
+		int columnCount = 0;
+		
+		while (rs.next()) {
+
+			columnCount = rsmd.getColumnCount();
+			
+			if (rs.getString(SQL_FIELD_ADDRESS1)==null || (rs.getString(SQL_FIELD_ADDRESS1)!=null && "".equals(rs.getString(SQL_FIELD_ADDRESS1).trim()))) {
+				break;
+			}
+
+			for (int i = 1; i <= columnCount; ++i) {
+
+				column = rsmd.getColumnName(i);
+				if (SQL_FIELD_TYPEOF.equalsIgnoreCase(column)) {
+					continue;
+				} else if (SQL_FIELD_COMPLEMENT.equalsIgnoreCase(column)) {
+					address.getExtendedAddress().setPropertyValue(rs.getString(i));
+				} else if (SQL_FIELD_ADDRESS1.equalsIgnoreCase(column)) {
+					address.getStreet().setPropertyValue(rs.getString(i));
+				} else if (SQL_FIELD_POSTALCODE.equalsIgnoreCase(column)) {
+					address.getPostalCode().setPropertyValue(rs.getString(i));
+				} else if (SQL_FIELD_CITY_NAME.equalsIgnoreCase(column)) {
+					address.getCity().setPropertyValue(rs.getString(i));
+				} else if (SQL_FIELD_STATE_NAME.equalsIgnoreCase(column)) {
+					address.getState().setPropertyValue(rs.getString(i));
+				} else if (SQL_FIELD_COUNTRY_ID.equalsIgnoreCase(column)) {
+					Country country = Country.getCountryByCode(rs.getString(i));
+					address.getCountry().setPropertyValue(country.getName());
+				} else {
+					throw new SQLException("\n=> Unhandled column: " + column);
+				}
+				
+			}		
+		}
 	}
 
@@ -1169,4 +1521,35 @@
 			} else if (SQL_FIELD_CATEGORY.equalsIgnoreCase(column)) {
 				c.getCategories().setPropertyValue(rs.getString(i));
+			} else if (SQL_FIELD_PHOTO.equalsIgnoreCase(column)) {
+				if(c.getPersonalDetail()==null) {
+					PersonalDetail pd = new PersonalDetail();
+					c.setPersonalDetail(pd);
+				}
+				Photo photo = new Photo();
+				photo.setImage(rs.getBytes(i));
+				c.getPersonalDetail().setPhotoObject(photo);
+			} else if (SQL_FIELD_NOTES.equalsIgnoreCase(column)) {
+				
+				try {
+					if(rs.getString(i) != null) {
+						if (c.getNotes() == null
+								|| (c.getNotes() != null && c.getNotes().size() != 1)
+								|| (c.getNotes() != null
+										&& c.getNotes().size() == 1 && c.getNotes()
+										.get(0) == null)) {
+							List<Note> l = new ArrayList<Note>(1);
+							l.add(new Note());
+							c.setNotes(l);
+						}
+						Note n = (Note) c.getNotes().get(0);
+						n.setPropertyValue(rs.getString(i));
+						n.setPropertyType("Body"); // HARD CODE
+					}
+				} catch (Exception e) {
+					log.error(e.getMessage(),e);
+				}
+
+			} else if (SQL_FIELD_NICK.equalsIgnoreCase(column)) {
+				c.getName().getNickname().setPropertyValue(rs.getString(i));
 			} else {
 				throw new SQLException("\n=> Unhandled column: " + column);
Index: /contrib/psync/src/main/java/br/com/prognus/psync/items/dao/PIMEntityDAO.java
===================================================================
--- /contrib/psync/src/main/java/br/com/prognus/psync/items/dao/PIMEntityDAO.java	(revision 1103)
+++ /contrib/psync/src/main/java/br/com/prognus/psync/items/dao/PIMEntityDAO.java	(revision 1545)
@@ -23,9 +23,14 @@
 import java.sql.ResultSet;
 import java.sql.Timestamp;
-import java.util.Enumeration;
-import java.util.Iterator;
+import java.util.Hashtable;
 import java.util.List;
 
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
 import javax.sql.DataSource;
 
@@ -38,11 +43,4 @@
 import com.funambol.framework.tools.DBTools;
 import com.funambol.framework.tools.DataSourceTools;
-import com.novell.ldap.LDAPAttribute;
-import com.novell.ldap.LDAPAttributeSet;
-import com.novell.ldap.LDAPConnection;
-import com.novell.ldap.LDAPEntry;
-import com.novell.ldap.LDAPException;
-import com.novell.ldap.LDAPSearchResults;
-import com.novell.ldap.util.Base64;
 
 public abstract class PIMEntityDAO {
@@ -123,73 +121,105 @@
 	// -----------------------------------------------------------Public methods
 
+	@SuppressWarnings("unchecked")
 	protected String LdapUID(String server, String dc, String user)
 			throws Exception {
 
-		LDAPConnection ldap = new LDAPConnection();
-		String searchAttrs[] = { "uidNumber" };
-		String id_owner = null;
-
-		try {
-
-			ldap.connect(server, 389);
-			LDAPSearchResults searchResults = ldap.search(dc,
-					LDAPConnection.SCOPE_SUB, "(uid=" + user + ")",
-					searchAttrs, false);
-
-			while (searchResults.hasMore()) {
-
-				LDAPEntry nextEntry = null;
-				try {
-					nextEntry = searchResults.next();
-				} catch (LDAPException e) {
-					if (e.getResultCode() == LDAPException.LDAP_TIMEOUT
-							|| e.getResultCode() == LDAPException.CONNECT_ERROR)
-						break;
-					else
-						continue;
-				}
-				LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
-				Iterator allAttributes = attributeSet.iterator();
-
-				while (allAttributes.hasNext()) {
-
-					LDAPAttribute attribute = (LDAPAttribute) allAttributes
-							.next();
-					String attributeName = attribute.getName();
-					Enumeration allValues = attribute.getStringValues();
-
-					if (allValues != null) {
-
-						while (allValues.hasMoreElements()) {
-
-							String Value = (String) allValues.nextElement();
-
-							if (Base64.isLDIFSafe(Value)) {
-							} else {
-								Value = Base64.encode(Value.getBytes());
-							}
-
-							if (attributeName.equalsIgnoreCase("uidNumber")) {
-								id_owner = Value;
-								break;
-							}
-
-						}
-					}
-				}
-			}
-
-			ldap.disconnect();
-
-			if (id_owner == null) {
-				throw new LDAPException();
-			}
-
-		} catch (LDAPException e) {
-			log.info("Error while connecting and binding to LDAP: "
-					+ e.toString());
-		}
-
-		return id_owner;
+		String uidNumber=null;
+		
+		Hashtable env = new Hashtable();
+        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+        env.put(Context.PROVIDER_URL, "ldap://" + server + ":" + 389);
+        
+        DirContext ctx = new InitialDirContext(env);
+        // Searching User
+        SearchControls ctls = new SearchControls();
+        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+        ctls.setCountLimit(1);
+        ctls.setTimeLimit(10000); // Espera no max 10 segundos
+        String filter = "(uid=" + user + ")";
+        
+        NamingEnumeration answer = ctx.search(dc, filter, ctls);
+        if (answer.hasMore()) {
+            SearchResult sr = (SearchResult) answer.next();
+            try {
+                // Getting User attributes
+                uidNumber = sr.getAttributes().get("uidNumber").get(0).toString();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        ctx.close();
+		if (uidNumber == null) {
+			log.info("Error while connecting and binding to LDAP");
+		}
+
+		return uidNumber;
+
+            
+//		LDAPConnection ldap = new LDAPConnection();
+//		String searchAttrs[] = { "uidNumber" };
+//		String id_owner = null;
+//
+//		try {
+//
+//			ldap.connect(server, 389);
+//			LDAPSearchResults searchResults = ldap.search(dc,
+//					LDAPConnection.SCOPE_SUB, "(uid=" + user + ")",
+//					searchAttrs, false);
+//
+//			while (searchResults.hasMore()) {
+//
+//				LDAPEntry nextEntry = null;
+//				try {
+//					nextEntry = searchResults.next();
+//				} catch (LDAPException e) {
+//					if (e.getResultCode() == LDAPException.LDAP_TIMEOUT
+//							|| e.getResultCode() == LDAPException.CONNECT_ERROR)
+//						break;
+//					else
+//						continue;
+//				}
+//				LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
+//				Iterator allAttributes = attributeSet.iterator();
+//
+//				while (allAttributes.hasNext()) {
+//
+//					LDAPAttribute attribute = (LDAPAttribute) allAttributes
+//							.next();
+//					String attributeName = attribute.getName();
+//					Enumeration allValues = attribute.getStringValues();
+//
+//					if (allValues != null) {
+//
+//						while (allValues.hasMoreElements()) {
+//
+//							String Value = (String) allValues.nextElement();
+//
+//							if (Base64.isLDIFSafe(Value)) {
+//							} else {
+//								Value = Base64.encode(Value.getBytes());
+//							}
+//
+//							if (attributeName.equalsIgnoreCase("uidNumber")) {
+//								id_owner = Value;
+//								break;
+//							}
+//
+//						}
+//					}
+//				}
+//			}
+//
+//			ldap.disconnect();
+//
+//			if (id_owner == null) {
+//				throw new LDAPException();
+//			}
+//
+//		} catch (LDAPException e) {
+//			log.info("Error while connecting and binding to LDAP: "
+//					+ e.toString());
+//		}
+//		return id_owner;
 	}
 
Index: /contrib/psync/src/main/java/br/com/prognus/psync/engine/source/PIMCalendarSyncSource.java
===================================================================
--- /contrib/psync/src/main/java/br/com/prognus/psync/engine/source/PIMCalendarSyncSource.java	(revision 1103)
+++ /contrib/psync/src/main/java/br/com/prognus/psync/engine/source/PIMCalendarSyncSource.java	(revision 1545)
@@ -77,5 +77,4 @@
 			this.manager = new PIMCalendarManager(JNDI_DATA_SOURCE_NAME, context.getPrincipal(), context.getSourceQuery());
 		} catch (Exception e) {
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
@@ -453,81 +452,89 @@
 	private String hackFix(String text) {
 
-		String result, head, title, clas, description, tail, new_title;
-		int p_categories, p_classes, p_location, p_dstart, values1, values2, op1, op2, op3, op4, op5, op6, op7, op8, qt1, qt2;
-
-		qt1 = 0;
-		qt2 = 0;
-
-		// Pega as posicoes das tags
-		p_categories = text.indexOf("CATEGORIES");
-		p_classes = text.indexOf("CLASS");
-
-		p_location = text.indexOf("LOCATION");
-		p_dstart = text.indexOf("DTSTART");
-
-		// Pega as posicoes das varias formas da tag SUMMARY
-		op1 = text.indexOf("SUMMARY:");
-		op2 = text.indexOf("SUMMARY;CHARSET=UTF-8:");
-		op3 = text.indexOf("SUMMARY;ENCODING=QUOTED-PRINTABLE:");
-		op4 = text.indexOf("SUMMARY;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:");
-
-		// Pega as posicoes das varias formas da tag DESCRIPTION
-		op5 = text.indexOf("DESCRIPTION:");
-		op6 = text.indexOf("DESCRIPTION;CHARSET=UTF-8:");
-		op7 = text.indexOf("DESCRIPTION;ENCODING=QUOTED-PRINTABLE:");
-		op8 = text.indexOf("DESCRIPTION;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:");
-
-		qt1 += (op1 == -1) ? 0 : op1 + 8;
-		qt1 += (op2 == -1) ? 0 : op2 + 22;
-		qt1 += (op3 == -1) ? 0 : op3 + 34;
-		qt1 += (op4 == -1) ? 0 : op4 + 48;
-
-		qt2 += (op5 == -1) ? 0 : op5 + 12;
-		qt2 += (op6 == -1) ? 0 : op6 + 26;
-		qt2 += (op7 == -1) ? 0 : op7 + 38;
-		qt2 += (op8 == -1) ? 0 : op8 + 52;
-
-		values1 = (p_categories == -1) ? p_classes : p_categories;
-		values2 = (p_location == -1) ? p_dstart : p_location;
-
-		head = text.substring(0, qt1);
-		title = text.substring(qt1, values1);
-		clas = text.substring(values1, qt2);
-		description = text.substring(qt2, values2);
-		tail = text.substring(values2);
-
-		new_title = title.replaceAll("\r\n ", " ");
-
-		// Retira os enters no final do titulo
-		int title_t, title_bl;
-
-		while(true){
-			title_t = new_title.length();
-			title_bl = new_title.lastIndexOf("=0D=0A=\r\n");
-
-			if(title_bl != -1 && title_t == title_bl + 11){
-				new_title = new_title.substring(0, title_bl) + "\r\n";
-			} else {
-				break;
-			}
-		}
-
-		// Retira os enters no final da descricao
-		int description_t, description_bl;
-
-		while(true){
-			description_t = description.length();
-			description_bl = description.lastIndexOf("=0D=0A=\r\n");
-
-			if(description_bl != -1 && description_t == description_bl + 11){
-				description = description.substring(0, description_bl) + "\r\n";
-			} else {
-				break;
-			}
-		}
-
-		result = head + new_title + clas + description + tail;
-
-		return result;
+		try {
+		
+			String result, head, title, clas, description, tail, new_title;
+			int p_categories, p_classes, p_location, p_dstart, values1, values2, op1, op2, op3, op4, op5, op6, op7, op8, qt1, qt2;
+	
+			qt1 = 0;
+			qt2 = 0;
+	
+			// Pega as posicoes das tags
+			p_categories = text.indexOf("CATEGORIES");
+			p_classes = text.indexOf("CLASS");
+	
+			p_location = text.indexOf("LOCATION");
+			p_dstart = text.indexOf("DTSTART");
+	
+			// Pega as posicoes das varias formas da tag SUMMARY
+			op1 = text.indexOf("SUMMARY:");
+			op2 = text.indexOf("SUMMARY;CHARSET=UTF-8:");
+			op3 = text.indexOf("SUMMARY;ENCODING=QUOTED-PRINTABLE:");
+			op4 = text.indexOf("SUMMARY;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:");
+	
+			// Pega as posicoes das varias formas da tag DESCRIPTION
+			op5 = text.indexOf("DESCRIPTION:");
+			op6 = text.indexOf("DESCRIPTION;CHARSET=UTF-8:");
+			op7 = text.indexOf("DESCRIPTION;ENCODING=QUOTED-PRINTABLE:");
+			op8 = text.indexOf("DESCRIPTION;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:");
+	
+			qt1 += (op1 == -1) ? 0 : op1 + 8;
+			qt1 += (op2 == -1) ? 0 : op2 + 22;
+			qt1 += (op3 == -1) ? 0 : op3 + 34;
+			qt1 += (op4 == -1) ? 0 : op4 + 48;
+	
+			qt2 += (op5 == -1) ? 0 : op5 + 12;
+			qt2 += (op6 == -1) ? 0 : op6 + 26;
+			qt2 += (op7 == -1) ? 0 : op7 + 38;
+			qt2 += (op8 == -1) ? 0 : op8 + 52;
+	
+			values1 = (p_categories == -1) ? p_classes : p_categories;
+			values2 = (p_location == -1) ? p_dstart : p_location;
+	
+			head = text.substring(0, qt1);
+			title = text.substring(qt1, values1);
+			clas = text.substring(values1, qt2);
+			description = text.substring(qt2, values2);
+			tail = text.substring(values2);
+	
+			new_title = title.replaceAll("\r\n ", " ");
+	
+			// Retira os enters no final do titulo
+			int title_t, title_bl;
+	
+			while(true){
+				title_t = new_title.length();
+				title_bl = new_title.lastIndexOf("=0D=0A=\r\n");
+	
+				if(title_bl != -1 && title_t == title_bl + 11){
+					new_title = new_title.substring(0, title_bl) + "\r\n";
+				} else {
+					break;
+				}
+			}
+	
+			// Retira os enters no final da descricao
+			int description_t, description_bl;
+	
+			while(true){
+				description_t = description.length();
+				description_bl = description.lastIndexOf("=0D=0A=\r\n");
+	
+				if(description_bl != -1 && description_t == description_bl + 11){
+					description = description.substring(0, description_bl) + "\r\n";
+				} else {
+					break;
+				}
+			}
+	
+			result = head + new_title + clas + description + tail;
+
+			return result;
+		}catch (Exception e) {
+			if (log.isTraceEnabled()) {
+				log.trace(e);
+			}
+			return text;
+		}
 	}
 
Index: /contrib/psync/src/main/java/br/com/prognus/psync/util/Country.java
===================================================================
--- /contrib/psync/src/main/java/br/com/prognus/psync/util/Country.java	(revision 1545)
+++ /contrib/psync/src/main/java/br/com/prognus/psync/util/Country.java	(revision 1545)
@@ -0,0 +1,279 @@
+package br.com.prognus.psync.util;
+
+/**
+ * From phpgwapi/inc/class.country.inc.php
+ * From http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html
+ *
+ */
+public enum Country {
+
+	AF ("AFGHANISTAN"),
+	AL ("ALBANIA"),
+	DZ ("ALGERIA"),
+	AS ("AMERICAN SAMOA"),
+	AD ("ANDORRA"),
+	AO ("ANGOLA"),
+	AI ("ANGUILLA"),
+	AQ ("ANTARCTICA"),
+	AG ("ANTIGUA AND BARBUDA"),
+	AR ("ARGENTINA"),
+	AM ("ARMENIA"),
+	AW ("ARUBA"),
+	AU ("AUSTRALIA"),
+	AT ("AUSTRIA"),
+	AZ ("AZERBAIJAN"),
+	BS ("BAHAMAS"),
+	BH ("BAHRAIN"),
+	BD ("BANGLADESH"),
+	BB ("BARBADOS"),
+	BY ("BELARUS"),
+	BE ("BELGIUM"),
+	BZ ("BELIZE"),
+	BJ ("BENIN"),
+	BM ("BERMUDA"),
+	BT ("BHUTAN"),
+	BO ("BOLIVIA"),
+	BA ("BOSNIA AND HERZEGOVINA"),
+	BW ("BOTSWANA"),
+	BV ("BOUVET ISLAND"),
+	BR ("BRAZIL"),
+	IO ("BRITISH INDIAN OCEAN TERRITORY"),
+	BN ("BRUNEI DARUSSALAM"),
+	BG ("BULGARIA"),
+	BF ("BURKINA FASO"),
+	BI ("BURUNDI"),
+	KH ("CAMBODIA"),
+	CM ("CAMEROON"),
+	CA ("CANADA"),
+	CV ("CAPE VERDE"),
+	KY ("CAYMAN ISLANDS"),
+	CF ("CENTRAL AFRICAN REPUBLIC"),
+	TD ("CHAD"),
+	CL ("CHILE"),
+	CN ("CHINA"),
+	CX ("CHRISTMAS ISLAND"),
+	CC ("COCOS (KEELING) ISLANDS"),
+	CO ("COLOMBIA"),
+	KM ("COMOROS"),
+	CG ("CONGO"),
+	CD ("CONGO, THE DEMOCRATIC REPUBLIC OF THE"),
+	CK ("COOK ISLANDS"),
+	CR ("COSTA RICA"),
+	CI ("COTE D IVOIRE"),
+	HR ("CROATIA"),
+	CU ("CUBA"),
+	CY ("CYPRUS"),
+	CZ ("CZECH REPUBLIC"),
+	DK ("DENMARK"),
+	DJ ("DJIBOUTI"),
+	DM ("DOMINICA"),
+	DO ("DOMINICAN REPUBLIC"),
+	TP ("EAST TIMOR"),
+	EC ("ECUADOR"),
+	EG ("EGYPT"),
+	SV ("EL SALVADOR"),
+	GQ ("EQUATORIAL GUINEA"),
+	ER ("ERITREA"),
+	EE ("ESTONIA"),
+	ET ("ETHIOPIA"),
+	FK ("FALKLAND ISLANDS (MALVINAS)"),
+	FO ("FAROE ISLANDS"),
+	FJ ("FIJI"),
+	FI ("FINLAND"),
+	FR ("FRANCE"),
+	GF ("FRENCH GUIANA"),
+	PF ("FRENCH POLYNESIA"),
+	TF ("FRENCH SOUTHERN TERRITORIES"),
+	GA ("GABON"),
+	GM ("GAMBIA"),
+	GE ("GEORGIA"),
+	DE ("GERMANY"),
+	GH ("GHANA"),
+	GI ("GIBRALTAR"),
+	GR ("GREECE"),
+	GL ("GREENLAND"),
+	GD ("GRENADA"),
+	GP ("GUADELOUPE"),
+	GU ("GUAM"),
+	GT ("GUATEMALA"),
+	GN ("GUINEA"),
+	GW ("GUINEA-BISSAU"),
+	GY ("GUYANA"),
+	HT ("HAITI"),
+	HM ("HEARD ISLAND AND MCDONALD ISLANDS"),
+	VA ("HOLY SEE (VATICAN CITY STATE)"),
+	HN ("HONDURAS"),
+	HK ("HONG KONG"),
+	HU ("HUNGARY"),
+	IS ("ICELAND"),
+	IN ("INDIA"),
+	ID ("INDONESIA"),
+	IR ("IRAN, ISLAMIC REPUBLIC OF"),
+	IQ ("IRAQ"),
+	IE ("IRELAND"),
+	IL ("ISRAEL"),
+	IT ("ITALY"),
+	JM ("JAMAICA"),
+	JP ("JAPAN"),
+	JO ("JORDAN"),
+	KZ ("KAZAKSTAN"),
+	KE ("KENYA"),
+	KI ("KIRIBATI"),
+	KP ("KOREA DEMOCRATIC PEOPLES REPUBLIC OF"),
+	KR ("KOREA REPUBLIC OF"),
+	KW ("KUWAIT"),
+	KG ("KYRGYZSTAN"),
+	LA ("LAO PEOPLES DEMOCRATIC REPUBLIC"),
+	LV ("LATVIA"),
+	LB ("LEBANON"),
+	LS ("LESOTHO"),
+	LR ("LIBERIA"),
+	LY ("LIBYAN ARAB JAMAHIRIYA"),
+	LI ("LIECHTENSTEIN"),
+	LT ("LITHUANIA"),
+	LU ("LUXEMBOURG"),
+	MO ("MACAU"),
+	MK ("MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF"),
+	MG ("MADAGASCAR"),
+	MW ("MALAWI"),
+	MY ("MALAYSIA"),
+	MV ("MALDIVES"),
+	ML ("MALI"),
+	MT ("MALTA"),
+	MH ("MARSHALL ISLANDS"),
+	MQ ("MARTINIQUE"),
+	MR ("MAURITANIA"),
+	MU ("MAURITIUS"),
+	YT ("MAYOTTE"),
+	MX ("MEXICO"),
+	FM ("MICRONESIA, FEDERATED STATES OF"),
+	MD ("MOLDOVA, REPUBLIC OF"),
+	MC ("MONACO"),
+	MN ("MONGOLIA"),
+	MS ("MONTSERRAT"),
+	MA ("MOROCCO"),
+	MZ ("MOZAMBIQUE"),
+	MM ("MYANMAR"),
+	NA ("NAMIBIA"),
+	NR ("NAURU"),
+	NP ("NEPAL"),
+	NL ("NETHERLANDS"),
+	AN ("NETHERLANDS ANTILLES"),
+	NC ("NEW CALEDONIA"),
+	NZ ("NEW ZEALAND"),
+	NI ("NICARAGUA"),
+	NE ("NIGER"),
+	NG ("NIGERIA"),
+	NU ("NIUE"),
+	NF ("NORFOLK ISLAND"),
+	MP ("NORTHERN MARIANA ISLANDS"),
+	NO ("NORWAY"),
+	OM ("OMAN"),
+	PK ("PAKISTAN"),
+	PW ("PALAU"),
+	PS ("PALESTINIAN TERRITORY, OCCUPIED"),
+	PA ("PANAMA"),
+	PG ("PAPUA NEW GUINEA"),
+	PY ("PARAGUAY"),
+	PE ("PERU"),
+	PH ("PHILIPPINES"),
+	PN ("PITCAIRN"),
+	PL ("POLAND"),
+	PT ("PORTUGAL"),
+	PR ("PUERTO RICO"),
+	QA ("QATAR"),
+	RE ("REUNION"),
+	RO ("ROMANIA"),
+	RU ("RUSSIAN FEDERATION"),
+	RW ("RWANDA"),
+	SH ("SAINT HELENA"),
+	KN ("SAINT KITTS AND NEVIS"),
+	LC ("SAINT LUCIA"),
+	PM ("SAINT PIERRE AND MIQUELON"),
+	VC ("SAINT VINCENT AND THE GRENADINES"),
+	WS ("SAMOA"),
+	SM ("SAN MARINO"),
+	ST ("SAO TOME AND PRINCIPE"),
+	SA ("SAUDI ARABIA"),
+	SN ("SENEGAL"),
+	SC ("SEYCHELLES"),
+	SL ("SIERRA LEONE"),
+	SG ("SINGAPORE"),
+	SK ("SLOVAKIA"),
+	SI ("SLOVENIA"),
+	SB ("SOLOMON ISLANDS"),
+	SO ("SOMALIA"),
+	ZA ("SOUTH AFRICA"),
+	GS ("SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS"),
+	ES ("SPAIN"),
+	LK ("SRI LANKA"),
+	SD ("SUDAN"),
+	SR ("SURINAME"),
+	SJ ("SVALBARD AND JAN MAYEN"),
+	SZ ("SWAZILAND"),
+	SE ("SWEDEN"),
+	CH ("SWITZERLAND"),
+	SY ("SYRIAN ARAB REPUBLIC"),
+	TW ("TAIWAN"),
+	TJ ("TAJIKISTAN"),
+	TZ ("TANZANIA, UNITED REPUBLIC OF"),
+	TH ("THAILAND"),
+	TG ("TOGO"),
+	TK ("TOKELAU"),
+	TO ("TONGA"),
+	TT ("TRINIDAD AND TOBAGO"),
+	TN ("TUNISIA"),
+	TR ("TURKEY"),
+	TM ("TURKMENISTAN"),
+	TC ("TURKS AND CAICOS ISLANDS"),
+	TV ("TUVALU"),
+	UG ("UGANDA"),
+	UA ("UKRAINE"),
+	AE ("UNITED ARAB EMIRATES"),
+	GB ("UNITED KINGDOM"),
+	US ("UNITED STATES"),
+	UM ("UNITED STATES MINOR OUTLYING ISLANDS"),
+	UY ("URUGUAY"),
+	UZ ("UZBEKISTAN"),
+	VU ("VANUATU"),
+	VE ("VENEZUELA"),
+	VN ("VIET NAM"),
+	VG ("VIRGIN ISLANDS, BRITISH"),
+	VI ("VIRGIN ISLANDS, U.S."),
+	WF ("WALLIS AND FUTUNA"),
+	EH ("WESTERN SAHARA"),
+	YE ("YEMEN"),
+	YU ("YUGOSLAVIA"),
+	ZM ("ZAMBIA"),
+	ZW ("ZIMBABWE");
+
+	private String nameCountry;
+	private String codeCountry;
+	
+	Country(String nameCountry) {
+		this.nameCountry=nameCountry;
+		this.codeCountry=this.name();
+	}
+	
+	public String getCode() {
+		return this.codeCountry;
+	}
+	
+	public String getName() {
+		return this.nameCountry;
+	}
+	
+	public static Country getCountryByCode(String code){
+		return Country.valueOf(code);
+	}
+	
+	public static Country getCountryByName(String name){
+		for (Country country : Country.values()) {
+			if(country.getName().equalsIgnoreCase(name)) {
+				return country;
+			}
+		}
+		return Country.BR;
+	}
+	
+}
Index: /contrib/psync/src/main/java/br/com/prognus/psync/util/TypeAddress.java
===================================================================
--- /contrib/psync/src/main/java/br/com/prognus/psync/util/TypeAddress.java	(revision 1545)
+++ /contrib/psync/src/main/java/br/com/prognus/psync/util/TypeAddress.java	(revision 1545)
@@ -0,0 +1,22 @@
+package br.com.prognus.psync.util;
+
+/**
+ * phpgw_cc_typeof_ct_addrs
+ *
+ */
+public enum TypeAddress {
+
+	RESIDENCIAL(1),
+	COMERCIAL(2);
+	
+	int id;
+	
+	TypeAddress(int num) {
+		this.id = num;
+	}
+	
+	public int getId() {
+		return id;
+	}
+	
+}
Index: /contrib/psync/src/main/java/com/funambol/server/security/LdapUserProvisioningOfficer.java
===================================================================
--- /contrib/psync/src/main/java/com/funambol/server/security/LdapUserProvisioningOfficer.java	(revision 1545)
+++ /contrib/psync/src/main/java/com/funambol/server/security/LdapUserProvisioningOfficer.java	(revision 1545)
@@ -0,0 +1,735 @@
+/*******************************************************************************
+ * Author: Emerson faria Nobre - emerson-faria.nobre@serpro.gov.br - january/09
+ * Organization: SERPRO - Servico Federal de Processamento de Dados
+ * Description: This source code is an extension of UserProvisioningOfficer.java
+ *              New capabilities implemented:
+ *              - Authenticate user in Ldap.
+ *              - Automatically Create/Update the MailServerAccount
+ *                (tables: fnbl_email_account, fnbl_email_enable_account,
+ *                 fnbl_email_push_registry)
+ * Changes:
+ * Author/Date/Description:
+ * Emerson Faria Nobre - june/2009 - Inserted parameters UserFieldName and
+ *              PwdFieldName because the LDAP Server of each Company that I
+ *              need to install Funambol use diferent names for this fields.
+ *              
+ * Changes:
+ * Autor/Description/Date:
+ * Lucas da Costa Silva / Sync with notes, photo, address, and the possibility
+ *                        to login with any uid from the overlay and it will use
+ *                        only the uid from the ldap not to add multiple principal
+ *                        to the same person that use different user in the same
+ *                        device. 
+ *                      / Sep to Oct-2009
+ *
+ *******************************************************************************
+ *
+ *
+ *
+ * Funambol is a mobile platform developed by Funambol, Inc.
+ * Copyright (C) 2006 - 2007 Funambol, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Affero General Public License version 3 as published by
+ * the Free Software Foundation with the addition of the following permission
+ * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
+ * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
+ * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program; if not, see http://www.gnu.org/licenses or write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
+ * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
+ *
+ * The interactive user interfaces in modified source and object code versions
+ * of this program must display Appropriate Legal Notices, as required under
+ * Section 5 of the GNU Affero General Public License version 3.
+ *
+ * In accordance with Section 7(b) of the GNU Affero General Public License
+ * version 3, these Appropriate Legal Notices must retain the display of the
+ * "Powered by Funambol" logo. If the display of the logo is not reasonably
+ * feasible for technical reasons, the Appropriate Legal Notices must display
+ * the words "Powered by Funambol".
+ */
+package com.funambol.server.security;
+
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import sun.util.logging.resources.logging;
+
+import com.funambol.email.console.dao.ConsoleDAO;
+import com.funambol.email.exception.DBAccessException;
+import com.funambol.email.exception.InboxListenerConfigException;
+import com.funambol.email.model.MailServer;
+import com.funambol.email.model.MailServerAccount;
+import com.funambol.email.util.Def;
+import com.funambol.framework.core.Authentication;
+import com.funambol.framework.core.Cred;
+import com.funambol.framework.filter.WhereClause;
+import com.funambol.framework.security.Sync4jPrincipal;
+import com.funambol.framework.server.Sync4jUser;
+import com.funambol.framework.server.store.NotFoundException;
+import com.funambol.framework.server.store.PersistentStoreException;
+import com.funambol.framework.tools.Base64;
+import com.funambol.framework.tools.beans.LazyInitBean;
+import com.funambol.pushlistener.service.registry.RegistryEntryStatus;
+import com.funambol.server.admin.AdminException;
+import com.funambol.server.admin.UserManager;
+import com.funambol.server.config.Configuration;
+
+
+/**
+ * This is an implementation of the <i>Officier</i> interface. It provides
+ * the user provisioning so if an user is not in the database he will be added.
+ * It requires basic authentication
+ *
+ * @version $Id: UserProvisioningOfficer.java,v 1.4 2008-06-24 12:50:06 piter_may Exp $
+ */
+public class LdapUserProvisioningOfficer
+        extends DBOfficer
+        implements LazyInitBean {
+	
+	private static final long serialVersionUID = 1978810349147209602L;
+	
+    Ldap objLdap;
+    MailServerAccount msa;
+    Boolean InsertMSA;
+    String ldapIP;
+    String ldapPort;
+    String ldapStartSearchPath;
+
+    boolean MsaEnablePush;
+    boolean MsaEnablePolling;
+    int MsaRefreshTime;
+    int MsaMaxEmailNumber;
+    int MsaMaxImapEmails;
+
+    // ------------------------------------------------------------ Constructors
+    public LdapUserProvisioningOfficer() {
+        super();
+        msa = new MailServerAccount();
+    }
+
+    // ---------------------------------------------------------- Public methods
+    public void init() {
+        super.init();
+    }
+
+    /**
+     * Authenticates a credential.
+     *
+     * @param credential the credential to be authenticated
+     *
+     * @return the Sync4jUser if the credential is autenticated, null otherwise
+     */
+    public Sync4jUser authenticateUser(Cred credential) {
+   	
+    	if (log.isTraceEnabled()) {
+    		StringBuffer sb = new StringBuffer("##########");
+    		sb.append(credential.getAuthentication().getPassword());
+    		sb.append("::");
+    		sb.append(credential.getAuthentication().getData());
+    		sb.append("::");
+    		sb.append(credential.getAuthentication().getUsername());
+    		sb.append("::");
+    		sb.append(credential.getUsername());
+    		sb.append("::");
+    		sb.append(credential.getData());
+    		sb.append("::");
+    		sb.append(credential.getFormat());
+    		sb.append("::");
+    		sb.append(credential.getType());
+    		sb.append("##############");
+            log.trace(sb.toString());
+        }
+    	
+    	
+        Configuration config = Configuration.getConfiguration();
+        ps = config.getStore();
+
+        userManager = (UserManager) config.getUserManager();
+
+        String type = credential.getType();
+
+        if ((Cred.AUTH_TYPE_BASIC).equals(type)) {
+            return authenticateBasicCredential(credential,"simple");
+            
+        } else if ((Cred.AUTH_TYPE_MD5).equals(type)) {
+        	return authenticateMD5Credential(credential);
+        	
+        }
+        return null;
+    }
+    
+    protected Sync4jUser getUser(String userName, String password) {
+    	
+    	try {
+			objLdap = new Ldap(this.getLdapIP(), this.getLdapPort(), userName,
+					"empty", this.getLdapStartSearchPath(), "nothing is so simple");
+			
+			return super.getUser(objLdap.getUid(),password);
+			
+		} catch (Exception e) {
+			return null;
+		}
+        
+    }
+
+    /**
+     * Gets the supported authentication type
+     *
+     * @return the basic authentication type
+     */
+    public String getClientAuth() {
+        return Cred.AUTH_TYPE_BASIC;
+    }
+
+    // ------------------------------------------------------- Protected Methods
+
+    // Insert/Update MailServerAccount (MSA)
+    protected void InsertUpdateMSA(String user, String pwd) {
+
+        if (log.isTraceEnabled()) {
+            log.trace("LdapUserProvisioningOfficer - I will create cdao object");
+        }
+        try {
+            ConsoleDAO cdao = new ConsoleDAO();
+
+            if (log.isTraceEnabled()) {
+                log.trace("LdapUserProvisioningOfficer - I will verify if it is insert or update");
+            }
+            msa = null;
+
+            if (log.isTraceEnabled()) {
+                log.trace("LdapUserProvisioningOfficer - before command cdao.getUser(user)");
+            }
+
+            List<MailServerAccount> accounts = cdao.getUserAccounts(user);
+            if(accounts!=null && accounts.size()>0) {
+            	for (MailServerAccount mailServerAccount : accounts) {
+					if(mailServerAccount.getMailServer().getDescription().equals("expresso")) {
+						msa = accounts.get(0);
+					}
+				}
+            }
+
+            if (log.isTraceEnabled()) {
+                log.trace("LdapUserProvisioningOfficer - after command cdao.getUser(user)");
+            }
+
+            if (msa == null) {
+                msa = new MailServerAccount();
+                this.InsertMSA = true;
+            } else {
+                this.InsertMSA = false;
+            }
+
+            if (log.isTraceEnabled()) {
+                log.trace("LdapUserProvisioningOfficer - after if (msa == null)");
+                log.trace("LdapUserProvisioningOfficer - msa.getUsername() = " + msa.getUsername());
+                log.trace("LdapUserProvisioningOfficer - It is insert: " + this.InsertMSA + "- username = " + msa.getUsername());
+            }
+            
+            if (!this.InsertMSA) {
+                if (log.isTraceEnabled()) {
+                    log.trace("LdapUserProvisioningOfficer - The key Id = " + msa.getId());
+                    log.trace("LdapUserProvisioningOfficer - The key UserName = " + msa.getUsername());
+                }
+            }
+            if (this.InsertMSA) {
+                if (log.isTraceEnabled()) {
+                    log.trace("LdapUserProvisioningOfficer - I will set setUserName" + user);
+                }
+                msa.setUsername(user);
+            }
+            msa.setMsLogin(user);
+            msa.setMsPassword(pwd);
+            msa.setMsAddress(objLdap.getmail());
+            msa.setPush(this.getMsaEnablePush());
+            msa.setMaxEmailNumber(this.getMsaMaxEmailNumber());
+            msa.setMaxImapEmail(this.getMsaMaxImapEmails());
+            msa.setPeriod(this.getMsaRefreshTime());
+            msa.setActive(this.getMsaEnablePolling());
+            msa.setTaskBeanFile(Def.DEFAULT_INBOX_LISTENER_BEAN_FILE);
+            msa.setLastUpdate(System.currentTimeMillis());
+            
+            if (this.InsertMSA) {
+            	msa.setStatus(RegistryEntryStatus.NEW);
+            } else {
+            	msa.setStatus(RegistryEntryStatus.UPDATED);
+            }
+
+            if (log.isTraceEnabled()) {
+            	log.trace("LdapUserProvisioningOfficer - I already set setMsLogin" + user);
+            	log.trace("LdapUserProvisioningOfficer - I will set setMsPassword");
+            	log.trace("LdapUserProvisioningOfficer - I will set setMsAddress = " + objLdap.getmail());
+            	log.trace("LdapUserProvisioningOfficer - I will set setPush = " + this.getMsaEnablePush());
+            	log.trace("LdapUserProvisioningOfficer - I will set setMaxEmailNumber = " + this.getMsaMaxEmailNumber());
+            	log.trace("LdapUserProvisioningOfficer - I will set setMaxImapEmail = " + this.getMsaMaxImapEmails());
+                log.trace("LdapUserProvisioningOfficer - I will set setPeriod = " + this.getMsaRefreshTime());
+                log.trace("LdapUserProvisioningOfficer - I will set setActive = " + this.getMsaEnablePolling());
+                log.trace("LdapUserProvisioningOfficer - I will set fnbl_email_push_registry");
+            }
+
+            String[] param = {"description"};
+            String[] value = {"expresso"};
+            String[] operator = {WhereClause.OPT_EQ};
+            
+            MailServer[] ms = cdao.getPubMailServers(new WhereClause(param[0], new String[]{value[0]}, operator[0], false));
+            
+            if (log.isTraceEnabled()) {
+                log.trace("LdapUserProvisioningOfficer - I found the MailServer expresso - ID = " + ms[0].getMailServerId());
+            }
+            msa.setMailServer(cdao.getPubMailServer(ms[0].getMailServerId()));
+
+            if (this.InsertMSA) {
+                int ret = cdao.insertUserAccount(msa);
+                if (log.isTraceEnabled()) {
+                	log.trace("LdapUserProvisioningOfficer - return of insertUser(msa): " + ret);
+                }
+            } else {
+            	int ret = cdao.updateUserAccount(msa);
+                if (log.isTraceEnabled()) {
+                    log.trace("LdapUserProvisioningOfficer - return of updateUser(msa): " + ret);
+                }
+            }
+        } catch (InboxListenerConfigException e) {
+            log.error("LdapUserProvisioningOfficer - Error creating DAO layer to Insert/Update Mail User: ", e);
+        } catch (DBAccessException e) {
+            log.error("LdapUserProvisioningOfficer - Error accessing Database to Insert/Update Mail User:  ", e);
+        }
+    }
+
+    /**
+     * Checks the given credential. If the user or the principal isn't found,
+     * they are created.
+     *
+     * @param credential the credential to check
+     *
+     * @return the Sync4jUser if the credential is autenticated, null otherwise
+     */
+    protected Sync4jUser authenticateBasicCredential(Cred credential, String authType) {
+        String username = null, password = null;
+
+        Authentication auth = credential.getAuthentication();
+        String deviceId = auth.getDeviceId();
+
+        String userpwd = new String(Base64.decode(auth.getData()));
+
+        int p = userpwd.indexOf(':');
+
+        if (p == -1) {
+            username = userpwd;
+            password = "";
+        } else {
+            username = (p > 0) ? userpwd.substring(0, p) : "";
+            password = (p == (userpwd.length() - 1)) ? "" : userpwd.substring(p + 1);
+        }
+
+        if (log.isTraceEnabled()) {
+            log.trace("User to check: " + username);
+        }
+
+        // LDAP Checkpoint
+        //
+        if (log.isTraceEnabled()) {
+            log.trace("LdapUserProvisioningOfficer - CheckPoint LDAP - getLdapIP: " + this.getLdapIP() + "  getLdapPort: " + this.getLdapPort());
+        }
+        objLdap = new Ldap(this.getLdapIP(), this.getLdapPort(), username, password, this.getLdapStartSearchPath(), authType);
+
+        // Try to authenticate in LDAP
+        if (objLdap.getreturnStatus() == false) {
+            if (log.isTraceEnabled()) {
+                log.trace("LDAP Authentication Failure: " + objLdap.geterrorMsg() + " - " + objLdap.geterrorStatus());
+            }
+            return null;
+        }
+        this.InsertUpdateMSA(objLdap.getUid(), password);
+
+        // Gets the user
+        Sync4jUser user = getUser(objLdap.getUid(), null);
+        if (user == null) {
+            try {
+                user = insertUser(objLdap.getUid(), password);
+                if (log.isTraceEnabled()) {
+                    log.trace(username+" to User '" + objLdap.getUid() + "' created");
+                }
+            } catch (Exception e) {
+                log.error("Error inserting a new user", e);
+                return null;
+            }
+        } else {
+            if (log.isTraceEnabled()) {
+            	log.trace(username+" to User '" + objLdap.getUid() + "' found");
+            }
+            // Check the roles
+            //
+            if (isASyncUser(user)) {
+                //
+                // User authenticated
+                if (log.isTraceEnabled()) {
+                    log.trace("User is a SyncUser");
+                }
+            } else {
+                // User not authenticated
+                //
+                if (log.isTraceEnabled()) {
+                    log.trace("The user is not a '" + ROLE_USER + "'");
+                }
+                return null;
+            }
+        }
+
+        //
+        // Verify that the principal for the specify deviceId and username exists
+        // Otherwise a new principal will be created
+        //
+        try {
+            handlePrincipal(objLdap.getUid(), deviceId);
+        } catch (PersistentStoreException e) {
+            log.error("Error handling the principal", e);
+            return null;
+        }
+        return user;
+    }
+
+    /**
+     * Insert a new user with the given username and password
+     *
+     * @param userName the username
+     * @param password the password
+     *
+     * @return the new user
+     *
+     * @throws AdminException in case of admin errors
+     * @throws PersistentStoreException if an error occurs
+     */
+    protected Sync4jUser insertUser(
+            String userName, String password)
+            throws AdminException, PersistentStoreException {
+
+        Sync4jUser user = new Sync4jUser();
+        user.setUsername(userName);
+        user.setPassword(password);
+        user.setFirstname(objLdap.getcn());
+        user.setRoles(new String[]{ROLE_USER});
+        user.setEmail(objLdap.getmail());
+
+        userManager.insertUser(user);
+        return user;
+    }
+
+    /**
+     * Returns the principal with the given username and deviceId.
+     * <code>null</code> if not found
+     * @param userName the username
+     * @param deviceId the device id
+     * @return the principal found or null.
+     * @throws PersistentStoreException if an error occurs
+     */
+    protected Sync4jPrincipal getPrincipal(String userName, String deviceId)
+            throws PersistentStoreException {
+
+        Sync4jPrincipal principal = null;
+
+        //
+        // Verify that exist the principal for the specify deviceId and username
+        //
+        principal = Sync4jPrincipal.createPrincipal(userName, deviceId);
+
+        try {
+            ps.read(principal);
+        } catch (NotFoundException ex) {
+            return null;
+        }
+
+        return principal;
+    }
+
+    /**
+     * Inserts a new principal with the given userName and deviceId
+     * @param userName the username
+     * @param deviceId the device id
+     * @return the principal created
+     * @throws PersistentStoreException if an error occurs creating the principal
+     */
+    protected Sync4jPrincipal insertPrincipal(String userName, String deviceId)
+            throws PersistentStoreException {
+
+        //
+        // We must create a new principal
+        //
+        Sync4jPrincipal principal = Sync4jPrincipal.createPrincipal(userName, deviceId);
+
+        ps.store(principal);
+
+        return principal;
+    }
+
+    /**
+     * Searchs if there is a principal with the given username and device id.
+     * if no principal is found, a new one is created.
+     * @param userName the user name
+     * @param deviceId the device id
+     * @return the found principal or the new one
+     */
+    protected Sync4jPrincipal handlePrincipal(String username, String deviceId)
+            throws PersistentStoreException {
+
+        Sync4jPrincipal principal = null;
+
+        //
+        // Verify if the principal for the specify deviceId and username exists
+        //
+        principal = getPrincipal(username, deviceId);
+
+        if (log.isTraceEnabled()) {
+            log.trace("Principal '" + username +
+                    "/" +
+                    deviceId + "' " +
+                    ((principal != null) ? "found" : "not found. A new principal will be created"));
+        }
+
+        if (principal == null) {
+            principal = insertPrincipal(username, deviceId);
+            if (log.isTraceEnabled()) {
+                log.trace("Principal '" + username +
+                        "/" +
+                        deviceId + "' created");
+            }
+
+        }
+
+        return principal;
+    }
+
+    public void setLdapIP(String pldapIP) {
+        this.ldapIP = pldapIP;
+    }
+
+    public String getLdapIP() {
+        return this.ldapIP;
+    }
+
+    public void setLdapPort(String pLdapPort) {
+        this.ldapPort = pLdapPort;
+    }
+
+    public String getLdapPort() {
+        return this.ldapPort;
+    }
+    
+    public void setLdapStartSearchPath(String pLdapStartSearchPath) {
+        this.ldapStartSearchPath = pLdapStartSearchPath;
+    }
+
+    public String getLdapStartSearchPath() {
+        return this.ldapStartSearchPath;
+    }
+
+    public void setMsaEnablePush(boolean pMsaEnablePush) {
+        this.MsaEnablePush = pMsaEnablePush;
+    }
+
+    public boolean getMsaEnablePush() {
+        return this.MsaEnablePush;
+    }
+
+    public void setMsaEnablePolling(boolean pMsaEnablePolling) {
+        this.MsaEnablePolling = pMsaEnablePolling;
+    }
+
+    public boolean getMsaEnablePolling() {
+        return this.MsaEnablePolling;
+    }
+
+    public void setMsaRefreshTime(int pMsaRefreshTime) {
+        this.MsaRefreshTime = pMsaRefreshTime;
+    }
+
+    public int getMsaRefreshTime() {
+        return this.MsaRefreshTime;
+    }
+
+    public void setMsaMaxEmailNumber(int pMsaMaxEmailNumber) {
+        this.MsaMaxEmailNumber = pMsaMaxEmailNumber;
+    }
+
+    public int getMsaMaxEmailNumber() {
+        return this.MsaMaxEmailNumber;
+    }
+
+    public void setMsaMaxImapEmails(int pMsaMaxImapEmails) {
+        this.MsaMaxImapEmails = pMsaMaxImapEmails;
+    }
+
+    public int getMsaMaxImapEmails() {
+        return this.MsaMaxImapEmails;
+    }
+}
+
+// Class to manage LDAP
+class Ldap {
+
+    private String ldapServer;
+    private String ldapPort;
+    private String ldapSearchPath;
+    private String UserID;
+    private String userDN;
+    private String pwd;
+    private String cn;
+    private String mail;
+    private String errorMsg;
+    private String errorStatus;
+    private boolean returnStatus;
+    private String uid;
+    private String authtype;
+
+    public Ldap(String ldapServer, String ldapPort, String UserID, String pwd, String ldapSearchPath, String authType) {
+        this.ldapServer = ldapServer;
+        this.ldapPort = ldapPort;
+        this.UserID = UserID;
+        this.pwd = pwd;
+        this.ldapSearchPath = ldapSearchPath;
+        this.authtype = authType;
+        this.returnStatus = processLDAP();
+    }
+
+    private boolean processLDAP() {
+        // Password cannot be null
+        if ((pwd.trim().length()) == 0) {
+            this.errorMsg = "Password Cannot be null";
+            this.errorStatus = "nullPwd";
+            return false;
+        }
+        
+        // Connecting as anonymous to get information about the user
+        Hashtable<String,String> env = new Hashtable<String,String>();
+        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+        env.put(Context.PROVIDER_URL, "ldap://" + this.ldapServer + ":" + this.ldapPort);
+        
+        try {
+            // Connecting
+            DirContext ctx = new InitialDirContext(env);
+            // Searching User
+            SearchControls ctls = new SearchControls();
+            ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+            ctls.setCountLimit(1);
+            ctls.setTimeLimit(10000); // max 10 seconds
+            String filter = "(uid=" + this.UserID + ")";
+            NamingEnumeration<SearchResult> answer = ctx.search(this.getLdapSearchPath(), filter, ctls);
+
+            if (answer.hasMore()) { // just the first one
+                SearchResult sr = (SearchResult) answer.next();
+                this.userDN = sr.getName() + "," + this.getLdapSearchPath();
+                try {
+                	
+                    // Getting User attributes
+                    this.cn = sr.getAttributes().get("cn").get(0).toString();
+                    this.mail = sr.getAttributes().get("mail").get(0).toString();
+                    this.uid = sr.getAttributes().get("uid").get(0).toString();
+                    
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    this.errorMsg = e.toString();
+                    this.errorStatus = "notGetAttributes";
+                    return false;
+                }
+            } else {
+                this.errorMsg = "User/Password not Found in LDAP";
+                this.errorStatus = "notFound";
+                return false;
+            }
+
+        } catch (NamingException e) {
+            e.printStackTrace();
+            this.errorMsg = e.toString();
+            this.errorStatus = "notConnect";
+            return false;
+        }
+
+        // only simple auth is suported in ldap
+        if("simple".equals(authtype)) {
+	        // Binding (Verifing Credentials)
+	        Hashtable<String,String> env2 = new Hashtable<String,String>();
+	        env2.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+	        env2.put(Context.PROVIDER_URL, "ldap://" + this.ldapServer + ":" + this.ldapPort);
+	        env2.put(Context.SECURITY_AUTHENTICATION, authtype);
+	        env2.put(Context.SECURITY_PRINCIPAL, this.userDN); // specify the user dn
+	        env2.put(Context.SECURITY_CREDENTIALS, this.pwd); // specify the password
+	
+	        try {
+	            DirContext ctx = new InitialDirContext(env2);
+	            ctx.close();
+	        } catch (NamingException e) {
+	            e.printStackTrace();
+	            this.errorMsg = e.toString();
+	            this.errorStatus = "notBind";
+	            return false;
+	        }
+        }
+        return true;
+    }
+
+    // Getters methods
+    public String getldapServer() {
+        return this.ldapServer;
+    }
+
+    public String getldapPort() {
+        return this.ldapPort;
+    }
+
+    public String getUserID() {
+        return this.UserID;
+    }
+
+    public String getuserDN() {
+        return this.userDN;
+    }
+
+    public String getcn() {
+        return this.cn;
+    }
+
+    public String getmail() {
+        return this.mail;
+    }
+
+    public String geterrorMsg() {
+        return this.errorMsg;
+    }
+
+    public String geterrorStatus() {
+        return this.errorStatus;
+    }
+
+    public boolean getreturnStatus() {
+        return this.returnStatus;
+    }
+
+    public String getLdapSearchPath() {
+        return this.ldapSearchPath;
+    }
+    
+    public String getUid() {
+    	return this.uid;
+    }
+}
Index: /contrib/psync/src/main/bean/psync/calendar/VEventSource.xml
===================================================================
--- /contrib/psync/src/main/bean/psync/calendar/VEventSource.xml	(revision 1009)
+++ /contrib/psync/src/main/bean/psync/calendar/VEventSource.xml	(revision 1545)
@@ -1,45 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<java version="1.4.0" class="java.beans.XMLDecoder">
- <object class="br.com.prognus.psync.engine.source.PIMCalendarSyncSource">
- <void property="name">
-   <string>calendario</string>
- </void>
- <void property="sourceURI">
-   <string>calendario</string>
- </void>
- <void property="entityType">
-   <class>com.funambol.common.pim.calendar.Event</class>
- </void>
- <void property="info">
-   <object class="com.funambol.framework.engine.source.SyncSourceInfo">
-     <void property="supportedTypes">
-     <array class="com.funambol.framework.engine.source.ContentType" length="2">
-      <void index="0">
-       <object class="com.funambol.framework.engine.source.ContentType">
-        <void property="type">
-         <string>text/x-vcalendar</string>
-        </void>
-        <void property="version">
-         <string>1.0</string>
-        </void>
-       </object>
-      </void>
-      <void index="1">
-       <object class="com.funambol.framework.engine.source.ContentType">
-        <void property="type">
-         <string>text/calendar</string>
-        </void>
-        <void property="version">
-         <string>2.0</string>
-        </void>
-       </object>
-      </void>
-     </array>
-     </void>  <!-- supportedTypes -->
-     <void property="preferred">
-       <int>0</int>
-     </void>
-   </object>
- </void> <!-- info -->
- </object>
-</java>
Index: /contrib/psync/src/main/bean/psync/contact/VCardSource.xml
===================================================================
--- /contrib/psync/src/main/bean/psync/contact/VCardSource.xml	(revision 1009)
+++ /contrib/psync/src/main/bean/psync/contact/VCardSource.xml	(revision 1545)
@@ -1,32 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<java version="1.4.0" class="java.beans.XMLDecoder">
- <object class="br.com.prognus.psync.engine.source.PIMContactSyncSource">
- <void property="name">
-   <string>catalogo</string>
- </void>
- <void property="sourceURI">
-   <string>catalogo</string>
- </void>
- <void property="info">
-   <object class="com.funambol.framework.engine.source.SyncSourceInfo">
-     <void property="supportedTypes">
-       <array class="com.funambol.framework.engine.source.ContentType" length="1">
-         <void index="0">
-           <object class="com.funambol.framework.engine.source.ContentType">
-             <void property="type">
-               <string>text/x-vcard</string>
-             </void>
-             <void property="version">
-               <string>2.1</string>
-             </void>
-           </object>
-         </void>
-       </array>
-     </void>  <!-- supportedTypes -->
-     <void property="preferred">
-       <int>0</int>
-     </void>
-   </object>
- </void> <!-- info -->
- </object>
-</java>
Index: /contrib/psync/src/main/config/psync/calendar/VEventSource.xml
===================================================================
--- /contrib/psync/src/main/config/psync/calendar/VEventSource.xml	(revision 1545)
+++ /contrib/psync/src/main/config/psync/calendar/VEventSource.xml	(revision 1545)
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<java version="1.4.0" class="java.beans.XMLDecoder">
+ <object class="br.com.prognus.psync.engine.source.PIMCalendarSyncSource">
+ <void property="name">
+   <string>calendario</string>
+ </void>
+ <void property="sourceURI">
+   <string>calendario</string>
+ </void>
+ <void property="entityType">
+   <class>com.funambol.common.pim.calendar.Event</class>
+ </void>
+ <void property="info">
+   <object class="com.funambol.framework.engine.source.SyncSourceInfo">
+     <void property="supportedTypes">
+     <array class="com.funambol.framework.engine.source.ContentType" length="2">
+      <void index="0">
+       <object class="com.funambol.framework.engine.source.ContentType">
+        <void property="type">
+         <string>text/x-vcalendar</string>
+        </void>
+        <void property="version">
+         <string>1.0</string>
+        </void>
+       </object>
+      </void>
+      <void index="1">
+       <object class="com.funambol.framework.engine.source.ContentType">
+        <void property="type">
+         <string>text/calendar</string>
+        </void>
+        <void property="version">
+         <string>2.0</string>
+        </void>
+       </object>
+      </void>
+     </array>
+     </void>  <!-- supportedTypes -->
+     <void property="preferred">
+       <int>0</int>
+     </void>
+   </object>
+ </void> <!-- info -->
+ </object>
+</java>
Index: /contrib/psync/src/main/config/psync/contact/VCardSource.xml
===================================================================
--- /contrib/psync/src/main/config/psync/contact/VCardSource.xml	(revision 1545)
+++ /contrib/psync/src/main/config/psync/contact/VCardSource.xml	(revision 1545)
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<java version="1.4.0" class="java.beans.XMLDecoder">
+ <object class="br.com.prognus.psync.engine.source.PIMContactSyncSource">
+ <void property="name">
+   <string>catalogo</string>
+ </void>
+ <void property="sourceURI">
+   <string>catalogo</string>
+ </void>
+ <void property="info">
+   <object class="com.funambol.framework.engine.source.SyncSourceInfo">
+     <void property="supportedTypes">
+       <array class="com.funambol.framework.engine.source.ContentType" length="1">
+         <void index="0">
+           <object class="com.funambol.framework.engine.source.ContentType">
+             <void property="type">
+               <string>text/x-vcard</string>
+             </void>
+             <void property="version">
+               <string>2.1</string>
+             </void>
+           </object>
+         </void>
+       </array>
+     </void>  <!-- supportedTypes -->
+     <void property="preferred">
+       <int>0</int>
+     </void>
+   </object>
+ </void> <!-- info -->
+ </object>
+</java>
Index: /contrib/psync/src/main/config/com/funambol/server/security/LdapUserProvisioningOfficer.xml
===================================================================
--- /contrib/psync/src/main/config/com/funambol/server/security/LdapUserProvisioningOfficer.xml	(revision 1545)
+++ /contrib/psync/src/main/config/com/funambol/server/security/LdapUserProvisioningOfficer.xml	(revision 1545)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<java version="1.4.0" class="java.beans.XMLDecoder">
+ <object class="com.funambol.server.security.LdapUserProvisioningOfficer">
+   <void property="serverAuth">
+   <string>none</string>
+  </void>
+  <void property="ldapPort">
+   <string>389</string>
+  </void>
+  <void property="ldapIP">
+     <string>mmldap</string>
+  </void>
+  <void property="ldapStartSearchPath">
+     <string>ou=Pessoas,ou=Usuarios,dc=previdencia,dc=gov,dc=br</string>
+  </void>
+    <void property="msaEnablePush">
+   <boolean>true</boolean>
+  </void>
+  <void property="msaEnablePolling">
+   <boolean>true</boolean>
+  </void>
+  <void property="msaRefreshTime">
+   <int>60000</int>
+  </void>
+  <void property="msaMaxEmailNumber">
+   <int>60</int>
+  </void>
+  <void property="msaMaxImapEmails">
+   <int>30</int>
+  </void>
+ </object>
+</java>
+
Index: /contrib/psync/pom.xml
===================================================================
--- /contrib/psync/pom.xml	(revision 1545)
+++ /contrib/psync/pom.xml	(revision 1545)
@@ -0,0 +1,221 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>funambol-connector</artifactId>
+    <groupId>modules</groupId>
+    <version>8.0</version>
+    <name>Funambol Connector</name>
+    <packaging>s4j</packaging>
+    
+    <!--
+        REPORTING
+    -->
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jxr-plugin</artifactId>
+                <configuration>
+                    <aggregate>true</aggregate>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-pmd-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <aggregate>true</aggregate>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+    
+    <!--
+        DEPENDENCIES
+    -->
+    <dependencies>
+        <dependency>
+            <artifactId>server-framework</artifactId>
+            <groupId>funambol</groupId>
+            <version>8.2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <artifactId>log4j</artifactId>
+            <groupId>log4j</groupId>
+            <version>1.2.14</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <artifactId>admin-framework</artifactId>
+            <groupId>funambol</groupId>
+            <version>8.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <artifactId>ds-server</artifactId>
+            <groupId>funambol</groupId>
+            <version>8.2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>funambol</groupId>
+            <artifactId>email-core</artifactId>
+            <version>8.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>funambol</groupId>
+            <artifactId>pim-framework</artifactId>
+            <version>8.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>funambol</groupId>
+            <artifactId>pim-listener</artifactId>
+            <version>8.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>funambol</groupId>
+            <artifactId>push-framework</artifactId>
+            <version>8.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>funambol</groupId>
+            <artifactId>foundation-core</artifactId>
+            <version>8.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>funambol</groupId>
+            <artifactId>ctp-server</artifactId>
+            <version>8.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>funambol</groupId>
+            <artifactId>ctp-client-driver</artifactId>
+            <version>8.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+    
+    <!--
+        Build plug-ins
+    -->
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <addClasspath>true</addClasspath>			
+                            <addExtensions/>
+                            <classpathPrefix/>
+                            
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+            
+            <plugin>
+                <!--
+                    The Funambol Maven Plugin enables the use of the following
+                    goals:
+                    - funambol:s4j -} to create a Funambol module archive
+                -->
+                <groupId>funambol</groupId>
+                <artifactId>funambol-plugin</artifactId>
+                <version>1.0.8</version>
+                <extensions>true</extensions>
+            </plugin>
+        </plugins>
+    </build>
+    
+    
+    <repositories>
+        <repository>
+            <id>funambol-snapshots</id>
+            <releases>
+                <enabled>false</enabled>
+                <updatePolicy>always</updatePolicy>
+                <checksumPolicy>warn</checksumPolicy>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+                <updatePolicy>never</updatePolicy>
+                <checksumPolicy>fail</checksumPolicy>
+            </snapshots>
+            <url>http://m2.funambol.org/repositories/snapshots</url>
+        </repository>
+        <repository>
+            <id>funambol-artifacts</id>
+            <releases>
+                <enabled>true</enabled>
+                <updatePolicy>always</updatePolicy>
+                <checksumPolicy>warn</checksumPolicy>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+                <updatePolicy>never</updatePolicy>
+                <checksumPolicy>fail</checksumPolicy>
+            </snapshots>
+            <url>http://m2.funambol.org/repositories/artifacts</url>
+        </repository>
+        <repository>
+            <id>central</id>
+            <releases>
+                <enabled>true</enabled>
+                <updatePolicy>always</updatePolicy>
+                <checksumPolicy>warn</checksumPolicy>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+                <updatePolicy>never</updatePolicy>
+                <checksumPolicy>fail</checksumPolicy>
+            </snapshots>
+            <url>http://repo1.maven.org/maven2/</url>
+        </repository>
+        <repository>
+            <id>jboss</id>
+            <releases>
+                <enabled>true</enabled>
+                <updatePolicy>always</updatePolicy>
+                <checksumPolicy>warn</checksumPolicy>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+                <updatePolicy>never</updatePolicy>
+                <checksumPolicy>fail</checksumPolicy>
+            </snapshots>
+            <url>http://repository.jboss.com/maven2/</url>
+        </repository>
+    </repositories>
+    <pluginRepositories>
+        <pluginRepository>
+            <id>funambol-pl-snapshots</id>
+            <url>http://m2.funambol.org/repositories/snapshots</url>
+        </pluginRepository>
+        <pluginRepository>
+            <id>funambol-pl-artifacts</id>
+            <url>http://m2.funambol.org/repositories/artifacts</url>
+        </pluginRepository>
+    </pluginRepositories>
+    
+    
+</project>
