/******************************************************************************* 
 * Copyright (c) 2016 Red Hat, Inc. 
 * Distributed under license by Red Hat, Inc. All rights reserved. 
 * This program is 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: 
 * Red Hat, Inc. - initial API and implementation 
 ******************************************************************************/ 
package org.jboss.reddeer.swt.impl.tree;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.hamcrest.Matcher;
import org.jboss.reddeer.common.logging.Logger;
import org.jboss.reddeer.swt.api.Tree;
import org.jboss.reddeer.swt.api.TreeItem;
import org.jboss.reddeer.core.handler.TreeHandler;
import org.jboss.reddeer.core.handler.TreeItemHandler;
import org.jboss.reddeer.core.reference.ReferencedComposite;
import org.jboss.reddeer.swt.widgets.AbstractControl;

public abstract class AbstractTree extends AbstractControl<org.eclipse.swt.widgets.Tree> implements Tree {

	private static final Logger logger = Logger.getLogger(AbstractTree.class);


	protected AbstractTree(ReferencedComposite refComposite, int index, Matcher<?>... matchers){
		super(org.eclipse.swt.widgets.Tree.class, refComposite, index, matchers);
	}
	
	protected AbstractTree(org.eclipse.swt.widgets.Tree tree){
		super(tree);
	}
	
	/* (non-Javadoc)
	 * @see org.jboss.reddeer.swt.api.Tree#getAllItems()
	 */
	public List<TreeItem> getAllItems() {
		List<TreeItem> list = new LinkedList<TreeItem>();
		list.addAll(getAllItemsRecursive(getItems()));
		return list;
	}

	/* (non-Javadoc)
	 * @see org.jboss.reddeer.swt.api.Tree#getItems()
	 */
	public List<TreeItem> getItems() {
		LinkedList<TreeItem> items = new LinkedList<TreeItem>();
		List<org.eclipse.swt.widgets.TreeItem> eclipseItems = TreeHandler.getInstance().getSWTItems(swtWidget);
		for (org.eclipse.swt.widgets.TreeItem swtTreeItem : eclipseItems) {
			items.addLast(new DefaultTreeItem(swtTreeItem));
		}
		return items;
	}

	public void selectItems(final TreeItem... treeItems) {
		// Tree items should be logged, however, the names needs to 
		// be retrieved in UI thread so it might be a performance issue
		logger.info("Select specified tree items");
		org.eclipse.swt.widgets.TreeItem[] items = new org.eclipse.swt.widgets.TreeItem[treeItems.length];
		for (int i=0; i < treeItems.length; i++) {
			items[i] = treeItems[i].getSWTWidget();
		}
		TreeItemHandler.getInstance().selectItems(items);
	}

	@Override
	public List<TreeItem> getSelectedItems() {
		List<TreeItem> selectedItems = new ArrayList<TreeItem>();
		for (org.eclipse.swt.widgets.TreeItem swtItem : TreeHandler.getInstance().getSelection(swtWidget)) {
			selectedItems.add(new DefaultTreeItem(swtItem));
		}
		return selectedItems;
	}

	/* (non-Javadoc)
	 * @see org.jboss.reddeer.swt.api.Tree#setFocus()
	 */
	public void setFocus() {
		TreeHandler.getInstance().setFocus(swtWidget);
	}

	/**
	 * Gets the column count.
	 *
	 * @return the column count
	 * @see Tree#getColumnCount()
	 */
	public int getColumnCount() {
		return TreeHandler.getInstance().getColumnCount(swtWidget);
	}
	
	/* (non-Javadoc)
	 * @see org.jboss.reddeer.swt.api.Tree#getHeaderColumns()
	 */
	public List<String> getHeaderColumns() {
		return TreeHandler.getInstance().getHeaderColumns(swtWidget);
	}

	/* (non-Javadoc)
	 * @see org.jboss.reddeer.swt.api.Tree#unselectAllItems()
	 */
	public void unselectAllItems() {
		logger.info("Unselect all tree items");
		TreeHandler.getInstance().unselectAllItems(swtWidget);
	}
	
	private List<TreeItem> getAllItemsRecursive(List<TreeItem> parentItems) {
		List<TreeItem> list = new LinkedList<TreeItem>();

		for (TreeItem item : parentItems) {
			list.add(item);
			list.addAll(getAllItemsRecursive(item.getItems()));
		}
		return list;
	}
}

@@ -676,24 +676,84 @@
 st.Matcher;%0A
+import org.jboss.reddeer.common.exception.RedDeerException;%0A
 import org.j
@@ -2121,56 +2121,248 @@
 %0A%09%09%09
-items.addLast(new DefaultTreeItem(swtTreeItem));
+DefaultTreeItem item = null;%0A%09%09%09try%7B%0A%09%09%09%09item = new DefaultTreeItem(swtTreeItem);%0A%09%09%09%09items.addLast(item);%0A%09%09%09%7D catch (RedDeerException e) %7B%0A%09%09%09%09if(TreeHandler.getInstance().isDisposed(swtTreeItem))%7B%0A%09%09%09%09%09continue;%0A%09%09%09%09%7D %0A%09%09%09%09throw e;%0A%09%09%09%7D 
 %0A%09%09%7D
@@ -3087,56 +3087,243 @@
 %0A%09%09%09
-selectedItems.add(new DefaultTreeItem(swtItem));
+DefaultTreeItem item = null;%0A%09%09%09try%7B%0A%09%09%09%09item = new DefaultTreeItem(swtItem);%0A%09%09%09%09selectedItems.add(item);%0A%09%09%09%7D catch (RedDeerException e) %7B%0A%09%09%09%09if(TreeHandler.getInstance().isDisposed(swtItem))%7B%0A%09%09%09%09%09continue;%0A%09%09%09%09%7D %0A%09%09%09%09throw e;%0A%09%09%09%7D
 %0A%09%09%7D

Check if treeitem is disposed when getting all Tree items. Fixes #1687