/****************************************************************************
 * Copyright (c) 2004, 2007 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.presence.ui;

import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.List;
import org.eclipse.core.runtime.*;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.internal.presence.ui.Activator;
import org.eclipse.ecf.internal.presence.ui.Messages;
import org.eclipse.ecf.internal.presence.ui.dialogs.*;
import org.eclipse.ecf.presence.*;
import org.eclipse.ecf.presence.chatroom.IChatRoomInfo;
import org.eclipse.ecf.presence.im.*;
import org.eclipse.ecf.presence.roster.*;
import org.eclipse.ecf.presence.service.IPresenceService;
import org.eclipse.ecf.presence.ui.chatroom.*;
import org.eclipse.ecf.presence.ui.dnd.IRosterViewerDropTarget;
import org.eclipse.ecf.ui.SharedImages;
import org.eclipse.ecf.ui.dialogs.ContainerConnectErrorDialog;
import org.eclipse.jface.action.*;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.forms.FormColors;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.widgets.*;
import org.eclipse.ui.part.*;

/**
 * View class for displaying multiple rosters in a tree viewer. This view part
 * implements {@link IMultiRosterViewPart} and provides the ability to display
 * multiple rosters in a single tree viewer. This class may be subclassed as
 * desired to add or customize behavior.
 */
public class MultiRosterView extends ViewPart implements IMultiRosterViewPart {

	public static final String VIEW_ID = "org.eclipse.ecf.presence.ui.MultiRosterView"; //$NON-NLS-1$

	protected static final int DEFAULT_EXPAND_LEVEL = 3;

	private static final String ROSTER_VIEWER_DROP_TARGET_EPOINT = Activator.PLUGIN_ID + "." //$NON-NLS-1$
			+ "rosterViewerDropTarget"; //$NON-NLS-1$

	private static final String ROSTER_VIEWER_DROP_TARGET_CLASS_ATTR = "class"; //$NON-NLS-1$

	private static final Transfer[] dndTransferTypes = {EditorInputTransfer.getInstance(), FileTransfer.getInstance(), HTMLTransfer.getInstance(), LocalSelectionTransfer.getTransfer(), PluginTransfer.getInstance(), RTFTransfer.getInstance(), TextTransfer.getInstance()};

	private static final int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;

	protected TreeViewer treeViewer;

	protected List rosterAccounts = new ArrayList();

	private Hashtable chatRooms = new Hashtable();

	private IMenuManager setStatusMenu;

	private IAction imAction;

	private IAction removeAction;

	private IAction setAvailableAction;

	private IAction setAwayAction;

	private IAction setDNDAction;

	private IAction setInvisibleAction;

	private IAction setOfflineAction;

	private IAction showOfflineAction;

	private IAction showEmptyGroupsAction;

	private IAction addContactAction;

	private IAction searchContactAction;

	private IAction openChatRoomAction;

	private IAction openAccountChatRoomAction;

	private IAction changePasswordAction;

	private IAction disconnectAllAccountsAction;

	private IAction disconnectAccountAction;

	// private IRosterSubscriptionListener subscriptionListener;

	private IPresenceListener presenceListener;

	private RosterViewerDropAdapter dropAdapter;

	private PageBook pageBook;

	private Label helpMessageLabel;

	private ViewerFilter hideOfflineFilter = new ViewerFilter() {
		public boolean select(Viewer viewer, Object parentElement, Object element) {
			if (element instanceof IRosterEntry) {
				IRosterEntry entry = (IRosterEntry) element;
				IPresence presence = entry.getPresence();
				if (presence != null)
					return (presence.getType() != IPresence.Type.UNAVAILABLE);
				return true;
			}
			return true;
		}
	};

	private ViewerFilter hideEmptyGroupsFilter = new ViewerFilter() {
		public boolean select(Viewer viewer, Object parentElement, Object element) {
			if (element instanceof IRosterGroup) {
				return !((IRosterGroup) element).getEntries().isEmpty();
			}
			return true;
		}
	};

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createPartControl(Composite parent) {
		pageBook = new PageBook(parent, SWT.NONE);

		createHelpMessage(pageBook);
		setupTreeViewer(pageBook);

		if (rosterAccounts.size() == 0)
			pageBook.showPage(helpMessageLabel);
	}

	private void createHelpMessage(Composite parent) {
		if (!parent.isDisposed()) {
			helpMessageLabel = new Label(parent, SWT.TOP + SWT.LEFT + SWT.WRAP);
			helpMessageLabel.setText(Messages.MultiRosterView_HELP_MESSAGE);
		}
	}

	protected void setupTreeViewer(Composite parent) {
		treeViewer = new TreeViewer(parent, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL);
		getSite().setSelectionProvider(treeViewer);
		presenceListener = new PresenceListener();
		treeViewer.setContentProvider(new MultiRosterContentProvider());
		treeViewer.setLabelProvider(new MultiRosterLabelProvider());
		treeViewer.addFilter(hideOfflineFilter);
		treeViewer.addFilter(hideEmptyGroupsFilter);
		treeViewer.setInput(rosterAccounts);
		treeViewer.addOpenListener(new IOpenListener() {
			public void open(OpenEvent e) {
				message((IStructuredSelection) e.getSelection());
			}
		});

		ToolTip toolTip = new ViewerToolTip(treeViewer.getControl());
		toolTip.setHideOnMouseDown(false);
		toolTip.setPopupDelay(200);
		toolTip.setShift(new Point(5, 5));

		makeActions();
		hookContextMenu();
		contributeToActionBars();
		hookDropSupport();
		retrieveServices();
		treeViewer.expandToLevel(DEFAULT_EXPAND_LEVEL);

	}

	class RosterViewerDropAdapter extends ViewerDropAdapter {
		private List rosterDropTargets = new ArrayList();
		private List rosterPerformDrop = new ArrayList();

		public RosterViewerDropAdapter(TreeViewer treeViewer, IRosterViewerDropTarget dropTarget) {
			super(treeViewer);
			Assert.isNotNull(dropTarget);
			setFeedbackEnabled(false);
			addRosterDropTarget(dropTarget);
		}

		public boolean addRosterDropTarget(IRosterViewerDropTarget rosterDropTarget) {
			return rosterDropTargets.add(rosterDropTarget);
		}

		public boolean performDrop(Object data) {
			boolean result = false;
			for (Iterator i = rosterPerformDrop.iterator(); i.hasNext();) {
				IRosterViewerDropTarget rdt = (IRosterViewerDropTarget) i.next();
				if (rdt.performDrop(data))
					result = true;
			}
			rosterPerformDrop.clear();
			return result;
		}

		public void dispose() {
			rosterDropTargets.clear();
			rosterPerformDrop.clear();
		}

		public boolean validateDrop(Object target, int operation, TransferData transferType) {
			if (target instanceof IRosterItem) {
				rosterPerformDrop.clear();
				boolean result = false;
				for (Iterator i = rosterDropTargets.iterator(); i.hasNext();) {
					IRosterViewerDropTarget rdt = (IRosterViewerDropTarget) i.next();
					if (rdt.validateDrop((IRosterItem) target, operation, transferType)) {
						result = true;
						rosterPerformDrop.add(rdt);
					}
				}
				return result;
			}
			return false;
		}
	}

	private void hookDropSupport() {
		IExtensionRegistry reg = Activator.getDefault().getExtensionRegistry();
		if (reg != null) {
			IExtensionPoint extensionPoint = reg.getExtensionPoint(ROSTER_VIEWER_DROP_TARGET_EPOINT);
			if (extensionPoint == null) {
				return;
			}
			IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements();

			for (int i = 0; i < configurationElements.length; i++) {
				try {
					IRosterViewerDropTarget rosterDropTarget = (IRosterViewerDropTarget) configurationElements[i].createExecutableExtension(ROSTER_VIEWER_DROP_TARGET_CLASS_ATTR);
					if (dropAdapter == null) {
						dropAdapter = new RosterViewerDropAdapter(treeViewer, rosterDropTarget);
						treeViewer.addDropSupport(dndOperations, dndTransferTypes, dropAdapter);
					} else
						dropAdapter.addRosterDropTarget(rosterDropTarget);
				} catch (CoreException e) {
					// Log
					Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.MultiRosterView_ROSTER_VIEW_EXT_POINT_ERROR_MESSAGE, e));
				}
			}
		}
	}

	private void retrieveServices() {
		IPresenceService[] services = Activator.getDefault().getPresenceServices();
		for (int i = 0; i < services.length; i++) {
			IContainer container = (IContainer) services[i].getAdapter(IContainer.class);
			if (container != null && container.getConnectedID() != null) {
				addContainer(container);
			}
		}
	}

	protected IChatRoomCommandListener createChatRoomCommandListener() {
		return null;
	}

	protected IChatRoomViewCloseListener createChatRoomViewCloseListener(final ID connectedID) {
		return new IChatRoomViewCloseListener() {
			public void chatRoomViewClosing() {
				chatRooms.remove(connectedID);
			}
		};
	}

	/**
	 * For the given container, join the chat room specified by roomInfo. NOTE:
	 * this is to be considered provisional 'Gunner' API and may not be
	 * available in subsequent versions of this class.
	 * 
	 * @param container
	 *            the IContainer instance that exposes the chat room. Must not
	 *            be <code>null</code>. Also must be the same container
	 *            associated with one of the accounts managed by this
	 *            MultiRosterView.
	 * @param roomInfo
	 *            chat room information that will be used to join. Must not be
	 *            <code>null</code>.
	 * @param password
	 *            a password associated with chat room access. May be
	 *            <code>null</code>.
	 * @throws ECFException
	 *             if the given container is not connected, or if the given
	 *             container is not managed by this MultiRosterView, or if
	 *             {@link ChatRoomManagerView} cannot be initialized.
	 */
	protected void joinChatRoom(IContainer container, IChatRoomInfo roomInfo, String password) throws ECFException {
		Assert.isNotNull(container);
		Assert.isNotNull(roomInfo);
		// Check to make sure given container is connected.
		ID connectedID = container.getConnectedID();
		if (connectedID == null)
			throw new ECFException(Messages.MultiRosterView_EXCEPTION_JOIN_ROOM_NOT_CONNECTED);
		// Check to make sure that the given container is one that we have in
		// our accounts set
		if (findAccountForContainer(container) == null)
			throw new ECFException(Messages.MultiRosterView_EXCEPTION_JOIN_ROOM_INVALID_ACCOUNT);

		IWorkbenchWindow ww = getViewSite().getPage().getWorkbenchWindow();
		IWorkbenchPage wp = ww.getActivePage();
		// Get existing roomView...if it's there
		RoomWithAView roomView = (RoomWithAView) chatRooms.get(connectedID);
		if (roomView != null) {
			// We've already connected to this room, so just show it.
			ChatRoomManagerView chatroommanagerview = roomView.getView();
			wp.activate(chatroommanagerview);
			chatroommanagerview.joinRoom(roomInfo, password);
			return;
		}
		try {
			IViewReference ref = wp.findViewReference(org.eclipse.ecf.presence.ui.chatroom.ChatRoomManagerView.VIEW_ID, connectedID.getName());
			// Open view for given connectedID (secondaryID)
			final ChatRoomManagerView chatroommanagerview = (ChatRoomManagerView) ((ref == null) ? wp.showView(org.eclipse.ecf.presence.ui.chatroom.ChatRoomManagerView.VIEW_ID, connectedID.getName(), IWorkbenchPage.VIEW_ACTIVATE) : ref.getView(true));
			// initialize new view
			chatroommanagerview.initializeWithoutManager(ChatRoomManagerView.getUsernameFromID(connectedID), ChatRoomManagerView.getHostnameFromID(connectedID), createChatRoomCommandListener(), createChatRoomViewCloseListener(connectedID));
			// join room
			chatroommanagerview.joinRoom(roomInfo, password);

			roomView = new RoomWithAView(chatroommanagerview, connectedID);
			chatRooms.put(roomView.getID(), roomView);
		} catch (Exception e1) {
			throw new ECFException(e1);
		}

	}

	private void selectAndJoinChatRoomForAccounts(MultiRosterAccount[] accounts) {
		// Create chat room selection dialog with managers, open
		ChatRoomSelectionDialog dialog = new ChatRoomSelectionDialog(getViewSite().getShell(), accounts);
		dialog.open();
		// If selection cancelled then simply return
		if (dialog.getReturnCode() != Window.OK)
			return;
		// Get selected room, selected manager, and selected IChatRoomInfo
		IChatRoomInfo selectedInfo = dialog.getSelectedRoom().getRoomInfo();
		MultiRosterAccount account = dialog.getSelectedRoom().getAccount();
		// Now get the secondary ID from the selected room id
		final IContainer container = account.getContainer();
		final ID connectedID = container.getConnectedID();
		if (connectedID == null) {
			MessageDialog.openError(getViewSite().getShell(), Messages.MultiRosterView_NO_IDENTIFIER_FOR_ROOM_TITLE, NLS.bind(Messages.MultiRosterView_NO_IDENTIFIER_FOR_ROOM_MESSAGE, selectedInfo.getRoomID()));
			return;
		}

		try {
			joinChatRoom(container, selectedInfo, null);
		} catch (ECFException e) {
			Throwable e1 = e.getStatus().getException();
			Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.MultiRosterView_EXCEPTION_LOG_JOIN_ROOM, e1));
			ContainerConnectErrorDialog ed = new ContainerConnectErrorDialog(getViewSite().getShell(), selectedInfo.getRoomID().getName(), e1);
			ed.open();
		}
	}

	private void makeActions() {
		imAction = new Action() {
			public void run() {
				message((IStructuredSelection) treeViewer.getSelection());
			}
		};
		imAction.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.IMG_MESSAGE));

		removeAction = new Action() {
			public void run() {
				IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection();
				remove((IRosterEntry) iss.getFirstElement());
			}
		};
		removeAction.setText(Messages.MultiRosterView_Remove);
		removeAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));

		setAvailableAction = new Action(Messages.MultiRosterView_SetAvailable, IAction.AS_RADIO_BUTTON) {
			public void run() {
				if (isChecked()) {
					sendPresence(IPresence.Mode.AVAILABLE);
				}
			}
		};

		setAwayAction = new Action(Messages.MultiRosterView_SetAway, IAction.AS_RADIO_BUTTON) {
			public void run() {
				if (isChecked()) {
					sendPresence(IPresence.Mode.AWAY);
				}
			}
		};

		setDNDAction = new Action(Messages.MultiRosterView_SetDoNotDisturb, IAction.AS_RADIO_BUTTON) {
			public void run() {
				if (isChecked()) {
					sendPresence(IPresence.Mode.DND);
				}
			}
		};

		setInvisibleAction = new Action(Messages.MultiRosterView_SetInvisible, IAction.AS_RADIO_BUTTON) {
			public void run() {
				if (isChecked()) {
					sendPresence(IPresence.Mode.INVISIBLE);
				}
			}
		};

		setOfflineAction = new Action(Messages.MultiRosterView_SetOffline, IAction.AS_RADIO_BUTTON) {
			public void run() {
				if (isChecked()) {
					for (int i = 0; i < rosterAccounts.size(); i++) {
						MultiRosterAccount account = (MultiRosterAccount) rosterAccounts.get(i);
						treeViewer.remove(account);
					}
					rosterAccounts.clear();
					refreshTreeViewer(null, false);
					setStatusMenu.setVisible(false);
					getViewSite().getActionBars().getMenuManager().update(false);
				}
			}
		};
		setOfflineAction.setChecked(true);

		showOfflineAction = new Action(Messages.MultiRosterView_ShowOffline, IAction.AS_CHECK_BOX) {
			public void run() {
				if (isChecked()) {
					treeViewer.removeFilter(hideOfflineFilter);
				} else {
					treeViewer.addFilter(hideOfflineFilter);
				}
			}
		};

		showEmptyGroupsAction = new Action(Messages.MultiRosterView_ShowEmptyGroups, IAction.AS_CHECK_BOX) {
			public void run() {
				if (isChecked()) {
					treeViewer.removeFilter(hideEmptyGroupsFilter);
				} else {
					treeViewer.addFilter(hideEmptyGroupsFilter);
				}
			}
		};

		addContactAction = new Action(Messages.MultiRosterView_AddContact, SharedImages.getImageDescriptor(SharedImages.IMG_ADD_BUDDY)) {
			public void run() {
				AddContactDialog dialog = new AddContactDialog(treeViewer.getControl().getShell());
				IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection();
				IRoster roster = (IRoster) iss.getFirstElement();
				MultiRosterAccount account = findAccountForUser(roster.getUser().getID());

				dialog.setInput(rosterAccounts);
				dialog.setDefaultRosterAccount(account);
				if (Window.OK == dialog.open()) {
					IPresenceContainerAdapter ipca = dialog.getSelection();
					IRosterSubscriptionSender sender = ipca.getRosterManager().getRosterSubscriptionSender();
					try {
						sender.sendRosterAdd(dialog.getAccountID(), dialog.getAlias(), null);
					} catch (ECFException e) {
						Activator.getDefault().getLog().log(e.getStatus());
					}
				}
			}
		};

		searchContactAction = new Action() {
			public void run() {
				IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection();
				IRoster roster = (IRoster) iss.getFirstElement();
				MultiRosterAccount account = findAccountForUser(roster.getUser().getID());
				if (account != null) {
					SearchContactDialog dialog = new SearchContactDialog(treeViewer.getControl().getShell(), account);
					dialog.open();
				}
			}
		};

		searchContactAction.setText(Messages.MultiRosterView_SearchContact);

		openChatRoomAction = new Action() {
			public void run() {
				selectAndJoinChatRoomForAccounts((MultiRosterAccount[]) rosterAccounts.toArray(new MultiRosterAccount[] {}));
			}
		};
		openChatRoomAction.setText(Messages.MultiRosterView_ENTER_CHATROOM_ACTION_TEXT);
		openChatRoomAction.setToolTipText(Messages.MultiRosterView_ENTER_CHATROOM_TOOLTIP_TEXT);
		openChatRoomAction.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.IMG_ADD_CHAT));
		openChatRoomAction.setEnabled(true);

		openAccountChatRoomAction = new Action() {
			public void run() {
				IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection();
				IRoster roster = (IRoster) iss.getFirstElement();
				MultiRosterAccount account = findAccountForUser(roster.getUser().getID());
				if (account != null)
					selectAndJoinChatRoomForAccounts(new MultiRosterAccount[] {account});
			}
		};
		openAccountChatRoomAction.setText(Messages.MultiRosterView_SHOW_CHAT_ROOMS_FOR_ACCOUNT_ACTION_TEXT);
		openAccountChatRoomAction.setEnabled(true);
		openAccountChatRoomAction.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.IMG_ADD_CHAT));

		changePasswordAction = new Action() {
			public void run() {
				IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection();
				IRoster roster = (IRoster) iss.getFirstElement();
				MultiRosterAccount account = findAccountForUser(roster.getUser().getID());
				if (account != null)
					changePasswordForAccount(account);
			}
		};

		changePasswordAction.setText(Messages.MultiRosterView_CHANGE_PASSWORD_MENU);
		changePasswordAction.setEnabled(true);

		disconnectAllAccountsAction = new Action() {
			public void run() {
				if (MessageDialog.openQuestion(getViewSite().getShell(), Messages.MultiRosterView_DISCONNECT_QUESTION_TITLE, Messages.MultiRosterView_DISCONNECT_ALL_ACCOUNTS_QUESTION_MESSAGE)) {
					disconnectAccounts((MultiRosterAccount[]) rosterAccounts.toArray(new MultiRosterAccount[] {}));
				}
			}
		};
		disconnectAllAccountsAction.setText(Messages.MultiRosterView_DISCONNECT_ALL_ACCOUNTS_ACTION_TEXT);
		disconnectAllAccountsAction.setEnabled(true);
		disconnectAllAccountsAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));

		disconnectAccountAction = new Action() {
			public void run() {
				IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection();
				IRoster roster = (IRoster) iss.getFirstElement();
				MultiRosterAccount account = findAccountForUser(roster.getUser().getID());
				ID connectedID = account.getContainer().getConnectedID();
				if (account != null && connectedID != null && MessageDialog.openQuestion(getViewSite().getShell(), Messages.MultiRosterView_DISCONNECT_QUESTION_TITLE, NLS.bind(Messages.MultiRosterView_DISCONNECT_ACCOUNT_QUESTION_MESSAGE, connectedID.getName()))) {
					disconnectAccounts(new MultiRosterAccount[] {account});
				}
			}
		};
		disconnectAccountAction.setText(Messages.MultiRosterView_DISCONNECT_ACCOUNT_ACTION_TEXT);
		disconnectAccountAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));

	}

	protected void changePasswordForAccount(MultiRosterAccount account) {
		ChangePasswordDialog cpd = new ChangePasswordDialog(getViewSite().getShell(), account.getRoster().getUser().getID().getName());
		cpd.open();
		if (cpd.getResult() == Window.OK) {
			IPresenceContainerAdapter pc = account.getPresenceContainerAdapter();
			IAccountManager am = pc.getAccountManager();
			try {
				if (am.changePassword(cpd.getNewPassword()))
					MessageDialog.openInformation(getViewSite().getShell(), Messages.MultiRosterView_PASSWORD_CHANGED_DIALOG_TITLE, Messages.MultiRosterView_PASSWORD_CHANGED_MESSAGE);
				else
					MessageDialog.openInformation(getViewSite().getShell(), Messages.MultiRosterView_PASSWORD_NOT_CHANGED_TITLE, Messages.MultiRosterView_PASSWORD_NOT_CHANGED_MESSAGE);
			} catch (ECFException e) {
				MessageDialog.openError(getViewSite().getShell(), Messages.MultiRosterView_PASSWORD_NOT_CHANGED_TITLE, Messages.MultiRosterView_PASSWORD_CHANGE_ERROR);
				Activator.getDefault().getLog().log(e.getStatus());
			}
		}
	}

	protected void disconnectAccounts(MultiRosterAccount[] accounts) {
		for (int i = 0; i < accounts.length; i++)
			accounts[i].getContainer().disconnect();
	}

	private MultiRosterAccount findAccountForUser(ID userID) {
		for (Iterator i = rosterAccounts.iterator(); i.hasNext();) {
			MultiRosterAccount account = (MultiRosterAccount) i.next();
			if (account.getRoster().getUser().getID().equals(userID))
				return account;
		}
		return null;
	}

	private void sendPresence(IPresence.Mode mode) {
		try {
			for (Iterator i = rosterAccounts.iterator(); i.hasNext();) {
				MultiRosterAccount account = (MultiRosterAccount) i.next();
				account.getRosterManager().getPresenceSender().sendPresenceUpdate(null, new Presence(IPresence.Type.AVAILABLE, null, mode));
			}
		} catch (ECFException e) {
			Activator.getDefault().getLog().log(e.getStatus());
		}
	}

	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager();
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				fillContextMenu(manager);
			}
		});
		Menu menu = menuMgr.createContextMenu(treeViewer.getControl());
		treeViewer.getControl().setMenu(menu);
		getSite().registerContextMenu(menuMgr, treeViewer);
	}

	private void fillContextMenu(IMenuManager manager) {
		IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection();
		Object element = iss.getFirstElement();
		if (element instanceof IRosterEntry) {
			IRosterEntry entry = (IRosterEntry) element;
			manager.add(imAction);
			imAction.setText(Messages.MultiRosterView_SendIM);
			// if the person is not online, we'll disable the action
			imAction.setEnabled(entry.getPresence().getType() == IPresence.Type.AVAILABLE);
			manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
			manager.add(removeAction);
		} else if (element instanceof IRoster) {
			IAccountManager accountManager = ((IRoster) element).getPresenceContainerAdapter().getAccountManager();
			if (accountManager != null) {
				manager.add(changePasswordAction);
				manager.add(new Separator());
			}
			manager.add(addContactAction);
			manager.add(new Separator());
			//add if the provider supports user search
			if (((IRoster) element).getPresenceContainerAdapter().getUserSearchManager().isEnabled()) {
				manager.add(searchContactAction);
				manager.add(new Separator());
			}
			manager.add(openAccountChatRoomAction);
			manager.add(new Separator());
			manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
			manager.add(disconnectAccountAction);
		} else {
			manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		}
	}

	private IRosterEntry find(Collection items, ID userID) {
		for (Iterator it = items.iterator(); it.hasNext();) {
			Object item = it.next();
			if (item instanceof IRosterGroup) {
				IRosterEntry entry = find(((IRosterGroup) item).getEntries(), userID);
				if (entry != null) {
					return entry;
				}
			} else if (userID.equals(((IRosterEntry) item).getUser().getID())) {
				return (IRosterEntry) item;
			}
		}
		return null;
	}

	private MultiRosterAccount findAccountForContainer(IContainer container) {
		if (container == null)
			return null;
		synchronized (rosterAccounts) {
			for (Iterator i = rosterAccounts.iterator(); i.hasNext();) {
				MultiRosterAccount account = (MultiRosterAccount) i.next();
				if (account.getContainer().getID().equals(container.getID()))
					return account;
			}
		}
		return null;
	}

	private void remove(IRosterEntry entry) {
		try {
			IRoster roster = entry.getRoster();
			if (roster != null) {
				roster.getPresenceContainerAdapter().getRosterManager().getRosterSubscriptionSender().sendRosterRemove(entry.getUser().getID());
			}
		} catch (ECFException e) {
			MessageDialog.openError(getViewSite().getShell(), Messages.MultiRosterView_ERROR_CONTACT_REMOVE_TITLE, NLS.bind(Messages.MultiRosterView_ERROR_CONTACT_REMOVED_MESSAGE, entry.getUser().getID().getName()));
			Activator.getDefault().getLog().log(e.getStatus());
		}
	}

	private void message(IStructuredSelection iss) {
		Object element = iss.getFirstElement();
		if (!(element instanceof IRosterEntry)) {
			return;
		}
		IRosterEntry entry = (IRosterEntry) element;
		IRoster roster = entry.getRoster();
		if (roster != null) {
			IChatManager manager = roster.getPresenceContainerAdapter().getChatManager();
			IChatMessageSender icms = manager.getChatMessageSender();
			ITypingMessageSender itms = manager.getTypingMessageSender();
			try {
				MessagesView view = (MessagesView) getSite().getWorkbenchWindow().getActivePage().showView(MessagesView.VIEW_ID);
				view.selectTab(icms, itms, roster.getUser().getID(), entry.getUser().getID());
			} catch (PartInitException e) {
				e.printStackTrace();
			}
		}
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalPullDown(bars.getMenuManager());
	}

	private void setLocalPullDownEnabled(boolean enabled) {
		setAvailableAction.setEnabled(enabled);
		setAwayAction.setEnabled(enabled);
		setDNDAction.setEnabled(enabled);
		setInvisibleAction.setEnabled(enabled);
		setOfflineAction.setEnabled(enabled);
		showOfflineAction.setEnabled(enabled);
		showEmptyGroupsAction.setEnabled(enabled);
		addContactAction.setEnabled(enabled);
		searchContactAction.setEnabled(enabled);
		openChatRoomAction.setEnabled(enabled);
		disconnectAllAccountsAction.setEnabled(enabled);
	}

	private void fillLocalPullDown(IMenuManager manager) {
		setStatusMenu = new MenuManager(Messages.MultiRosterView_SetStatusAs, null);
		setStatusMenu.add(setAvailableAction);
		setStatusMenu.add(setAwayAction);
		setStatusMenu.add(setDNDAction);
		setStatusMenu.add(setInvisibleAction);
		setStatusMenu.add(setOfflineAction);
		manager.add(setStatusMenu);
		manager.add(new Separator());

		manager.add(showOfflineAction);

		manager.add(showEmptyGroupsAction);

		manager.add(new Separator());
		manager.add(addContactAction);
		manager.add(new Separator());
		manager.add(searchContactAction);
		manager.add(new Separator());
		manager.add(openChatRoomAction);
		manager.add(new Separator());
		manager.add(disconnectAllAccountsAction);
		setLocalPullDownEnabled(false);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
	 */
	public void dispose() {
		if (dropAdapter != null) {
			dropAdapter.dispose();
			dropAdapter = null;
		}
		treeViewer = null;
		for (Iterator i = rosterAccounts.iterator(); i.hasNext();) {
			MultiRosterAccount account = (MultiRosterAccount) i.next();
			account.getRosterManager().removePresenceListener(presenceListener);
			// detach listeners
			account.dispose();
		}
		rosterAccounts.clear();
		super.dispose();
	}

	protected boolean containerPresent(IContainer container) {
		// Then check if this new account is already in rosterAccounts (container ID the same).
		for (Iterator i = rosterAccounts.iterator(); i.hasNext();) {
			MultiRosterAccount existingAccount = (MultiRosterAccount) i.next();
			if (existingAccount.getContainer().getID().equals(container.getID()))
				return true;
		}
		return false;
	}

	protected boolean addRosterAccount(MultiRosterAccount account) {
		// If account is null, we don't add it.  This is just a sanity check.
		if (account == null)
			return false;
		// Not found, so we continue with add
		boolean result = rosterAccounts.add(account);
		if (result)
			setLocalPullDownEnabled(true);
		return result;
	}

	protected void rosterAccountDisconnected(MultiRosterAccount disconnectedAccount) {
		// remove account. This will be changed to maintain the roster account
		// info even though disconnected...see bug
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166670
		removeRosterAccount(disconnectedAccount);
	}

	protected void removeRosterAccount(MultiRosterAccount account) {
		// Remove presence listener
		account.getRosterManager().removePresenceListener(presenceListener);

		if (treeViewer != null)
			treeViewer.remove(account.getRoster());
		// Remove account
		rosterAccounts.remove(account);
		if (rosterAccounts.size() == 0) {
			setLocalPullDownEnabled(false);
			// container may disconnect while widgets are being disposed, check for this
			if (!pageBook.isDisposed()) {
				pageBook.showPage(helpMessageLabel);
			}
		}
		account.dispose();
		refreshTreeViewer(null, true);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
	 */
	public void setFocus() {
		treeViewer.getControl().setFocus();
	}

	protected void refreshTreeViewer(Object val, boolean labels) {
		if (treeViewer != null) {
			Control c = treeViewer.getControl();
			if (c != null && !c.isDisposed()) {
				if (val != null) {
					treeViewer.refresh(val, labels);
					ViewerFilter[] filters = treeViewer.getFilters();
					if (filters.length != 0) {
						treeViewer.refresh(labels);
					}
				} else {
					treeViewer.refresh(labels);
				}
				treeViewer.expandToLevel(DEFAULT_EXPAND_LEVEL);
			}
		}
	}

	protected void addEntryToTreeViewer(IRosterEntry entry) {
		if (treeViewer != null)
			treeViewer.add(entry.getParent(), entry);
	}

	protected void removeEntryFromTreeViewer(IRosterEntry entry) {
		if (treeViewer != null)
			treeViewer.remove(entry);
	}

	protected void removeEntryFromTreeViewer(ID entryID) {
		synchronized (rosterAccounts) {
			for (Iterator i = rosterAccounts.iterator(); i.hasNext();) {
				MultiRosterAccount account = (MultiRosterAccount) i.next();
				final IRosterEntry entry = find(account.getRoster().getItems(), entryID);
				if (entry != null)
					treeViewer.remove(entry);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.presence.ui.IMultiRosterViewPart#addContainer(org.eclipse.ecf.core.IContainer)
	 */
	public boolean addContainer(IContainer container) {
		if (container == null)
			return false;
		IPresenceContainerAdapter containerAdapter = (IPresenceContainerAdapter) container.getAdapter(IPresenceContainerAdapter.class);
		if (containerAdapter == null)
			return false;
		if (containerPresent(container))
			return false;
		MultiRosterAccount account = new MultiRosterAccount(this, container, containerAdapter);
		if (!addRosterAccount(account))
			return false;

		IRosterManager manager = containerAdapter.getRosterManager();
		try {
			if (setAvailableAction.isChecked() || setOfflineAction.isChecked()) {
				manager.getPresenceSender().sendPresenceUpdate(null, new Presence(null, null, IPresence.Mode.AVAILABLE));
				setOfflineAction.setChecked(false);
				setAvailableAction.setChecked(true);
			} else if (setAwayAction.isChecked()) {
				manager.getPresenceSender().sendPresenceUpdate(null, new Presence(null, null, IPresence.Mode.AWAY));
			} else if (setDNDAction.isChecked()) {
				manager.getPresenceSender().sendPresenceUpdate(null, new Presence(null, null, IPresence.Mode.DND));
			} else if (setInvisibleAction.isChecked()) {
				manager.getPresenceSender().sendPresenceUpdate(null, new Presence(null, null, IPresence.Mode.INVISIBLE));
			}
		} catch (ECFException e) {
			Activator.getDefault().getLog().log(e.getStatus());
		}
		containerAdapter.getRosterManager().addPresenceListener(presenceListener);
		setStatusMenu.setVisible(true);
		getViewSite().getActionBars().getMenuManager().update(true);
		treeViewer.add(treeViewer.getInput(), account.getRoster());
		pageBook.showPage(treeViewer.getControl());
		return true;
	}

	private class PresenceListener implements IPresenceListener {

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ecf.presence.IParticipantListener#handlePresence(org.eclipse.ecf.core.identity.ID,
		 *      org.eclipse.ecf.presence.IPresence)
		 */
		public void handlePresence(ID fromID, IPresence presence) {
			// do nothing
		}

	}

	private class ViewerToolTip extends ToolTip {

		private Image image;

		public ViewerToolTip(Control control) {
			super(control);
		}

		protected Composite createToolTipContentArea(Event event, Composite parent) {
			TreeItem item = treeViewer.getTree().getItem(new Point(event.x, event.y));
			IRosterEntry entry = (IRosterEntry) item.getData();

			FormToolkit toolkit = new FormToolkit(parent.getDisplay());
			FormColors colors = toolkit.getColors();
			Color top = colors.getColor(IFormColors.H_GRADIENT_END);
			Color bot = colors.getColor(IFormColors.H_GRADIENT_START);

			// create the base form
			Form form = toolkit.createForm(parent);
			form.setText(entry.getName());
			form.setImage(SharedImages.getImage(SharedImages.IMG_USER_AVAILABLE));
			form.setTextBackground(new Color[] {top, bot}, new int[] {100}, true);
			GridLayout layout = new GridLayout();
			layout.numColumns = 3;
			form.getBody().setLayout(layout);

			// create the text
			FormText text = toolkit.createFormText(form.getBody(), true);
			GridData td = new GridData();
			td.horizontalSpan = 2;
			td.heightHint = 100;
			td.widthHint = 250;
			text.setLayoutData(td);

			String buffer = getRosterEntryChildrenFromPresence(entry);
			text.setText(buffer, true, false);

			// create the picture
			td = new GridData();
			td.horizontalSpan = 1;
			td.heightHint = 100;
			td.widthHint = 64;
			FormText formImage = toolkit.createFormText(form.getBody(), false);
			formImage.setText("<form><p><img href=\"image\"/></p></form>", true, false); //$NON-NLS-1$
			formImage.setLayoutData(td);

			// grab the image and resize it
			byte[] data = entry.getPresence().getPictureData();
			if (data.length != 0) {
				Image originalImage = new Image(parent.getDisplay(), new ByteArrayInputStream(data));
				image = resize(originalImage, 64, 64);
				formImage.setImage("image", image); //$NON-NLS-1$
				originalImage.dispose();
			}

			return parent;
		}

		public void deactivate() {
			super.deactivate();
			if (image != null)
				image.dispose();
		}

		private Image resize(Image image1, int width, int height) {
			final Image scaled = new Image(Display.getDefault(), width, height);
			GC gc = new GC(scaled);
			gc.setAntialias(SWT.ON);
			gc.setInterpolation(SWT.HIGH);
			gc.drawImage(image1, 0, 0, image1.getBounds().width, image1.getBounds().height, 0, 0, width, height);
			gc.dispose();
			return scaled;
		}

		private String getResourceName(ID id) {
			IFQID fqid = (IFQID) id.getAdapter(IFQID.class);
			if (fqid != null) {
				return fqid.getResourceName();
			}
			return null;
		}

		private String getRosterEntryChildrenFromPresence(IRosterEntry entry) {
			IPresence presence = entry.getPresence();
			Map properties = presence.getProperties();
			String resourceName = getResourceName(entry.getUser().getID());
			StringBuffer buffer = new StringBuffer();
			buffer.append("<form>"); //$NON-NLS-1$
			buffer.append("<p>"); //$NON-NLS-1$
			buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Account, entry.getUser().getID().getName()));
			buffer.append("</p>"); //$NON-NLS-1$
			buffer.append("<p>"); //$NON-NLS-1$
			buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Type, presence.getType()));
			buffer.append("</p>"); //$NON-NLS-1$
			buffer.append("<p>");//$NON-NLS-1$
			buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Mode, presence.getMode().toString()));
			buffer.append("</p>"); //$NON-NLS-1$
			buffer.append("<p>"); //$NON-NLS-1$
			buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Resource, ((resourceName == null) ? "" : resourceName))); //$NON-NLS-1$
			buffer.append("</p>"); //$NON-NLS-1$
			for (Iterator i = properties.keySet().iterator(); i.hasNext();) {
				buffer.append("<p>"); //$NON-NLS-1$
				Object key = i.next();
				buffer.append(key).append(": ").append(properties.get(key)); //$NON-NLS-1$
				buffer.append("</p>"); //$NON-NLS-1$
			}
			buffer.append("</form>"); //$NON-NLS-1$
			return buffer.toString();
		}

		protected boolean shouldCreateToolTip(Event e) {
			if (super.shouldCreateToolTip(e)) {
				TreeItem item = treeViewer.getTree().getItem(new Point(e.x, e.y));
				return item != null && item.getData() instanceof IRosterEntry;
			}
			return false;
		}
	}

	class RoomWithAView {
		ChatRoomManagerView view;

		ID secondaryID;

		RoomWithAView(ChatRoomManagerView view, ID secondaryID) {
			this.view = view;
			this.secondaryID = secondaryID;
		}

		public ChatRoomManagerView getView() {
			return view;
		}

		public ID getID() {
			return secondaryID;
		}
	}
}
