org.rssowl.ui.internal.dialogs.importer.ImportElementsPage.java Source code

Java tutorial

Introduction

Here is the source code for org.rssowl.ui.internal.dialogs.importer.ImportElementsPage.java

Source

/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2005-2009 RSSOwl Development Team                                  **
 **   http://www.rssowl.org/                                                 **
 **                                                                          **
 **   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.rssowl.org/legal/epl-v10.html                               **
 **                                                                          **
 **   A copy is found in the file epl-v10.html and important notices to the  **
 **   license from the team is found in the textfile LICENSE.txt distributed **
 **   in this package.                                                       **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Contributors:                                                          **
 **     RSSOwl Development Team - initial API and implementation             **
 **                                                                          **
 **  **********************************************************************  */

package org.rssowl.ui.internal.dialogs.importer;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.rssowl.core.Owl;
import org.rssowl.core.connection.AuthenticationRequiredException;
import org.rssowl.core.connection.ConnectionException;
import org.rssowl.core.connection.CredentialsException;
import org.rssowl.core.connection.HttpConnectionInputStream;
import org.rssowl.core.connection.IAbortable;
import org.rssowl.core.connection.IConnectionPropertyConstants;
import org.rssowl.core.connection.ICredentials;
import org.rssowl.core.connection.IProtocolHandler;
import org.rssowl.core.connection.SyncConnectionException;
import org.rssowl.core.internal.persist.pref.DefaultPreferences;
import org.rssowl.core.interpreter.ITypeImporter;
import org.rssowl.core.interpreter.InterpreterException;
import org.rssowl.core.interpreter.ParserException;
import org.rssowl.core.persist.IBookMark;
import org.rssowl.core.persist.IEntity;
import org.rssowl.core.persist.IFeed;
import org.rssowl.core.persist.IFolder;
import org.rssowl.core.persist.IFolderChild;
import org.rssowl.core.persist.ILabel;
import org.rssowl.core.persist.IModelFactory;
import org.rssowl.core.persist.INewsBin;
import org.rssowl.core.persist.IPreference;
import org.rssowl.core.persist.ISearchFilter;
import org.rssowl.core.persist.ISearchMark;
import org.rssowl.core.persist.dao.DynamicDAO;
import org.rssowl.core.persist.dao.IBookMarkDAO;
import org.rssowl.core.persist.pref.IPreferenceScope;
import org.rssowl.core.persist.reference.FeedLinkReference;
import org.rssowl.core.util.CoreUtils;
import org.rssowl.core.util.Pair;
import org.rssowl.core.util.RegExUtils;
import org.rssowl.core.util.StringUtils;
import org.rssowl.core.util.SyncUtils;
import org.rssowl.core.util.URIUtils;
import org.rssowl.ui.internal.Activator;
import org.rssowl.ui.internal.Application;
import org.rssowl.ui.internal.Controller;
import org.rssowl.ui.internal.OwlUI;
import org.rssowl.ui.internal.dialogs.CustomWizardDialog;
import org.rssowl.ui.internal.dialogs.LoginDialog;
import org.rssowl.ui.internal.dialogs.PreviewFeedDialog;
import org.rssowl.ui.internal.dialogs.importer.ImportSourcePage.Source;
import org.rssowl.ui.internal.dialogs.welcome.WelcomeWizard;
import org.rssowl.ui.internal.util.BrowserUtils;
import org.rssowl.ui.internal.util.FolderChildCheckboxTree;
import org.rssowl.ui.internal.util.JobRunner;
import org.rssowl.ui.internal.util.LayoutUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A {@link WizardPage} to select the elements to import.
 *
 * @author bpasero
 */
public class ImportElementsPage extends WizardPage {

    /* Initial Connection Timeout when looking for Feeds remotely */
    private static final int INITIAL_CON_TIMEOUT = 30000;

    /* Connection Timeout when testing for Feeds remotely */
    private static final int FEED_CON_TIMEOUT = 7000;

    /* Default Feed Search Language */
    private static final String DEFAULT_LANGUAGE = "en"; //$NON-NLS-1$

    private CheckboxTreeViewer fViewer;
    private FolderChildCheckboxTree fFolderChildTree;
    private Button fDeselectAll;
    private Button fSelectAll;
    private Button fPreviewButton;
    private Button fFlattenCheck;
    private Button fHideExistingCheck;
    private ExistingBookmarkFilter fExistingFilter = new ExistingBookmarkFilter();
    private Map<URI, IFeed> fLoadedFeedCache = new ConcurrentHashMap<URI, IFeed>();
    private IProgressMonitor fCurrentProgressMonitor;

    /* Remember Current Import Values */
    private Source fCurrentSourceKind;
    private String fCurrentSourceResource;
    private String fCurrentSourceKeywords;
    private boolean fCurrentSourceLocalizedFeedSearch;
    private long fCurrentSourceFileModified;

    /* Imported Entities */
    private List<ILabel> fLabels = Collections.synchronizedList(new ArrayList<ILabel>());
    private List<ISearchFilter> fFilters = Collections.synchronizedList(new ArrayList<ISearchFilter>());
    private List<IPreference> fPreferences = Collections.synchronizedList(new ArrayList<IPreference>());

    /* Filter to Exclude Existing Bookmarks (empty folders are excluded as well) */
    private static class ExistingBookmarkFilter extends ViewerFilter {
        private IBookMarkDAO dao = DynamicDAO.getDAO(IBookMarkDAO.class);
        private Map<IFolderChild, Boolean> cache = new IdentityHashMap<IFolderChild, Boolean>();

        @Override
        public boolean select(Viewer viewer, Object parentElement, Object element) {
            if (element instanceof IFolderChild)
                return select((IFolderChild) element);

            return true;
        }

        void clear() {
            cache.clear();
        }

        private boolean select(IFolderChild element) {

            /* Bookmark (exclude if another Bookmark with same Link exists) */
            if (element instanceof IBookMark) {
                IBookMark bm = (IBookMark) element;
                Boolean select = cache.get(bm);
                if (select == null) {
                    select = !dao.exists(bm.getFeedLinkReference());
                    cache.put(bm, select);
                }

                return select;
            }

            /* Bin (exclude if another Bin with same name Exists at same Location) */
            else if (element instanceof INewsBin) {
                INewsBin bin = (INewsBin) element;
                Boolean select = cache.get(bin);
                if (select == null) {
                    select = !CoreUtils.existsNewsBin(bin);
                    cache.put(bin, select);
                }

                return select;
            }

            /* Search (exclude if another Search with same name Exists at same Location and same Conditions) */
            else if (element instanceof ISearchMark) {
                ISearchMark searchmark = (ISearchMark) element;
                Boolean select = cache.get(searchmark);
                if (select == null) {
                    select = !CoreUtils.existsSearchMark(searchmark);
                    cache.put(searchmark, select);
                }

                return select;
            }

            /* Folder */
            else if (element instanceof IFolder) {
                IFolder folder = (IFolder) element;
                Boolean select = cache.get(folder);
                if (select == null) {
                    List<IFolderChild> children = folder.getChildren();
                    for (IFolderChild child : children) {
                        select = select(child);
                        if (select)
                            break;
                    }

                    cache.put(folder, select);
                }

                return select != null ? select : false;
            }

            return true;
        }
    }

    ImportElementsPage() {
        super(Messages.ImportElementsPage_CHOOSE_ELEMENTS, Messages.ImportElementsPage_CHOOSE_ELEMENTS, null);
        setMessage(Messages.ImportElementsPage_CHOOSE_ELEMENTS_MESSAGE);
    }

    /* Get Elements to Import */
    List<IFolderChild> getFolderChildsToImport() {
        doImportSource(); //Ensure to be in sync with Source
        return fFolderChildTree.getCheckedElements();
    }

    /* Returns Labels available for Import */
    List<ILabel> getLabelsToImport() {
        doImportSource(); //Ensure to be in sync with Source
        return fLabels;
    }

    /* Returns Filters available for Import */
    List<ISearchFilter> getFiltersToImport() {
        doImportSource(); //Ensure to be in sync with Source
        return fFilters;
    }

    /* Returns the Preferences available for Import */
    List<IPreference> getPreferencesToImport() {
        doImportSource(); //Ensure to be in sync with Source
        return fPreferences;
    }

    /* Returns whether existing bookmarks should be ignored for the Import */
    boolean excludeExisting() {
        return fHideExistingCheck.getSelection();
    }

    /* Check if the Options Page should be shown from the Wizard */
    boolean showOptionsPage() {
        return !fLabels.isEmpty() || !fFilters.isEmpty() || !fPreferences.isEmpty();
    }

    /*
     * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
     */
    public void createControl(Composite parent) {
        boolean isWelcome = (getWizard() instanceof WelcomeWizard);

        /* Title Image */
        setImageDescriptor(
                OwlUI.getImageDescriptor(getWizard() instanceof WelcomeWizard ? "icons/wizban/welcome_wiz.gif" //$NON-NLS-1$
                        : "icons/wizban/import_wiz.png")); //$NON-NLS-1$

        /* Container */
        Composite container = new Composite(parent, SWT.NONE);
        container.setLayout(new GridLayout(1, false));

        /* Viewer for Folder Child Selection */
        fFolderChildTree = new FolderChildCheckboxTree(container);
        if (!isWelcome)
            ((GridData) fFolderChildTree.getViewer().getTree().getLayoutData()).heightHint = 140;
        fViewer = fFolderChildTree.getViewer();

        /* Open Preview on Doubleclick */
        fViewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                openPreview(event.getSelection());
            }
        });

        /* Control Preview Button Enablement */
        fViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                ISelection selection = event.getSelection();
                fPreviewButton.setEnabled(!selection.isEmpty()
                        && ((IStructuredSelection) selection).getFirstElement() instanceof IBookMark);
            }
        });

        /* Filter (exclude existing) */
        fViewer.addFilter(fExistingFilter);

        /* Update Page Complete on Selection */
        fViewer.getTree().addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                updatePageComplete();
            }
        });

        /* Select All / Deselect All */
        Composite buttonContainer = new Composite(container, SWT.NONE);
        buttonContainer.setLayout(LayoutUtils.createGridLayout(isWelcome ? 5 : 6, 0, 0));
        buttonContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));

        fSelectAll = new Button(buttonContainer, SWT.PUSH);
        fSelectAll.setText(Messages.ImportElementsPage_SELECT_ALL);
        Dialog.applyDialogFont(fSelectAll);
        setButtonLayoutData(fSelectAll);
        fSelectAll.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                fFolderChildTree.setAllChecked(true);
                updatePageComplete();
            }
        });

        fDeselectAll = new Button(buttonContainer, SWT.PUSH);
        fDeselectAll.setText(Messages.ImportElementsPage_DESELECT_ALL);
        Dialog.applyDialogFont(fDeselectAll);
        setButtonLayoutData(fDeselectAll);
        fDeselectAll.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                fFolderChildTree.setAllChecked(false);
                updatePageComplete();
            }
        });

        if (!Application.IS_MAC) {
            Label sep = new Label(buttonContainer, SWT.SEPARATOR | SWT.VERTICAL);
            sep.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, false));
            ((GridData) sep.getLayoutData()).heightHint = 20;
        }

        fPreviewButton = new Button(buttonContainer, SWT.PUSH);
        fPreviewButton.setText(Messages.ImportElementsPage_PREVIEW);
        fPreviewButton.setEnabled(false);
        fPreviewButton.setToolTipText(Messages.ImportElementsPage_SHOW_PREVIEW);
        Dialog.applyDialogFont(fPreviewButton);
        setButtonLayoutData(fPreviewButton);
        fPreviewButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                openPreview(fViewer.getSelection());
            }
        });

        /* Show as Flat List of News Marks */
        fFlattenCheck = new Button(buttonContainer, SWT.CHECK);
        fFlattenCheck.setText(Messages.ImportElementsPage_FLATTEN);
        Dialog.applyDialogFont(fFlattenCheck);
        setButtonLayoutData(fFlattenCheck);
        ((GridData) fFlattenCheck.getLayoutData()).horizontalAlignment = SWT.END;
        ((GridData) fFlattenCheck.getLayoutData()).horizontalIndent = 30;
        ((GridData) fFlattenCheck.getLayoutData()).grabExcessHorizontalSpace = true;
        fFlattenCheck.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                fFolderChildTree.setFlat(fFlattenCheck.getSelection());
                fViewer.expandToLevel(2);
                fFolderChildTree.setAllChecked(true);
            }
        });

        /* Hide Existing News Marks */
        fHideExistingCheck = new Button(buttonContainer, SWT.CHECK);
        fHideExistingCheck.setText(Messages.ImportElementsPage_HIDE_EXISTING);
        fHideExistingCheck.setSelection(true);
        Dialog.applyDialogFont(fHideExistingCheck);
        setButtonLayoutData(fHideExistingCheck);
        ((GridData) fHideExistingCheck.getLayoutData()).exclude = isWelcome;
        fHideExistingCheck.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (fHideExistingCheck.getSelection())
                    fViewer.addFilter(fExistingFilter);
                else
                    fViewer.removeFilter(fExistingFilter);

                fViewer.expandToLevel(2);
                updateMessage(false);
            }
        });

        /* React on user clicking Cancel if a progress is showing */
        if (getContainer() instanceof CustomWizardDialog) {
            Button cancelButton = ((CustomWizardDialog) getContainer()).getButton(IDialogConstants.CANCEL_ID);
            if (cancelButton != null) {
                cancelButton.addSelectionListener(new SelectionAdapter() {
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        onCancel();
                    }
                });
            }
        }

        Dialog.applyDialogFont(container);

        setControl(container);
    }

    private void onCancel() {
        if (fCurrentProgressMonitor != null && getShell() != null && !getShell().isDisposed()) {
            IProgressMonitor monitor = fCurrentProgressMonitor;
            monitor.setTaskName(Messages.ImportElementsPage_CANCEL_SEARCH);
            monitor.subTask(""); //$NON-NLS-1$
        }
    }

    private void openPreview(ISelection selection) {
        IStructuredSelection sel = (IStructuredSelection) selection;
        if (!sel.isEmpty()) {
            Object[] elements = sel.toArray();
            int offset = 0;
            for (Object element : elements) {
                if (element instanceof IBookMark) {
                    IBookMark bookmark = (IBookMark) element;
                    IFeed loadedFeed = fLoadedFeedCache.get(bookmark.getFeedLinkReference().getLink());

                    PreviewFeedDialog dialog = new PreviewFeedDialog(getShell(), bookmark, loadedFeed);
                    dialog.setBlockOnOpen(false);
                    dialog.open();

                    if (offset != 0) {
                        Point location = dialog.getShell().getLocation();
                        dialog.getShell().setLocation(location.x + offset, location.y + offset);
                    }

                    offset += 20;
                }
            }
        }
    }

    private void updateMessage(boolean clearErrors) {
        List<?> input = (List<?>) fViewer.getInput();
        if (!input.isEmpty() && fViewer.getTree().getItemCount() == 0 && fViewer.getFilters().length > 0)
            setMessage(Messages.ImportElementsPage_HIDDEN_ELEMENTS_INFO, IMessageProvider.INFORMATION);
        else
            setMessage(Messages.ImportElementsPage_CHOOSE_ELEMENTS_MESSAGE);

        if (clearErrors)
            setErrorMessage(null);

        updatePageComplete();
    }

    private void updatePageComplete() {
        boolean complete = (showOptionsPage() || fViewer.getCheckedElements().length > 0);
        setPageComplete(complete);
    }

    /*
     * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean)
     */
    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (!visible)
            return;

        fViewer.getControl().setFocus();

        /* Load Elements to Import from Source on first time */
        doImportSource();
    }

    @SuppressWarnings("unchecked")
    private void doImportSource() {
        ImportSourcePage importSourcePage = (ImportSourcePage) getPreviousPage();
        final Source source = importSourcePage.getSource();

        /* Return if the Source did not Change */
        if (source == Source.RECOMMENDED && fCurrentSourceKind == Source.RECOMMENDED)
            return;
        else if (source == Source.GOOGLE && fCurrentSourceKind == Source.GOOGLE)
            return;
        else if (source == Source.KEYWORD && fCurrentSourceKind == Source.KEYWORD
                && importSourcePage.getImportKeywords().equals(fCurrentSourceKeywords)
                && fCurrentSourceLocalizedFeedSearch == importSourcePage.isLocalizedFeedSearch())
            return;
        else if (source == Source.RESOURCE && fCurrentSourceKind == Source.RESOURCE) {
            String importResource = importSourcePage.getImportResource();

            /* Same URL */
            if (importSourcePage.isRemoteSource() && importResource.equals(fCurrentSourceResource))
                return;

            /* Same Unmodified File */
            else if (importResource.equals(fCurrentSourceResource)) {
                File file = new File(importResource);
                if (file.exists() && file.lastModified() == fCurrentSourceFileModified)
                    return;
            }
        }

        /* Remember Source */
        fCurrentSourceKind = source;
        fCurrentSourceResource = importSourcePage.getImportResource();
        final File sourceFile = (source == Source.RESOURCE) ? new File(importSourcePage.getImportResource()) : null;
        fCurrentSourceFileModified = (sourceFile != null && sourceFile.exists()) ? sourceFile.lastModified() : 0;
        fCurrentSourceKeywords = importSourcePage.getImportKeywords();
        fCurrentSourceLocalizedFeedSearch = importSourcePage.isLocalizedFeedSearch();

        /* Reset Fields */
        fLabels.clear();
        fFilters.clear();
        fPreferences.clear();

        /* Reset Messages */
        setErrorMessage(null);
        setMessage(Messages.ImportElementsPage_CHOOSE_ELEMENTS_MESSAGE);

        /* Clear Viewer before loading */
        setImportedElements(Collections.EMPTY_LIST);

        /* Ask for Username and Password if importing from Google */
        if (source == Source.GOOGLE) {
            if (!SyncUtils.hasSyncCredentials() && OwlUI.openSyncLogin(getShell()) != IDialogConstants.OK_ID) {
                setErrorMessage(Messages.ImportElementsPage_MISSING_ACCOUNT);
                setPageComplete(false);
                fCurrentSourceKind = null;
                return;
            }
        }

        /* Import Runnable */
        Runnable runnable = new Runnable() {
            public void run() {
                try {

                    /* Import from Supplied File */
                    if (source == Source.RESOURCE && sourceFile != null && sourceFile.exists())
                        importFromLocalResource(sourceFile);

                    /* Import from Supplied Online Resource */
                    else if (source == Source.RESOURCE && URIUtils.looksLikeLink(fCurrentSourceResource, false))
                        importFromOnlineResource(new URI(URIUtils.ensureProtocol(fCurrentSourceResource)));

                    /* Import from Google */
                    else if (source == Source.GOOGLE)
                        importFromGoogleReader();

                    /* Import by Keyword Search */
                    else if (source == Source.KEYWORD)
                        importFromKeywordSearch(fCurrentSourceKeywords, fCurrentSourceLocalizedFeedSearch);

                    /* Import from Default OPML File */
                    else if (source == Source.RECOMMENDED)
                        importFromLocalResource(getClass().getResourceAsStream("/default_feeds.xml")); //$NON-NLS-1$;
                }

                /* Log and Show any Exception during Import */
                catch (Exception e) {

                    /* Offer a Login Dialog in case Google Reader import fails with provided credentials */
                    if (e instanceof InvocationTargetException
                            && e.getCause() instanceof AuthenticationRequiredException && source == Source.GOOGLE) {
                        if (OwlUI.openSyncLogin(getShell()) == IDialogConstants.OK_ID) {
                            try {
                                importFromGoogleReader();
                                return;
                            } catch (InvocationTargetException ex1) {
                                e = ex1; //Pass exception on to outer handling
                            } catch (InterruptedException ex2) {
                                e = ex2; //Pass exception on to outer handling
                            }
                        }
                    }

                    /* Handle SyncConnectionException */
                    if (e instanceof InvocationTargetException && e.getCause() instanceof SyncConnectionException) {
                        String userLink = ((SyncConnectionException) e.getCause()).getUserUrl();
                        if (StringUtils.isSet(userLink)) {
                            MessageBox box = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK | SWT.CANCEL);
                            box.setText(Messages.ImportElementsPage_ERROR_IMPORT_GR);
                            String msg = NLS.bind(Messages.ImportElementsPage_ERROR_IMPORT_GR_DETAILS,
                                    e.getCause().getMessage());

                            box.setMessage(msg);
                            if (box.open() == SWT.OK)
                                BrowserUtils.openLinkExternal(userLink);
                        }
                    }

                    /* Log Message */
                    String logMessage = e.getMessage();
                    if (e instanceof InvocationTargetException && e.getCause() != null
                            && StringUtils.isSet(e.getCause().getMessage()))
                        logMessage = e.getCause().getMessage();

                    if (StringUtils.isSet(logMessage))
                        logMessage = NLS.bind(Messages.ImportElementsPage_UNABLE_TO_IMPORT_REASON, logMessage);
                    else
                        logMessage = Messages.ImportElementsPage_UNABLE_TO_IMPORT;

                    /* User Message */
                    String userMessage = CoreUtils.toMessage(e);
                    if (StringUtils.isSet(userMessage))
                        userMessage = NLS.bind(Messages.ImportElementsPage_UNABLE_TO_IMPORT_REASON, userMessage);
                    else
                        userMessage = Messages.ImportElementsPage_UNABLE_TO_IMPORT;

                    Activator.getDefault().logError(logMessage, e);
                    setErrorMessage(userMessage);
                    setPageComplete(false);

                    /* Give a chance to try again */
                    fCurrentSourceKind = null;
                }
            }
        };

        /* Perform delayed if potential remote import to give Viewer a chance to show */
        if (importSourcePage.isRemoteSource())
            JobRunner.runInUIThread(50, getShell(), runnable);
        else
            runnable.run();
    }

    /* Import from a Local Input Stream (no progress required) */
    private void importFromLocalResource(InputStream in) throws InterpreterException, ParserException {

        /* Show Folder Childs in Viewer */
        List<? extends IEntity> types = Owl.getInterpreter().importFrom(in);
        setImportedElements(types);
        updateMessage(true);
    }

    /* Import from a Local File */
    private void importFromLocalResource(final File file)
            throws FileNotFoundException, InvocationTargetException, InterruptedException {
        boolean bruteForce = false;

        /* First Try to Import as OPML */
        try {
            importFromLocalResource(new FileInputStream(file));
        } catch (ParserException e) {
            bruteForce = true;
        } catch (InterpreterException e) {
            bruteForce = true;
        }

        /* Then try to parse links found in the file as Feeds */
        if (bruteForce) {
            setMessage(Messages.ImportElementsPage_INVALID_OPML_WARNING, IMessageProvider.WARNING);

            IRunnableWithProgress runnable = new IRunnableWithProgress() {
                public void run(final IProgressMonitor monitor) throws InvocationTargetException {
                    monitor.beginTask(Messages.ImportElementsPage_SEARCHING_FOR_FEEDS, IProgressMonitor.UNKNOWN);
                    fCurrentProgressMonitor = monitor;

                    /* Return on Cancellation */
                    if (monitor.isCanceled() || Controller.getDefault().isShuttingDown())
                        return;

                    /* Read Content */
                    Reader reader = null;
                    try {
                        reader = new FileReader(file);
                        String content = StringUtils.readString(reader);

                        /* Extract Links from Content */
                        List<String> links = new ArrayList<String>();
                        if (StringUtils.isSet(content))
                            links.addAll(RegExUtils.extractLinksFromText(content, false));

                        /* Check Links for valid Feeds */
                        importFromLinksBruteforce(links, monitor);
                    } catch (Exception e) {
                        throw new InvocationTargetException(e);
                    } finally {
                        fCurrentProgressMonitor = null;
                        monitor.done();

                        /* Close Reader */
                        if (reader != null) {
                            try {
                                reader.close();
                            } catch (IOException e) {
                                throw new InvocationTargetException(e);
                            }
                        }
                    }
                }
            };

            /* Run Operation in Background and allow for Cancellation */
            getContainer().run(true, true, runnable);
        }
    }

    private void importFromOnlineResource(final URI link) throws InvocationTargetException, InterruptedException {
        IRunnableWithProgress runnable = new IRunnableWithProgress() {
            public void run(final IProgressMonitor monitor) throws InvocationTargetException {
                InputStream in = null;
                boolean canceled = false;
                Exception error = null;
                boolean bruteForce = false;
                try {
                    monitor.beginTask(Messages.ImportElementsPage_SEARCHING_FOR_FEEDS, IProgressMonitor.UNKNOWN);
                    monitor.subTask(Messages.ImportElementsPage_CONNECTING);
                    fCurrentProgressMonitor = monitor;

                    /* Return on Cancellation */
                    if (monitor.isCanceled() || Controller.getDefault().isShuttingDown()) {
                        canceled = true;
                        return;
                    }

                    /* Open Stream */
                    in = openStream(link, monitor, INITIAL_CON_TIMEOUT, false, false, null);

                    /* Return on Cancellation */
                    if (monitor.isCanceled() || Controller.getDefault().isShuttingDown()) {
                        canceled = true;
                        return;
                    }

                    /* Try to Import */
                    try {
                        final List<? extends IEntity> types = Owl.getInterpreter().importFrom(in);

                        /* Return on Cancellation */
                        if (monitor.isCanceled() || Controller.getDefault().isShuttingDown()) {
                            canceled = true;
                            return;
                        }

                        /* Show in UI */
                        JobRunner.runInUIThread(getShell(), new Runnable() {
                            public void run() {
                                setImportedElements(types);
                                updateMessage(true);
                            }
                        });
                    }

                    /* Error Importing from File - Try Bruteforce then */
                    catch (Exception e) {
                        error = e;
                        bruteForce = true;
                    }
                }

                /* Error finding a Handler for the Link - Rethrow */
                catch (Exception e) {
                    final boolean showError[] = new boolean[] { true };

                    /* Give user a chance to log in */
                    if (e instanceof AuthenticationRequiredException && !monitor.isCanceled()
                            && !Controller.getDefault().isShuttingDown()) {
                        final Shell shell = getShell();
                        if (shell != null && !shell.isDisposed()) {
                            boolean locked = Controller.getDefault().getLoginDialogLock().tryLock();
                            if (locked) {
                                try {
                                    final AuthenticationRequiredException authEx = (AuthenticationRequiredException) e;
                                    JobRunner.runSyncedInUIThread(shell, new Runnable() {
                                        public void run() {
                                            try {

                                                /* Return on Cancelation or shutdown or deletion */
                                                if (monitor.isCanceled()
                                                        || Controller.getDefault().isShuttingDown())
                                                    return;

                                                /* Credentials might have been provided meanwhile in another dialog */
                                                try {
                                                    URI normalizedUri = URIUtils.normalizeUri(link, true);
                                                    if (Owl.getConnectionService().getAuthCredentials(normalizedUri,
                                                            authEx.getRealm()) != null) {
                                                        importFromOnlineResource(link);
                                                        showError[0] = false;
                                                        return;
                                                    }
                                                } catch (CredentialsException exe) {
                                                    Activator.getDefault().getLog().log(exe.getStatus());
                                                }

                                                /* Show Login Dialog */
                                                LoginDialog login = new LoginDialog(shell, link, authEx.getRealm());
                                                if (login.open() == Window.OK && !monitor.isCanceled()
                                                        && !Controller.getDefault().isShuttingDown()) {
                                                    importFromOnlineResource(link);
                                                    showError[0] = false;
                                                }
                                            } catch (InvocationTargetException e) {
                                                /* Ignore - Error will be handled outside already */
                                            } catch (InterruptedException e) {
                                                /* Ignore - Error will be handled outside already */
                                            }
                                        }
                                    });
                                } finally {
                                    Controller.getDefault().getLoginDialogLock().unlock();
                                }
                            }
                        }
                    }

                    /* Rethrow Exception */
                    if (showError[0])
                        throw new InvocationTargetException(e);
                } finally {

                    /* Reset Field in case of error or cancellation */
                    if (canceled || error != null)
                        fCurrentProgressMonitor = null;

                    /* Close Input Stream */
                    if (in != null) {
                        try {
                            if ((canceled || error != null) && in instanceof IAbortable)
                                ((IAbortable) in).abort();
                            else
                                in.close();
                        } catch (IOException e) {
                            throw new InvocationTargetException(e);
                        }
                    }
                }

                /* Scan remote Resource for Links and valid Feeds */
                if (bruteForce && !monitor.isCanceled() && !Controller.getDefault().isShuttingDown()) {
                    try {
                        importFromOnlineResourceBruteforce(link, monitor, false, false);
                    } catch (Exception e) {
                        throw new InvocationTargetException(e);
                    } finally {
                        fCurrentProgressMonitor = null;
                    }
                }

                /* Done */
                monitor.done();
                fCurrentProgressMonitor = null;
            }
        };

        /* Run Operation in Background and allow for Cancellation */
        getContainer().run(true, true, runnable);
    }

    private void importFromGoogleReader() throws InvocationTargetException, InterruptedException {
        IRunnableWithProgress runnable = new IRunnableWithProgress() {
            public void run(final IProgressMonitor monitor) throws InvocationTargetException {
                InputStream in = null;
                boolean canceled = false;
                Exception error = null;
                try {
                    monitor.beginTask(Messages.ImportElementsPage_IMPORT_GOOGLE_READER, IProgressMonitor.UNKNOWN);
                    monitor.subTask(Messages.ImportElementsPage_CONNECTING);
                    fCurrentProgressMonitor = monitor;

                    /* Return on Cancellation */
                    if (monitor.isCanceled() || Controller.getDefault().isShuttingDown()) {
                        canceled = true;
                        return;
                    }

                    /* Obtain Google Account Credentials */
                    ICredentials credentials = Owl.getConnectionService()
                            .getAuthCredentials(URI.create(SyncUtils.GOOGLE_LOGIN_URL), null);
                    if (credentials == null) {
                        canceled = true;
                        return;
                    }

                    /* Obtain Auth Token */
                    String googleAuthToken = SyncUtils.getGoogleAuthToken(credentials.getUsername(),
                            credentials.getPassword(), true, monitor);

                    /* Return on Cancellation */
                    if (monitor.isCanceled() || Controller.getDefault().isShuttingDown()) {
                        canceled = true;
                        return;
                    }

                    /* Open Stream */
                    in = openStream(URI.create(SyncUtils.GOOGLE_READER_OPML_URI), monitor, INITIAL_CON_TIMEOUT,
                            false, false, googleAuthToken);

                    /* Return on Cancellation */
                    if (monitor.isCanceled() || Controller.getDefault().isShuttingDown()) {
                        canceled = true;
                        return;
                    }

                    /* Try to Import */
                    try {
                        final List<IEntity> types = Owl.getInterpreter().importFrom(in);
                        enableSynchronization(types);

                        /* Return on Cancellation */
                        if (monitor.isCanceled() || Controller.getDefault().isShuttingDown()) {
                            canceled = true;
                            return;
                        }

                        /* Show in UI */
                        JobRunner.runInUIThread(getShell(), new Runnable() {
                            public void run() {
                                setImportedElements(types);
                                updateMessage(true);
                            }
                        });
                    }

                    /* Error Importing from File - Try Bruteforce then */
                    catch (Exception e) {
                        error = e;
                    }
                }

                /* Error finding a Handler for the Link - Rethrow */
                catch (Exception e) {
                    throw new InvocationTargetException(e);
                } finally {

                    /* Reset Field in case of error or cancellation */
                    if (canceled || error != null)
                        fCurrentProgressMonitor = null;

                    /* Close Input Stream */
                    if (in != null) {
                        try {
                            if ((canceled || error != null) && in instanceof IAbortable)
                                ((IAbortable) in).abort();
                            else
                                in.close();
                        } catch (IOException e) {
                            throw new InvocationTargetException(e);
                        }
                    }
                }

                /* Done */
                monitor.done();
                fCurrentProgressMonitor = null;
            }
        };

        /* Run Operation in Background and allow for Cancellation */
        getContainer().run(true, true, runnable);
    }

    private void enableSynchronization(List<IEntity> types) throws URISyntaxException {

        /* Convert to Synchronized Feeds */
        for (IEntity entity : types) {
            if (entity instanceof IFolder)
                enableSynchronization((IFolder) entity);
            else if (entity instanceof IBookMark)
                enableSynchronization((IBookMark) entity);
        }

        /* Add Special Google Reader Feeds */
        if (!types.isEmpty() && types.get(0) instanceof IFolder) {
            IModelFactory factory = Owl.getModelFactory();
            IFolder root = (IFolder) types.get(0);

            /* Shared Items */
            FeedLinkReference feedLinkRef = new FeedLinkReference(
                    URI.create(SyncUtils.GOOGLE_READER_SHARED_ITEMS_FEED));
            IBookMark bm = factory.createBookMark(null, root, feedLinkRef,
                    Messages.ImportElementsPage_GR_SHARED_ITEMS);
            setSynchronizationProperties(bm);

            /* Recommended Items */
            feedLinkRef = new FeedLinkReference(URI.create(SyncUtils.GOOGLE_READER_RECOMMENDED_ITEMS_FEED));
            bm = factory.createBookMark(null, root, feedLinkRef, Messages.ImportElementsPage_GR_RECOMMENDED_ITEMS);
            setSynchronizationProperties(bm);

            /* Notes */
            feedLinkRef = new FeedLinkReference(URI.create(SyncUtils.GOOGLE_READER_NOTES_FEED));
            bm = factory.createBookMark(null, root, feedLinkRef, Messages.ImportElementsPage_GR_NOTES);
            setSynchronizationProperties(bm);
        }
    }

    private void enableSynchronization(IFolder folder) throws URISyntaxException {
        List<IFolderChild> children = folder.getChildren();
        for (IFolderChild child : children) {
            if (child instanceof IFolder)
                enableSynchronization((IFolder) child);
            else if (child instanceof IBookMark)
                enableSynchronization((IBookMark) child);
        }
    }

    private void enableSynchronization(IBookMark bm) throws URISyntaxException {

        /* Convert the Feed Link to enable Synchronization */
        FeedLinkReference feedLinkReference = bm.getFeedLinkReference();
        bm.setFeedLinkReference(new FeedLinkReference(enableSynchronization(feedLinkReference.getLink())));

        /* Add some specific settings that improve the sync experience */
        setSynchronizationProperties(bm);
    }

    private void setSynchronizationProperties(IBookMark bm) {
        IPreferenceScope preferences = Owl.getPreferenceService().getEntityScope(bm);
        preferences.putBoolean(DefaultPreferences.BM_RELOAD_ON_STARTUP, true);
        preferences.putBoolean(DefaultPreferences.NEVER_DEL_LABELED_NEWS_STATE, false);
    }

    private URI enableSynchronization(URI uri) throws URISyntaxException {
        String scheme = URIUtils.HTTPS_SCHEME.equals(uri.getScheme()) ? SyncUtils.READER_HTTPS_SCHEME
                : SyncUtils.READER_HTTP_SCHEME;
        return new URI(scheme, uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(),
                uri.getFragment());
    }

    private void importFromKeywordSearch(final String keywords, final boolean isLocalizedSearch) throws Exception {
        IRunnableWithProgress runnable = new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor) throws InvocationTargetException {
                try {
                    monitor.beginTask(Messages.ImportElementsPage_SEARCHING_FOR_FEEDS, IProgressMonitor.UNKNOWN);
                    monitor.subTask(Messages.ImportElementsPage_CONNECTING);
                    fCurrentProgressMonitor = monitor;

                    /* Build Link for Keyword-Feed Search */
                    String linkVal = Controller.getDefault().toFeedSearchLink(keywords);

                    /* Return on Cancellation */
                    if (monitor.isCanceled() || Controller.getDefault().isShuttingDown())
                        return;

                    /* Scan remote Resource for Links and valid Feeds */
                    importFromOnlineResourceBruteforce(new URI(linkVal), monitor, true, isLocalizedSearch);
                } catch (Exception e) {
                    throw new InvocationTargetException(e);
                } finally {
                    monitor.done();
                    fCurrentProgressMonitor = null;
                }
            }
        };

        /* Run Operation in Background and allow for Cancellation */
        getContainer().run(true, true, runnable);
    }

    private void importFromOnlineResourceBruteforce(URI resourceLink, IProgressMonitor monitor,
            final boolean isKeywordSearch, boolean isLocalizedSearch) throws ConnectionException, IOException {

        /* Read Content */
        Pair<String, URI> result = readContent(resourceLink, isLocalizedSearch, monitor);
        if (result == null)
            return;

        String content = result.getFirst();
        resourceLink = result.getSecond();

        /* Add the used Link at first if the user has typed in a valid feed address */
        List<String> links = new ArrayList<String>();
        if (!isKeywordSearch)
            links.add(resourceLink.toString());

        /* Extract Links from Content */
        if (StringUtils.isSet(content))
            links.addAll(RegExUtils.extractLinksFromText(content, false));

        /* Sort List: First process likely feeds, then others */
        final String resourceLinkValue = resourceLink.toString();
        Collections.sort(links, new Comparator<String>() {
            public int compare(String o1, String o2) {

                /* Check common feed patterns in URL */
                if (URIUtils.looksLikeFeedLink(o1, false))
                    return -1;
                else if (URIUtils.looksLikeFeedLink(o2, false))
                    return 1;

                /* Check Origin from same Domain */
                if (!isKeywordSearch) {
                    if (o1.contains(resourceLinkValue))
                        return -1;
                    else if (o2.contains(resourceLinkValue))
                        return 1;
                }

                return -1;
            }
        });

        /* If this is not a keyword search, add the top most feed entry first */
        if (!isKeywordSearch) {
            URI feed = CoreUtils.findFeed(new BufferedReader(new StringReader(content)), resourceLink, monitor);
            if (feed != null) {
                String feedStr = feed.toString();
                if (links.contains(feedStr))
                    links.remove(feedStr);
                links.add(0, feedStr);
            }
        }

        /* Look for Links */
        importFromLinksBruteforce(links, monitor);
    }

    @SuppressWarnings("null")
    private void importFromLinksBruteforce(List<String> links, IProgressMonitor monitor) {

        /* Return on Cancellation */
        if (monitor.isCanceled() || Controller.getDefault().isShuttingDown())
            return;

        /* Update Task Information */
        monitor.beginTask(Messages.ImportElementsPage_SEARCHING_FOR_FEEDS, links.size());
        monitor.subTask(Messages.ImportElementsPage_FETCHING_RESULTS);

        /* A Root to add Found Bookmarks into */
        final IFolder defaultRootFolder = Owl.getModelFactory().createFolder(null, null,
                Messages.ImportElementsPage_BOOKMARKS);
        defaultRootFolder.setProperty(ITypeImporter.TEMPORARY_FOLDER, true);

        /* For Each Link of the Queue - try to interpret as Feed */
        int counter = 0;
        final List<String> foundBookMarkNames = new ArrayList<String>();
        IBookMarkDAO dao = DynamicDAO.getDAO(IBookMarkDAO.class);
        for (String feedLinkVal : links) {
            monitor.worked(1);

            InputStream in = null;
            boolean canceled = false;
            Exception error = null;
            try {
                URI feedLink = new URI(feedLinkVal);

                /* Report Progress Back To User */
                if (counter == 1)
                    monitor.subTask(Messages.ImportElementsPage_SINGLE_RESULT);
                else if (counter > 1)
                    monitor.subTask(NLS.bind(Messages.ImportElementsPage_N_RESULTS, counter));

                /* Ignore if already present in Subscriptions List (ignoring trailing slashes) */
                if (dao.exists(new FeedLinkReference(feedLink)))
                    continue;
                else if (feedLinkVal.endsWith("/") && dao //$NON-NLS-1$
                        .exists(new FeedLinkReference(new URI(feedLinkVal.substring(0, feedLinkVal.length() - 1)))))
                    continue;
                else if (!feedLinkVal.endsWith("/") //$NON-NLS-1$
                        && dao.exists(new FeedLinkReference(new URI(feedLinkVal + "/")))) //$NON-NLS-1$
                    continue;

                /* Return on Cancellation */
                if (monitor.isCanceled() || Controller.getDefault().isShuttingDown())
                    break;

                /* Open Stream to potential Feed */
                in = openStream(feedLink, monitor, FEED_CON_TIMEOUT, false, false, null);

                /* Return on Cancellation */
                if (monitor.isCanceled() || Controller.getDefault().isShuttingDown()) {
                    canceled = true;
                    break;
                }

                /* Try to interpret as Feed */
                IFeed feed = Owl.getModelFactory().createFeed(null, feedLink);
                Owl.getInterpreter().interpret(in, feed, null);
                fLoadedFeedCache.put(feedLink, feed);

                /* Return on Cancellation */
                if (monitor.isCanceled() || Controller.getDefault().isShuttingDown()) {
                    canceled = true;
                    break;
                }

                /* Add as Result if Feed contains News */
                if (!feed.getNews().isEmpty() && StringUtils.isSet(feed.getTitle())) {
                    String title = feed.getTitle();
                    boolean sameTitleExists = foundBookMarkNames.contains(title);
                    if (sameTitleExists && StringUtils.isSet(feed.getFormat()))
                        title = NLS.bind(Messages.ImportElementsPage_FEED_TITLE, title, feed.getFormat());

                    final IBookMark bookmark = Owl.getModelFactory().createBookMark(null, defaultRootFolder,
                            new FeedLinkReference(feedLink), title);
                    foundBookMarkNames.add(bookmark.getName());
                    counter++;

                    if (StringUtils.isSet(feed.getDescription()))
                        bookmark.setProperty(ITypeImporter.DESCRIPTION_KEY, feed.getDescription());

                    if (feed.getHomepage() != null)
                        bookmark.setProperty(ITypeImporter.HOMEPAGE_KEY, feed.getHomepage());

                    /* Directly show in Viewer */
                    JobRunner.runInUIThread(getShell(), new Runnable() {
                        public void run() {
                            addImportedElement(bookmark);
                        }
                    });
                }
            }

            /* Ignore Errors (likely not a Feed then) */
            catch (Exception e) {
                error = e;
            }

            /* Close Stream */
            finally {

                /* Close Input Stream */
                if (in != null) {
                    try {
                        if ((canceled || error != null) && in instanceof IAbortable)
                            ((IAbortable) in).abort();
                        else
                            in.close();
                    } catch (IOException e) {
                        /* Ignore Silently */
                    }
                }
            }
        }

        /* Inform if no feeds have been found */
        if (counter == 0) {
            JobRunner.runInUIThread(getShell(), new Runnable() {
                public void run() {
                    setMessage(Messages.ImportElementsPage_NO_FEEDS_FOUND, IMessageProvider.INFORMATION);
                }
            });
        }
    }

    private Pair<String, URI> readContent(URI link, boolean isLocalizedSearch, IProgressMonitor monitor)
            throws ConnectionException, IOException {
        InputStream in = null;
        try {

            /* Return on Cancellation */
            if (monitor.isCanceled() || Controller.getDefault().isShuttingDown())
                return null;

            /* Open Stream */
            in = openStream(link, monitor, INITIAL_CON_TIMEOUT, true, isLocalizedSearch, null);

            /* Return on Cancellation */
            if (monitor.isCanceled() || Controller.getDefault().isShuttingDown())
                return null;

            /* Read Content */
            String content = StringUtils.readString(new InputStreamReader(in));

            /* Return actual URI that was connected to (supporting redirects) */
            if (in instanceof HttpConnectionInputStream)
                return Pair.create(content, ((HttpConnectionInputStream) in).getLink());

            /* Otherwise just use input URI */
            return Pair.create(content, link);
        } finally {
            if (in instanceof IAbortable)
                ((IAbortable) in).abort(); //Abort the stream to avoid downloading the full content if error or cancelled
            else if (in != null)
                in.close();
        }
    }

    private InputStream openStream(URI link, IProgressMonitor monitor, int timeout, boolean setAcceptLanguage,
            boolean isLocalized, String authToken) throws ConnectionException {
        IProtocolHandler handler = Owl.getConnectionService().getHandler(link);

        Map<Object, Object> properties = new HashMap<Object, Object>();
        properties.put(IConnectionPropertyConstants.CON_TIMEOUT, timeout);

        /* Set Authorization Header if required */
        if (StringUtils.isSet(authToken)) {
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Authorization", SyncUtils.getGoogleAuthorizationHeader(authToken)); //$NON-NLS-1$
            properties.put(IConnectionPropertyConstants.HEADERS, headers);
        }

        /* Set the Accept-Language Header */
        if (setAcceptLanguage) {
            StringBuilder languageHeader = new StringBuilder();
            String clientLanguage = Locale.getDefault().getLanguage();

            /* Set Both English and Client Locale */
            if (!isLocalized) {
                languageHeader.append(DEFAULT_LANGUAGE);
                if (StringUtils.isSet(clientLanguage) && !DEFAULT_LANGUAGE.equals(clientLanguage))
                    languageHeader.append(",").append(clientLanguage); //$NON-NLS-1$
            }

            /* Only set Client Locale */
            else {
                if (StringUtils.isSet(clientLanguage))
                    languageHeader.append(clientLanguage);
                else
                    languageHeader.append(DEFAULT_LANGUAGE);
            }

            properties.put(IConnectionPropertyConstants.ACCEPT_LANGUAGE, languageHeader.toString());
        }

        return handler.openStream(link, monitor, properties);
    }

    /* Updates Caches and Shows Elements */
    private void setImportedElements(List<? extends IEntity> types) {
        List<IFolderChild> folderChilds = new ArrayList<IFolderChild>();
        for (IEntity type : types) {
            if (type instanceof IFolderChild)
                folderChilds.add((IFolderChild) type);
            else if (type instanceof ILabel)
                fLabels.add((ILabel) type);
            else if (type instanceof ISearchFilter)
                fFilters.add((ISearchFilter) type);
            else if (type instanceof IPreference)
                fPreferences.add((IPreference) type);
        }

        /* Re-Add Filter if necessary */
        if (!fHideExistingCheck.getSelection()) {
            fHideExistingCheck.setSelection(true);
            fViewer.addFilter(fExistingFilter);
        }

        /* Apply as Input */
        fViewer.setInput(folderChilds);
        OwlUI.setAllChecked(fViewer.getTree(), true);
        fExistingFilter.clear();
    }

    /* Adds a IFolderChild to the Viewer and updates caches */
    @SuppressWarnings("unchecked")
    private void addImportedElement(IFolderChild child) {
        Object input = fViewer.getInput();
        ((List) input).add(child);
        fViewer.add(input, child);
        fViewer.setChecked(child, true);
        fViewer.reveal(child);
    }
}