/*******************************************************************************
 * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: Composent, Inc. - initial API and implementation
 ******************************************************************************/
package org.eclipse.ecf.internal.provider.xmpp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.sharedobject.ISharedObject;
import org.eclipse.ecf.core.sharedobject.ISharedObjectConfig;
import org.eclipse.ecf.core.sharedobject.ISharedObjectContext;
import org.eclipse.ecf.core.sharedobject.SharedObjectInitException;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectActivatedEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectMessageEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectMessageListener;
import org.eclipse.ecf.core.user.IUser;
import org.eclipse.ecf.core.user.User;
import org.eclipse.ecf.core.util.AsyncResult;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.core.util.Event;
import org.eclipse.ecf.core.util.IAsyncResult;
import org.eclipse.ecf.core.util.ICallable;
import org.eclipse.ecf.internal.provider.xmpp.events.IQEvent;
import org.eclipse.ecf.internal.provider.xmpp.events.MessageEvent;
import org.eclipse.ecf.internal.provider.xmpp.events.PresenceEvent;
import org.eclipse.ecf.internal.provider.xmpp.smack.ECFConnection;
import org.eclipse.ecf.presence.IPresence;
import org.eclipse.ecf.presence.IPresenceListener;
import org.eclipse.ecf.presence.IPresenceSender;
import org.eclipse.ecf.presence.im.IChatManager;
import org.eclipse.ecf.presence.im.ITypingMessage;
import org.eclipse.ecf.presence.im.TypingMessage;
import org.eclipse.ecf.presence.roster.AbstractRosterManager;
import org.eclipse.ecf.presence.roster.IRosterEntry;
import org.eclipse.ecf.presence.roster.IRosterGroup;
import org.eclipse.ecf.presence.roster.IRosterItem;
import org.eclipse.ecf.presence.roster.IRosterManager;
import org.eclipse.ecf.presence.roster.IRosterSubscriptionSender;
import org.eclipse.ecf.provider.xmpp.XMPPContainer;
import org.eclipse.ecf.provider.xmpp.identity.XMPPID;
import org.eclipse.ecf.provider.xmpp.identity.XMPPRoomID;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.packet.Presence.Mode;
import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smackx.packet.VCard;

public class XMPPContainerPresenceHelper implements ISharedObject {

	public static final String VCARD = "vcard";
	public static final String VCARD_EMAIL = VCARD + ".email";
	public static final String VCARD_EMAIL_HOME = VCARD_EMAIL + ".home";
	public static final String VCARD_EMAIL_WORK = VCARD_EMAIL + ".work";
	public static final String VCARD_NAME = VCARD + ".name";
	public static final String VCARD_NAME_FIRST = VCARD_NAME + ".first";
	public static final String VCARD_NAME_MIDDLE = VCARD_NAME + ".middle";
	public static final String VCARD_NAME_LAST = VCARD_NAME + ".last";
	public static final String VCARD_NAME_NICK = VCARD_NAME + ".nick";
	public static final String VCARD_PHONE = VCARD + ".phone";
	public static final String VCARD_PHONE_HOME = VCARD_PHONE + ".home";
	public static final String VCARD_PHONE_HOME_VOICE = VCARD_PHONE_HOME + ".voice";
	public static final String VCARD_PHONE_HOME_CELL = VCARD_PHONE_HOME + ".cell";
	public static final String VCARD_PHONE_WORK = VCARD_PHONE + ".work";
	public static final String VCARD_PHONE_WORK_VOICE = VCARD_PHONE_WORK + ".voice";
	public static final String VCARD_PHONE_WORK_CELL = VCARD_PHONE_WORK + ".cell";

	private ISharedObjectConfig config = null;

	private final List sharedObjectMessageListeners = new ArrayList();

	private XMPPContainer container = null;

	private XMPPChatManager chatManager = null;

	private final List presenceListeners = new ArrayList();

	public XMPPContainerPresenceHelper(XMPPContainer container) {
		this.container = container;
		chatManager = new XMPPChatManager(this);
		roster = new org.eclipse.ecf.presence.roster.Roster(container);
		rosterManager = new PresenceRosterManager(roster);
	}

	// ISharedObject implementation

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig)
	 */
	public void init(ISharedObjectConfig initData) throws SharedObjectInitException {
		this.config = initData;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event)
	 */
	public void handleEvent(Event event) {
		trace("handleEvent(" + event + ")");
		if (event instanceof ISharedObjectActivatedEvent) {
		} else if (event instanceof IQEvent) {
			handleIQEvent((IQEvent) event);
		} else if (event instanceof MessageEvent) {
			handleMessageEvent((MessageEvent) event);
		} else if (event instanceof PresenceEvent) {
			handlePresenceEvent((PresenceEvent) event);
		} else if (event instanceof ISharedObjectMessageEvent) {
			handleSharedObjectMessageEvent((ISharedObjectMessageEvent) event);
		} else {
			trace("unhandled event=" + event);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.core.ISharedObject#handleEvents(org.eclipse.ecf.core.util.Event[])
	 */
	public void handleEvents(Event[] events) {
		for (int i = 0; i < events.length; i++) {
			handleEvent(events[i]);
		}
	}

	public void disconnect() {
		rosterManager.disconnect();
		chatManager.disconnect();
		synchronized (sharedObjectMessageListeners) {
			sharedObjectMessageListeners.clear();
		}
		synchronized (presenceListeners) {
			presenceListeners.clear();
		}
		vcardCache.clear();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.core.ISharedObject#dispose(org.eclipse.ecf.core.identity.ID)
	 */
	public void dispose(ID containerID) {
		vcardCache.clear();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.core.ISharedObject#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class adapter) {
		if (adapter == null)
			return null;
		if (adapter.isInstance(this))
			return this;
		final IAdapterManager adapterManager = XmppPlugin.getDefault().getAdapterManager();
		return (adapterManager == null) ? null : adapterManager.loadAdapter(this, adapter.getName());
	}

	// end ISharedObject implementation

	protected org.eclipse.ecf.presence.roster.Roster roster;

	protected PresenceRosterManager rosterManager;

	class PresenceRosterManager extends AbstractRosterManager {

		public PresenceRosterManager(org.eclipse.ecf.presence.roster.Roster roster) {
			super(roster);
		}

		public void notifySubscriptionListener(ID fromID, IPresence presence) {
			this.fireSubscriptionListener(fromID, presence.getType());
		}

		public void notifyRosterUpdate(IRosterItem changedItem) {
			fireRosterUpdate(changedItem);
		}

		public void notifyRosterAdd(IRosterEntry entry) {
			fireRosterAdd(entry);
		}

		public void notifyRosterRemove(IRosterEntry entry) {
			fireRosterRemove(entry);
		}

		public void disconnect() {
			getRoster().getItems().clear();
			super.disconnect();
			fireRosterUpdate(roster);
		}

		public void setUser(IUser user) {
			final org.eclipse.ecf.presence.roster.Roster roster = (org.eclipse.ecf.presence.roster.Roster) getRoster();
			roster.setUser(user);
			notifyRosterUpdate(roster);
		}

		org.eclipse.ecf.presence.IPresenceSender rosterPresenceSender = new org.eclipse.ecf.presence.IPresenceSender() {
			public void sendPresenceUpdate(ID toID, org.eclipse.ecf.presence.IPresence presence) throws ECFException {
				try {
					getConnectionOrThrowIfNull().sendPresenceUpdate(toID, createPresence(presence));
				} catch (final IOException e) {
					traceAndThrowECFException("sendPresenceUpdate", e);
				}
			}

		};

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ecf.presence.roster.AbstractRosterManager#getPresenceSender()
		 */
		public IPresenceSender getPresenceSender() {
			return rosterPresenceSender;
		}

		org.eclipse.ecf.presence.roster.IRosterSubscriptionSender rosterSubscriptionSender = new org.eclipse.ecf.presence.roster.IRosterSubscriptionSender() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.ecf.presence.roster.IRosterSubscriptionSender#sendRosterAdd(java.lang.String,
			 *      java.lang.String, java.lang.String[])
			 */
			public void sendRosterAdd(String user, String name, String[] groups) throws ECFException {
				try {
					getConnectionOrThrowIfNull().sendRosterAdd(user, name, groups);
				} catch (final Exception e) {
					traceAndThrowECFException("sendRosterAdd", e);
				}
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.ecf.presence.roster.IRosterSubscriptionSender#sendRosterRemove(org.eclipse.ecf.core.identity.ID)
			 */
			public void sendRosterRemove(ID userID) throws ECFException {
				try {
					if (!(userID instanceof XMPPID))
						throw new ECFException("invalid userID");
					final XMPPID xmppID = (XMPPID) userID;
					getConnectionOrThrowIfNull().sendRosterRemove(xmppID.getUsernameAtHost());
				} catch (final Exception e) {
					traceAndThrowECFException("sendRosterRemove", e);
				}
			}

		};

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ecf.presence.roster.AbstractRosterManager#getRosterSubscriptionSender()
		 */
		public IRosterSubscriptionSender getRosterSubscriptionSender() {
			return rosterSubscriptionSender;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ecf.presence.roster.IRosterManager#addPresenceListener(org.eclipse.ecf.presence.roster.IPresenceListener)
		 */
		public void addPresenceListener(IPresenceListener listener) {
			synchronized (presenceListeners) {
				presenceListeners.add(listener);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ecf.presence.roster.IRosterManager#removePresenceListener(org.eclipse.ecf.presence.roster.IPresenceListener)
		 */
		public void removePresenceListener(IPresenceListener listener) {
			synchronized (presenceListeners) {
				presenceListeners.add(listener);
			}
		}

	}

	/**
	 * @return IRosterManager roster manager. Will not return <code>null</code>.
	 */
	public IRosterManager getRosterManager() {
		return rosterManager;
	}

	/**
	 * @param user
	 *            set the user for this presence helper.
	 */
	public void setUser(IUser user) {
		rosterManager.setUser(user);
	}

	protected void addSharedObjectMessageListener(ISharedObjectMessageListener listener) {
		synchronized (sharedObjectMessageListeners) {
			sharedObjectMessageListeners.add(listener);
		}
	}

	protected void sendTypingMessage(ID toID, boolean isTyping, String body) throws IOException {
		getContext().sendMessage(toID, new TypingMessage(rosterManager.getRoster().getUser().getID(), isTyping, body));
	}

	protected void handleSharedObjectMessageEvent(ISharedObjectMessageEvent event) {
		List toNotify = null;
		synchronized (sharedObjectMessageListeners) {
			toNotify = new ArrayList(sharedObjectMessageListeners);
		}
		for (final Iterator i = toNotify.iterator(); i.hasNext();) {
			final ISharedObjectMessageListener l = (ISharedObjectMessageListener) i.next();
			l.handleSharedObjectMessage(event);
		}

		final Object data = event.getData();
		if (data instanceof ITypingMessage) {
			final ITypingMessage tmess = (ITypingMessage) data;
			chatManager.fireTypingMessage(tmess.getFromID(), tmess);
		}

	}

	protected void removeSharedObjectMessageListener(ISharedObjectMessageListener listener) {
		synchronized (sharedObjectMessageListeners) {
			sharedObjectMessageListeners.remove(listener);
		}
	}

	private void addToRoster(IRosterItem[] items) {
		for (int i = 0; i < items.length; i++) {
			roster.addItem(items[i]);
		}
		rosterManager.notifyRosterUpdate(roster);
	}

	protected ISharedObjectContext getContext() {
		return config.getContext();
	}

	protected String getUserNameFromXMPPAddress(XMPPID userID) {
		return userID.getUsername();
	}

	protected IRosterEntry createRosterEntry(RosterEntry entry) {
		return createRosterEntry(createIDFromName(entry.getUser()), entry.getName(), entry.getGroups());
	}

	protected IRosterEntry createRosterEntry(RosterPacket.Item entry) {
		return createRosterEntry(createIDFromName(entry.getUser()), entry.getName(), entry.getGroupNames());
	}

	protected void handleIQEvent(IQEvent evt) {
		final IQ iq = evt.getIQ();
		if (iq instanceof RosterPacket) {
			// Roster packet...report to UI
			final RosterPacket rosterPacket = (RosterPacket) iq;
			if (rosterPacket.getType() == IQ.Type.SET || rosterPacket.getType() == IQ.Type.RESULT) {
				for (final Iterator i = rosterPacket.getRosterItems(); i.hasNext();) {
					final RosterPacket.Item item = (RosterPacket.Item) i.next();
					final RosterPacket.ItemType itemType = item.getItemType();
					boolean remove = false;
					final IRosterItem items[] = createRosterEntries(item);
					final IRosterEntry entry = createRosterEntry(item);
					if (itemType == RosterPacket.ItemType.NONE || itemType == RosterPacket.ItemType.REMOVE) {
						removeItemFromRoster(roster.getItems(), createIDFromName(item.getUser()));
						remove = true;
					} else {
						remove = false;
						addToRoster(items);
					}
					// In both cases fire set roster entry
					fireSetRosterEntry(remove, entry);
				}
			}
		} else {
			trace("Received non rosterpacket IQ message");
		}
	}

	protected void fireSetRosterEntry(boolean remove, IRosterEntry entry) {
		if (remove)
			rosterManager.notifyRosterRemove(entry);
		else
			rosterManager.notifyRosterAdd(entry);
	}

	private void removeItemFromRoster(Collection rosterItems, XMPPID itemIDToRemove) {
		boolean removed = false;
		synchronized (rosterItems) {
			for (final Iterator i = rosterItems.iterator(); i.hasNext();) {
				final IRosterItem item = (IRosterItem) i.next();
				if (item instanceof org.eclipse.ecf.presence.roster.RosterGroup) {
					final org.eclipse.ecf.presence.roster.RosterGroup group = (org.eclipse.ecf.presence.roster.RosterGroup) item;
					removed = removeItemFromRosterGroup(group, itemIDToRemove);
					// If group is empty, remove it too
					if (group.getEntries().size() == 0)
						i.remove();
				} else if (item instanceof org.eclipse.ecf.presence.roster.RosterEntry) {
					if (((org.eclipse.ecf.presence.roster.RosterEntry) item).getUser().getID().equals(itemIDToRemove)) {
						i.remove();
						removed = true;
					}
				}
			}
		}
		if (removed)
			rosterManager.notifyRosterUpdate(roster);

	}

	private boolean removeItemFromRosterGroup(org.eclipse.ecf.presence.roster.RosterGroup group, XMPPID itemIDToRemove) {
		final Collection groupEntries = group.getEntries();
		synchronized (groupEntries) {
			for (final Iterator i = group.getEntries().iterator(); i.hasNext();) {
				final org.eclipse.ecf.presence.roster.RosterEntry entry = (org.eclipse.ecf.presence.roster.RosterEntry) i.next();
				if (entry.getUser().getID().equals(itemIDToRemove)) {
					i.remove();
					return true;
				}
			}
		}
		return false;
	}

	protected void handleMessageEvent(MessageEvent evt) {
		Message msg = evt.getMessage();
		final String from = msg.getFrom();
		final String body = msg.getBody();
		final String subject = msg.getSubject();
		final ID fromID = createIDFromName(from);
		final ID threadID = createThreadID(msg.getThread());
		msg = filterMessageType(msg);
		if (msg != null) {
			if (msg.getExtension("composing", //$NON-NLS-1$
					"http://jabber.org/protocol/chatstates") != null) { //$NON-NLS-1$
				chatManager.fireTypingMessage(fromID, new TypingMessage(fromID, true, body));
			} else if (msg.getExtension("paused", //$NON-NLS-1$
					"http://jabber.org/protocol/chatstates") != null) { //$NON-NLS-1$
				chatManager.fireTypingMessage(fromID, new TypingMessage(fromID, false, body));
			} else {
				final Iterator xhtmlbodies = evt.getXHTMLBodies();
				if (xhtmlbodies != null) {
					final List xhtmlbodylist = new ArrayList();
					for (; xhtmlbodies.hasNext();)
						xhtmlbodylist.add(xhtmlbodies.next());
					chatManager.fireXHTMLChatMessage(fromID, threadID, msg.getType(), subject, body, ECFConnection.getPropertiesFromPacket(msg), xhtmlbodylist);
				} else if (body != null) {
					chatManager.fireChatMessage(fromID, threadID, msg.getType(), subject, body, ECFConnection.getPropertiesFromPacket(msg));
				}
			}
		}
	}

	protected void handlePresenceEvent(PresenceEvent evt) {
		final Presence xmppPresence = evt.getPresence();
		final String from = xmppPresence.getFrom();
		final IPresence newPresence = createIPresence(xmppPresence);
		final XMPPID fromID = createIDFromName(from);
		if (newPresence.getType().equals(IPresence.Type.SUBSCRIBE) || newPresence.getType().equals(IPresence.Type.UNSUBSCRIBE) || newPresence.getType().equals(IPresence.Type.SUBSCRIBED) || newPresence.getType().equals(IPresence.Type.UNSUBSCRIBED)) {
			rosterManager.notifySubscriptionListener(fromID, newPresence);
		} else {
			updatePresence(fromID, newPresence);
			firePresenceListeners(fromID, newPresence);
		}
	}

	private void firePresenceListeners(ID fromID, IPresence presence) {
		List toNotify = null;
		synchronized (presenceListeners) {
			toNotify = new ArrayList(presenceListeners);
		}
		for (final Iterator i = toNotify.iterator(); i.hasNext();) {
			final IPresenceListener l = (IPresenceListener) i.next();
			l.handlePresence(fromID, presence);
		}
	}

	private void updatePresence(XMPPID fromID, IPresence newPresence) {
		final Collection rosterItems = roster.getItems();
		synchronized (rosterItems) {
			for (final Iterator i = roster.getItems().iterator(); i.hasNext();) {
				final IRosterItem item = (IRosterItem) i.next();
				if (item instanceof IRosterGroup) {
					updatePresenceInGroup((IRosterGroup) item, fromID, newPresence);
				} else if (item instanceof org.eclipse.ecf.presence.roster.RosterEntry) {
					updatePresenceForMatchingEntry((org.eclipse.ecf.presence.roster.RosterEntry) item, fromID, newPresence);
				}
			}
		}
	}

	private void updatePresenceForMatchingEntry(org.eclipse.ecf.presence.roster.RosterEntry entry, XMPPID fromID, IPresence newPresence) {
		final IUser user = entry.getUser();
		if (fromID.equals(user.getID())) {
			entry.setPresence(newPresence);
			rosterManager.notifyRosterUpdate(entry);
		}
	}

	private void updatePresenceInGroup(IRosterGroup group, XMPPID fromID, IPresence newPresence) {
		final Collection groupEntries = group.getEntries();
		synchronized (groupEntries) {
			for (final Iterator i = group.getEntries().iterator(); i.hasNext();) {
				updatePresenceForMatchingEntry((org.eclipse.ecf.presence.roster.RosterEntry) i.next(), fromID, newPresence);
			}
		}
	}

	protected void handleRoster(Roster roster) {
		for (final Iterator i = roster.getEntries(); i.hasNext();) {
			final IRosterItem[] items = createRosterEntries((RosterEntry) i.next());
			for (int j = 0; j < items.length; j++) {
				this.roster.addItem(items[j]);
			}
		}
		rosterManager.notifyRosterUpdate(this.roster);
	}

	protected XMPPID createIDFromName(String uname) {
		try {
			if (uname.indexOf('@') == -1) {
				return new XMPPID(container.getConnectNamespace(), "admin" + "@" + uname);
			}
			return new XMPPID(container.getConnectNamespace(), uname);
		} catch (final Exception e) {
			traceStack("Exception in createIDFromName", e);
			return null;
		}
	}

	protected ID createThreadID(String thread) {
		try {
			if (thread == null || thread.equals(""))
				return null;
			return IDFactory.getDefault().createStringID(thread);
		} catch (final Exception e) {
			traceStack("Exception in createThreadID", e);
			return null;
		}

	}

	private final Map vcardCache = new WeakHashMap();

	private VCard getFromCache(String id) {
		if (id == null)
			return null;
		return (VCard) vcardCache.get(id);
	}

	private void addToCache(String id, VCard card) {
		vcardCache.put(id, card);
	}

	private VCard getVCardForPresence(Presence xmppPresence) {
		VCard result = null;
		if (xmppPresence.getExtension("x", "vcard-temp:x:update") != null) {
			final String from = xmppPresence.getFrom();
			result = getFromCache(from);
			if (result == null && from != null) {
				result = new VCard();
				try {
					result.load(container.getXMPPConnection(), from);
					addToCache(from, result);
				} catch (final XMPPException e) {
					traceStack("vcard loading exception", e);
				}
			}
		}
		return result;
	}

	private Map addVCardProperties(VCard vcard, Map props) {
		if (vcard == null)
			return props;
		final String emailHome = vcard.getEmailHome();
		if (emailHome != null && !emailHome.equals(""))
			props.put(VCARD_EMAIL_HOME, emailHome);
		final String emailWork = vcard.getEmailWork();
		if (emailWork != null && !emailWork.equals(""))
			props.put(VCARD_EMAIL_WORK, emailWork);
		final String firstName = vcard.getFirstName();
		if (firstName != null && !firstName.equals(""))
			props.put(VCARD_NAME_FIRST, firstName);
		final String middleName = vcard.getMiddleName();
		if (middleName != null && !middleName.equals(""))
			props.put(VCARD_NAME_MIDDLE, middleName);
		final String lastName = vcard.getLastName();
		if (lastName != null && !lastName.equals(""))
			props.put(VCARD_NAME_LAST, lastName);
		final String nickName = vcard.getNickName();
		if (nickName != null && !nickName.equals(""))
			props.put(VCARD_NAME_NICK, nickName);
		final String phoneHomeVoice = vcard.getPhoneHome("VOICE");
		if (phoneHomeVoice != null && !phoneHomeVoice.equals(""))
			props.put(VCARD_PHONE_HOME_VOICE, phoneHomeVoice);
		final String phoneHomeCell = vcard.getPhoneHome("CELL");
		if (phoneHomeCell != null && !phoneHomeCell.equals(""))
			props.put(VCARD_PHONE_HOME_CELL, phoneHomeCell);
		final String phoneWorkVoice = vcard.getPhoneWork("VOICE");
		if (phoneWorkVoice != null && !phoneWorkVoice.equals(""))
			props.put(VCARD_PHONE_WORK_VOICE, phoneWorkVoice);
		final String phoneWorkCell = vcard.getPhoneWork("CELL");
		if (phoneWorkCell != null && !phoneWorkCell.equals(""))
			props.put(VCARD_PHONE_WORK_CELL, phoneWorkCell);
		return props;
	}

	class XMPPPresence extends org.eclipse.ecf.presence.Presence {

		private static final long serialVersionUID = 7843634971520771692L;

		IAsyncResult asyncResult = null;
		String fromID = null;

		XMPPPresence(String fromID, Presence xmppPresence, IAsyncResult future) {
			super(createIPresenceType(xmppPresence), xmppPresence.getStatus(), createIPresenceMode(xmppPresence), ECFConnection.getPropertiesFromPacket(xmppPresence), null);
			this.fromID = fromID;
		}

		private void fillFromVCard() {
			VCard card = getFromCache(fromID);
			if (card == null && asyncResult != null) {
				try {
					card = (VCard) asyncResult.get();
					asyncResult = null;
				} catch (final Exception e) {
				}
			}
			if (card != null) {
				addToCache(fromID, card);
				final byte[] bytes = card.getAvatar();
				this.pictureData = (bytes == null) ? new byte[0] : bytes;
				this.properties = addVCardProperties(card, this.properties);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ecf.presence.Presence#getPictureData()
		 */
		public byte[] getPictureData() {
			fillFromVCard();
			return this.pictureData;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ecf.presence.Presence#getProperties()
		 */
		public Map getProperties() {
			fillFromVCard();
			return this.properties;
		}
	}

	protected IPresence createIPresence(final Presence xmppPresence) {
		final AsyncResult asyncResult = new AsyncResult();
		final Thread t = new Thread(asyncResult.setter(new ICallable() {
			public Object call() throws Throwable {
				return getVCardForPresence(xmppPresence);
			}
		}));
		t.start();
		return new XMPPPresence(xmppPresence.getFrom(), xmppPresence, asyncResult);
	}

	protected Presence createPresence(IPresence ipresence) {
		final Presence newPresence = new Presence(createPresenceType(ipresence), ipresence.getStatus(), 0, createPresenceMode(ipresence));
		ECFConnection.setPropertiesInPacket(newPresence, ipresence.getProperties());
		return newPresence;
	}

	protected IPresence.Mode createIPresenceMode(Presence xmppPresence) {
		if (xmppPresence == null)
			return IPresence.Mode.AVAILABLE;
		final Mode mode = xmppPresence.getMode();
		if (mode == Presence.Mode.AVAILABLE) {
			return IPresence.Mode.AVAILABLE;
		} else if (mode == Presence.Mode.AWAY) {
			return IPresence.Mode.AWAY;
		} else if (mode == Presence.Mode.CHAT) {
			return IPresence.Mode.CHAT;
		} else if (mode == Presence.Mode.DO_NOT_DISTURB) {
			return IPresence.Mode.DND;
		} else if (mode == Presence.Mode.EXTENDED_AWAY) {
			return IPresence.Mode.EXTENDED_AWAY;
		} else if (mode == Presence.Mode.INVISIBLE) {
			return IPresence.Mode.INVISIBLE;
		}
		return IPresence.Mode.AVAILABLE;
	}

	protected Presence.Mode createPresenceMode(IPresence ipresence) {
		if (ipresence == null)
			return Presence.Mode.AVAILABLE;
		final IPresence.Mode mode = ipresence.getMode();
		if (mode == IPresence.Mode.AVAILABLE) {
			return Presence.Mode.AVAILABLE;
		} else if (mode == IPresence.Mode.AWAY) {
			return Presence.Mode.AWAY;
		} else if (mode == IPresence.Mode.CHAT) {
			return Presence.Mode.CHAT;
		} else if (mode == IPresence.Mode.DND) {
			return Presence.Mode.DO_NOT_DISTURB;
		} else if (mode == IPresence.Mode.EXTENDED_AWAY) {
			return Presence.Mode.EXTENDED_AWAY;
		} else if (mode == IPresence.Mode.INVISIBLE) {
			return Presence.Mode.INVISIBLE;
		}
		return Presence.Mode.AVAILABLE;
	}

	protected IPresence.Type createIPresenceType(Presence xmppPresence) {
		if (xmppPresence == null)
			return IPresence.Type.AVAILABLE;
		final Type type = xmppPresence.getType();
		if (type == Presence.Type.AVAILABLE) {
			return IPresence.Type.AVAILABLE;
		} else if (type == Presence.Type.ERROR) {
			return IPresence.Type.ERROR;
		} else if (type == Presence.Type.SUBSCRIBE) {
			return IPresence.Type.SUBSCRIBE;
		} else if (type == Presence.Type.SUBSCRIBED) {
			return IPresence.Type.SUBSCRIBED;
		} else if (type == Presence.Type.UNSUBSCRIBE) {
			return IPresence.Type.UNSUBSCRIBE;
		} else if (type == Presence.Type.UNSUBSCRIBED) {
			return IPresence.Type.UNSUBSCRIBED;
		} else if (type == Presence.Type.UNAVAILABLE) {
			return IPresence.Type.UNAVAILABLE;
		}
		return IPresence.Type.AVAILABLE;
	}

	protected Presence.Type createPresenceType(IPresence ipresence) {
		if (ipresence == null)
			return Presence.Type.AVAILABLE;
		final IPresence.Type type = ipresence.getType();
		if (type == IPresence.Type.AVAILABLE) {
			return Presence.Type.AVAILABLE;
		} else if (type == IPresence.Type.ERROR) {
			return Presence.Type.ERROR;
		} else if (type == IPresence.Type.SUBSCRIBE) {
			return Presence.Type.SUBSCRIBE;
		} else if (type == IPresence.Type.SUBSCRIBED) {
			return Presence.Type.SUBSCRIBED;
		} else if (type == IPresence.Type.UNSUBSCRIBE) {
			return Presence.Type.UNSUBSCRIBE;
		} else if (type == IPresence.Type.UNSUBSCRIBED) {
			return Presence.Type.UNSUBSCRIBED;
		} else if (type == IPresence.Type.UNAVAILABLE) {
			return Presence.Type.UNAVAILABLE;
		}
		return Presence.Type.AVAILABLE;
	}

	protected IRosterItem[] createRosterEntries(RosterEntry entry) {
		return createRosterEntries(entry.getGroups(), roster, new User(createIDFromName(entry.getUser()), entry.getName()));
	}

	private IRosterItem[] createRosterEntries(Iterator grps, IRosterItem parent, IUser user) {
		final List result = new ArrayList();
		if (grps.hasNext()) {
			for (; grps.hasNext();) {
				final Object o = grps.next();
				// Get group name
				final String groupName = (o instanceof String) ? (String) o : ((RosterGroup) o).getName();

				if (groupName == null || groupName.equals("")) {
					createRosterEntries(parent, user, result);
					continue;
				}
				// See if group is already in roster
				org.eclipse.ecf.presence.roster.RosterGroup rosterGroup = findRosterGroup(parent, groupName);
				// Set flag if not
				final boolean groupFound = rosterGroup != null;
				if (!groupFound)
					rosterGroup = new org.eclipse.ecf.presence.roster.RosterGroup(parent, groupName);

				if (findRosterEntry(rosterGroup, user) == null) {
					// Now create new roster entry
					new org.eclipse.ecf.presence.roster.RosterEntry(rosterGroup, user, new org.eclipse.ecf.presence.Presence(IPresence.Type.UNAVAILABLE, IPresence.Type.UNAVAILABLE.toString(), IPresence.Mode.AWAY));
				}
				// Only add localGrp if not already in list
				if (!groupFound)
					result.add(rosterGroup);
			}
		} else
			createRosterEntries(parent, user, result);
		return (IRosterItem[]) result.toArray(new IRosterItem[] {});
	}

	protected IRosterEntry createRosterEntry(ID userID, String name, Iterator grps) {
		final List groups = new ArrayList();
		for (; grps.hasNext();) {
			final Object o = grps.next();
			final String groupName = (o instanceof String) ? (String) o : ((RosterGroup) o).getName();
			final IRosterGroup localGrp = new org.eclipse.ecf.presence.roster.RosterGroup(roster, groupName);
			groups.add(localGrp);
		}
		final IUser user = new User(userID, name);
		IRosterEntry newEntry = null;
		if (groups.size() == 0)
			return new org.eclipse.ecf.presence.roster.RosterEntry(roster, user, null);
		else
			for (int i = 0; i < groups.size(); i++) {
				final IRosterGroup grp = (IRosterGroup) groups.get(i);
				if (i == 0)
					newEntry = new org.eclipse.ecf.presence.roster.RosterEntry(grp, user, null);
				else {
					grp.getEntries().add(newEntry);
					newEntry.getGroups().add(grp);
				}
			}
		return newEntry;
	}

	private void createRosterEntries(IRosterItem parent, IUser user, List result) {
		final org.eclipse.ecf.presence.roster.RosterEntry oldEntry = findRosterEntry((org.eclipse.ecf.presence.roster.RosterGroup) null, user);
		if (oldEntry == null) {
			final org.eclipse.ecf.presence.roster.RosterEntry newEntry = new org.eclipse.ecf.presence.roster.RosterEntry(parent, user, new org.eclipse.ecf.presence.Presence(IPresence.Type.UNAVAILABLE, IPresence.Type.UNAVAILABLE.toString(), IPresence.Mode.AWAY));
			result.add(newEntry);
		}
	}

	private org.eclipse.ecf.presence.roster.RosterEntry findRosterEntry(org.eclipse.ecf.presence.roster.RosterGroup rosterGroup, IUser user) {
		if (rosterGroup != null)
			return findRosterEntry(rosterGroup.getEntries(), user);
		else
			return findRosterEntry(roster.getItems(), user);
	}

	private org.eclipse.ecf.presence.roster.RosterEntry findRosterEntry(Collection entries, IUser user) {
		for (final Iterator i = entries.iterator(); i.hasNext();) {
			final Object o = i.next();
			if (o instanceof org.eclipse.ecf.presence.roster.RosterEntry) {
				final org.eclipse.ecf.presence.roster.RosterEntry entry = (org.eclipse.ecf.presence.roster.RosterEntry) o;
				if (entry.getUser().getID().equals(user.getID()))
					return entry;
			}
		}
		return null;
	}

	protected IRosterItem[] createRosterEntries(RosterPacket.Item entry) {
		final XMPPID id = createIDFromName(entry.getUser());
		String name = entry.getName();
		if (name == null)
			name = id.getUsername();
		return createRosterEntries(entry.getGroupNames(), roster, new User(id, name));
	}

	protected org.eclipse.ecf.presence.roster.RosterGroup findRosterGroup(Object parent, String grp) {
		final Collection items = roster.getItems();
		for (final Iterator i = items.iterator(); i.hasNext();) {
			final IRosterItem item = (IRosterItem) i.next();
			if (item.getName().equals(grp))
				return (org.eclipse.ecf.presence.roster.RosterGroup) item;
		}
		return null;
	}

	// utility methods

	protected ECFConnection getConnectionOrThrowIfNull() throws IOException {
		final ECFConnection conn = container.getECFConnection();
		if (conn == null)
			throw new IOException("Not connected");
		return conn;
	}

	protected void traceAndThrowECFException(String msg, Throwable t) throws ECFException {
		throw new ECFException(msg, t);
	}

	protected void trace(String msg) {

	}

	protected void traceStack(String msg, Throwable e) {

	}

	protected ID createRoomIDFromName(String from) {
		try {
			final ECFConnection ecfConnection = getConnectionOrThrowIfNull();
			return new XMPPRoomID(container.getConnectNamespace(), ecfConnection.getXMPPConnection(), from);
		} catch (final Exception e) {
			traceStack("Exception in createRoomIDFromName", e);
			return null;
		}
	}

	protected ID createUserIDFromName(String name) {
		ID result = null;
		try {
			result = new XMPPID(container.getConnectNamespace(), name);
			return result;
		} catch (final Exception e) {
			traceStack("Exception in createIDFromName", e);
			return null;
		}
	}

	protected Message.Type[] ALLOWED_MESSAGES = {Message.Type.CHAT, Message.Type.ERROR, Message.Type.HEADLINE, Message.Type.NORMAL};

	protected Message filterMessageType(Message msg) {
		for (int i = 0; i < ALLOWED_MESSAGES.length; i++) {
			if (ALLOWED_MESSAGES[i].equals(msg.getType())) {
				return msg;
			}
		}
		return null;
	}

	/**
	 * @return chat manager.
	 */
	public IChatManager getChatManager() {
		return chatManager;
	}

}
