/******************************************************************************
 * Copyright (c) 2006, Intalio Inc.
 * 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:
 *     Intalio Inc. - initial API and implementation
 *******************************************************************************/

package org.eclipse.stp.bpmn.diagram.part;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.Tool;
import org.eclipse.gef.palette.PaletteContainer;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.palette.PaletteEntry;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.gef.tools.AbstractTool;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IPrimaryEditPart;
import org.eclipse.gmf.runtime.diagram.ui.services.palette.PaletteService;
import org.eclipse.gmf.runtime.diagram.ui.tools.UnspecifiedTypeConnectionTool;
import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.stp.bpmn.ActivityType;
import org.eclipse.stp.bpmn.BpmnPackage;
import org.eclipse.stp.bpmn.commands.ElementTypeEx;
import org.eclipse.stp.bpmn.commands.IElementTypeEx;
import org.eclipse.stp.bpmn.diagram.providers.BpmnElementTypes;
import org.eclipse.stp.bpmn.palette.IStickableToolEntry;
import org.eclipse.stp.bpmn.provider.BpmnEditPlugin;
import org.eclipse.stp.bpmn.tools.SelectionToolEx;
import org.eclipse.stp.bpmn.tools.UnspecifiedActivityTypeCreationToolEx;
import org.osgi.framework.Bundle;

/**
 * @generated
 */
public class BpmnPaletteFactory {

    
    /**
     * @generated
     */
    public void fillPaletteGen(PaletteRoot paletteRoot) {
        paletteRoot.add(createbpmn1Group());
        //paletteRoot.add(createEventShapes2Group());
        paletteRoot.add(createGatewayShapes3Group());
    }
    /**
     * 
     * 
     * @param paletteRoot
     * @notgenenated customizes the default entry to use the customized
     * select-tool. TODO: find a better place to do this so we don't need to
     * use introspection.
     */
    public void fillPalette(PaletteRoot paletteRoot) {
        PaletteEntry pe = null;
        for (Object paletteEntry : paletteRoot.getChildren()) {
            pe = (PaletteEntry)paletteEntry;
            if (pe.getId().equals(PaletteService.GROUP_STANDARD)) {
                break;
            }
            pe = null;
        }
        if (pe != null) {
            setupStandardPaletteEntries(pe);
        }
        paletteRoot.add(createbpmn1Group());
        paletteRoot.add(createEventShapes21Group());
        paletteRoot.add(createEventShapes22Group());
        paletteRoot.add(createEventShapes23Group());
        paletteRoot.add(createGatewayShapes3Group());

        ToolEntry toolEntry = paletteRoot.getDefaultEntry();
        SelectionToolEx.setToolClass(toolEntry, SelectionToolEx.class);
    }
    
    /**
     * @see PaletteService
     * @param pe The palette entry that contains the default selection tool,
     * the zoom and the note attachment tool. We subsitute them by BPMN tools.
     */
    private void setupStandardPaletteEntries(PaletteEntry pe) {
        
    }

    /**
     * @notgenerated
     */
    private PaletteContainer createbpmn1Group() {
        PaletteContainer paletteContainer = new PaletteDrawer("Basic BPMN Shapes");
        paletteContainer.setDescription("");
        paletteContainer.add(createTask1CreationTool());
        paletteContainer.add(createLoopingTask1CreationTool());
        paletteContainer.add(createEdgeConnection2CreationTool());
        paletteContainer.add(createMessageConnection5CreationTool());
        paletteContainer.add(createPool3CreationTool());
        paletteContainer.add(createSubProcess4CreationTool());
        paletteContainer.add(createSubProcessLooping5CreationTool());
        paletteContainer.add(createLane6CreationTool());
        return paletteContainer;
    }

    /**
     * @generated
     */
    private PaletteContainer createEventShapes2GroupGen() {
        PaletteContainer paletteContainer = new PaletteDrawer("Event Shapes");
        paletteContainer.setDescription("Event Shapes");
        paletteContainer.add(createStartEmpty1CreationTool());
        paletteContainer.add(createStartMessage2CreationTool());
        paletteContainer.add(createStartRule3CreationTool());
        paletteContainer.add(createIntermediateEmpty4CreationTool());
        paletteContainer.add(createIntermediateMessage5CreationTool());
        paletteContainer.add(createIntermediateTimer6CreationTool());
        paletteContainer.add(createIntermediateError7CreationTool());
        paletteContainer.add(createIntermediateCompensation8CreationTool());
        paletteContainer.add(createIntermediateRule9CreationTool());
        paletteContainer.add(createEndEmpty10CreationTool());
        paletteContainer.add(createEndMessage11CreationTool());
        paletteContainer.add(createEndError12CreationTool());
        paletteContainer.add(createEndCompensation13CreationTool());
        paletteContainer.add(createEndTerminate14CreationTool());
        return paletteContainer;
    }

    /**
     * @notgenerated todo: re-do this through the gmftool file.
     */
    private PaletteContainer createEventShapes21Group() {
        PaletteContainer paletteContainer1 = new PaletteDrawer("Start Events");
        paletteContainer1.setDescription("Start Events");
        paletteContainer1.add(createStartEmpty1CreationTool());
        paletteContainer1.add(createStartMessage2CreationTool());
        paletteContainer1.add(createStartRule3CreationTool());
        return paletteContainer1;
    }
    /**
     * @notgenerated todo: re-do this through the gmftool file.
     */
    private PaletteContainer createEventShapes22Group() {
        PaletteContainer paletteContainer2 = new PaletteDrawer("Intermediary Events");
        paletteContainer2.setDescription("Intermediary Events");
        paletteContainer2.add(createIntermediateEmpty4CreationTool());
        paletteContainer2.add(createIntermediateMessage5CreationTool());
        paletteContainer2.add(createIntermediateTimer6CreationTool());
        paletteContainer2.add(createIntermediateError7CreationTool());
        paletteContainer2.add(createIntermediateCompensation8CreationTool());
        paletteContainer2.add(createIntermediateRule9CreationTool());
        return paletteContainer2;
    }
    /**
     * @notgenerated todo: re-do this through the gmftool file.
     */
    private PaletteContainer createEventShapes23Group() {
        PaletteContainer paletteContainer3 = new PaletteDrawer("End Events");
        paletteContainer3.setDescription("End Events");
        paletteContainer3.add(createEndEmpty10CreationTool());
        paletteContainer3.add(createEndMessage11CreationTool());
        paletteContainer3.add(createEndError12CreationTool());
        paletteContainer3.add(createEndCompensation13CreationTool());
        paletteContainer3.add(createEndTerminate14CreationTool());
        
        return paletteContainer3;
    }

    /**
     * @generated
     */
    private PaletteContainer createGatewayShapes3Group() {
        PaletteContainer paletteContainer = new PaletteDrawer("Gateway Shapes");
        paletteContainer.setDescription("Gateway Shapes");
        paletteContainer.add(createDatabasedexcusive1CreationTool());
        paletteContainer.add(createEventbasedexclusive2CreationTool());
        paletteContainer.add(createDatabasedinclusive3CreationTool());
        paletteContainer.add(createParallel4CreationTool());
        return paletteContainer;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createTask1CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(TASK);
        ImageDescriptor largeImage = findLargeImgDescr(TASK);

        final List elementTypes = new ArrayList();
        elementTypes.add(BpmnElementTypes.Activity_2001);
        elementTypes.add(BpmnElementTypes.Activity_2003);
        ToolEntry result = new NodeToolEntry("Task", "Create a task",
                smallImage, largeImage, elementTypes);

        return result;
    }
    /**
     * @notgenerated
     */
    private ToolEntry createLoopingTask1CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(TASK_LOOPING);
        ImageDescriptor largeImage = findLargeImgDescr(TASK_LOOPING);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity1 = ElementTypeEx.wrap(
                BpmnElementTypes.Activity_2001,
                BpmnPackage.Literals.ACTIVITY__LOOPING.getName());
        IElementTypeEx activity2 = ElementTypeEx.wrap(
                BpmnElementTypes.Activity_2003,
                BpmnPackage.Literals.ACTIVITY__LOOPING.getName());
        elementTypes.add(activity1);
        elementTypes.add(activity2);
        ToolEntry result = new NodeToolEntry("Looping Task", "Create a looping task",
                smallImage, largeImage, elementTypes);

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createEdgeConnection2CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(FLOW_CONNECTOR);
        ImageDescriptor largeImage = findLargeImgDescr(FLOW_CONNECTOR);

        final List relationshipTypes = new ArrayList();
        relationshipTypes.add(BpmnElementTypes.SequenceEdge_3001);
        ToolEntry result = new LinkToolEntry("Flow Connector",
                "Create a flow connection", smallImage, largeImage,
                relationshipTypes);

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createPool3CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(POOL);
        ImageDescriptor largeImage = findLargeImgDescr(POOL);

        final List elementTypes = new ArrayList();
        elementTypes.add(BpmnElementTypes.Pool_1001);
        ToolEntry result = new NodeToolEntry("Pool", "Create a pool",
                smallImage, largeImage, elementTypes);

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createSubProcess4CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(SUB_PROCESS_EXPANDED);
        ImageDescriptor largeImage = findLargeImgDescr(SUB_PROCESS_EXPANDED);

        final List elementTypes = new ArrayList();
        elementTypes.add(BpmnElementTypes.SubProcess_2002);
        ToolEntry result = new NodeToolEntry("Sub-process",
                "Create a sub-process", smallImage, largeImage, elementTypes);

        return result;
    }
    
    /**
     * @notgenerated
     */
    private ToolEntry createSubProcessLooping5CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(SUB_PROCESS_EXPANDED_LOOPING);
        ImageDescriptor largeImage = findLargeImgDescr(SUB_PROCESS_EXPANDED_LOOPING);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                BpmnElementTypes.SubProcess_2002,
                BpmnPackage.Literals.ACTIVITY__LOOPING.getName());
        elementTypes.add(activity);
        ToolEntry result = new NodeToolEntry("Looping Sub-process",
                "Create a looping sub-process", smallImage, largeImage, elementTypes);
        return result;
    }

    /**
     * @generated
     */
    private ToolEntry createMessageConnection5CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(MESSAGE_CONNECTOR);
        ImageDescriptor largeImage = findLargeImgDescr(MESSAGE_CONNECTOR);

        final List relationshipTypes = new ArrayList();
        relationshipTypes.add(BpmnElementTypes.MessagingEdge_3002);
        ToolEntry result = new LinkToolEntry("Message Connector",
                "Create a message Connection", smallImage, largeImage,
                relationshipTypes);

        return result;
    }

    /**
     * @generated
     */
    private ToolEntry createLane6CreationTool() {
        ImageDescriptor smallImage;
        ImageDescriptor largeImage;

        smallImage = BpmnElementTypes
                .getImageDescriptor(BpmnElementTypes.Lane_2004);

        largeImage = smallImage;

        final List elementTypes = new ArrayList();
        elementTypes.add(BpmnElementTypes.Lane_2004);
        ToolEntry result = new NodeToolEntry("Lane", "Create a lane",
                smallImage, largeImage, elementTypes);

        return result;
    }
    
//    /**
//     * @return true if the tool once used should be unloaded. false it should
//     * remain loaded. It is read in the preferences.
//     * @see BpmnDiagramPreferenceInitializer
//     */
//    public static boolean getUnloadToolWhenFinished() {
//        return
//            BpmnDiagramEditorPlugin.getInstance().getPreferenceStore().getBoolean(
//                    BpmnDiagramPreferenceInitializer.PREF_UNLOAD_CREATION_TOOL);
//        
//    }

    /**
     * @notgenerated
     */
    private ToolEntry createStartEmpty1CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(START_EMPTY);
        ImageDescriptor largeImage = findLargeImgDescr(START_EMPTY);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx
                .wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.EVENT_START_EMPTY_LITERAL.getLiteral());

        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Empty Start", //$NON-NLS-1$
                "Create an empty start event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createStartMessage2CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(START_MESSAGE);
        ImageDescriptor largeImage = findLargeImgDescr(START_MESSAGE);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx
                .wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.EVENT_START_MESSAGE_LITERAL.getLiteral());
        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Message Start", //$NON-NLS-1$
                "Create a message start event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createStartRule3CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(START_RULE);
        ImageDescriptor largeImage = findLargeImgDescr(START_RULE);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.EVENT_START_RULE_LITERAL.getLiteral());

        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Rule Start", //$NON-NLS-1$
                "Create a rule start event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createIntermediateEmpty4CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(INTERMEDIATE_EMPTY);
        ImageDescriptor largeImage = findLargeImgDescr(INTERMEDIATE_EMPTY);
        
        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.EVENT_INTERMEDIATE_EMPTY_LITERAL.getLiteral());

        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Empty Intermediate", //$NON-NLS-1$
                "Create an empty intermediate event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createIntermediateMessage5CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(INTERMEDIATE_MESSAGE);
        ImageDescriptor largeImage = findLargeImgDescr(INTERMEDIATE_MESSAGE);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.EVENT_INTERMEDIATE_MESSAGE_LITERAL.getLiteral());

        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Message Intermediate", //$NON-NLS-1$
                "Create a message intermediate event", smallImage, //$NON-NLS-1$
                largeImage, elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated Specifies the secondary hint and support either activity
     *  in compartment either activity on sub-process border
     */
    private ToolEntry createIntermediateTimer6CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(INTERMEDIATE_TIMER);
        ImageDescriptor largeImage = findLargeImgDescr(INTERMEDIATE_TIMER);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                BpmnElementTypes.Activity_2001,
                ActivityType.EVENT_INTERMEDIATE_TIMER_LITERAL.getLiteral());
        IElementTypeEx activity2 = ElementTypeEx.wrap(
                BpmnElementTypes.Activity_2003,
                ActivityType.EVENT_INTERMEDIATE_TIMER_LITERAL.getLiteral());
        elementTypes.add(activity);
        elementTypes.add(activity2);

        ToolEntry result = new NodeToolEntry("Timer Intermediate", //$NON-NLS-1$
                "Create a timer intermediate event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated Specifies the secondary hint and support either activity
     *  in compartment either activity on sub-process border
     */
    private ToolEntry createIntermediateError7CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(INTERMEDIATE_ERROR);
        ImageDescriptor largeImage = findLargeImgDescr(INTERMEDIATE_ERROR);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                BpmnElementTypes.Activity_2001,
                ActivityType.EVENT_INTERMEDIATE_ERROR_LITERAL.getLiteral());
        IElementTypeEx activity2 = ElementTypeEx.wrap(
                BpmnElementTypes.Activity_2003,
                ActivityType.EVENT_INTERMEDIATE_ERROR_LITERAL.getLiteral());

        elementTypes.add(activity);
        elementTypes.add(activity2);

        ToolEntry result = new NodeToolEntry("Error Intermediate", //$NON-NLS-1$
                "Create an error intermediate event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * This tool creates either activities on the border of the sub-process or on
     * the compartment of a pool or a sub-process
     * @notgenerated
     */
    private ToolEntry createIntermediateCompensation8CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(INTERMEDIATE_COMPENSATION);
        ImageDescriptor largeImage = findLargeImgDescr(INTERMEDIATE_COMPENSATION);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                BpmnElementTypes.Activity_2001,
                ActivityType.EVENT_INTERMEDIATE_COMPENSATION_LITERAL.getLiteral());
        IElementTypeEx activity2 = ElementTypeEx.wrap(
                BpmnElementTypes.Activity_2003,
                ActivityType.EVENT_INTERMEDIATE_COMPENSATION_LITERAL.getLiteral());

        elementTypes.add(activity);
        elementTypes.add(activity2);

        ToolEntry result = new NodeToolEntry("Compensation Intermediate", //$NON-NLS-1$
                "Create a compensation intermediate event", smallImage, //$NON-NLS-1$
                largeImage, elementTypes) {
        };
        
        

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createIntermediateRule9CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(INTERMEDIATE_RULE);
        ImageDescriptor largeImage = findLargeImgDescr(INTERMEDIATE_RULE);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                    BpmnElementTypes.Activity_2001,
                    ActivityType.EVENT_INTERMEDIATE_RULE_LITERAL.getLiteral());
        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Rule Intermediate", //$NON-NLS-1$
                "Create a rule intermediate event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createEndEmpty10CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(END_EMPTY);
        ImageDescriptor largeImage = findLargeImgDescr(END_EMPTY);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.EVENT_END_EMPTY_LITERAL.getLiteral());
        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Empty End", //$NON-NLS-1$
                "Create an empty end event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createEndMessage11CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(END_MESSAGE);
        ImageDescriptor largeImage = findLargeImgDescr(END_MESSAGE);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.EVENT_END_MESSAGE_LITERAL.getLiteral());

        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Message End", //$NON-NLS-1$
                "Create a message end event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createEndError12CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(END_ERROR);
        ImageDescriptor largeImage = findLargeImgDescr(END_ERROR);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.EVENT_END_ERROR_LITERAL.getLiteral());
        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Error End", //$NON-NLS-1$
                "Create an error end event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createEndCompensation13CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(END_COMPENSATION);
        ImageDescriptor largeImage = findLargeImgDescr(END_COMPENSATION);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx
                .wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.EVENT_END_COMPENSATION_LITERAL.getLiteral());
        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Compensation End", //$NON-NLS-1$
                "Create a compensation end event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createEndTerminate14CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(END_TERMINATE);
        ImageDescriptor largeImage = findLargeImgDescr(END_TERMINATE);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.EVENT_END_TERMINATE_LITERAL.getLiteral());
        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Terminate", //$NON-NLS-1$
                "Create a terminate event", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createDatabasedexcusive1CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(GATEWAY_DATABASED_EXCLUSIVE);
        ImageDescriptor largeImage = findLargeImgDescr(GATEWAY_DATABASED_EXCLUSIVE);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                        BpmnElementTypes.Activity_2001,
                        ActivityType.GATEWAY_DATA_BASED_EXCLUSIVE_LITERAL.getLiteral());
        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Exclusive Data-based", //$NON-NLS-1$
                "Create an exclusive data-based gateway", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createEventbasedexclusive2CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(GATEWAY_EVENT_BASED);
        ImageDescriptor largeImage = findLargeImgDescr(GATEWAY_EVENT_BASED);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx
                .wrap(
                        BpmnElementTypes.Activity_2001,
                        Messages
                                .getString("BpmnPaletteFactory._UI_ActivityType_GatewayEventBasedExclusive_literal")); //$NON-NLS-1$

        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Exclusive Event-based", //$NON-NLS-1$
                "Create an exclusive event-based gateway", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createDatabasedinclusive3CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(GATEWAY_DATABASED_INCLUSIVE);
        ImageDescriptor largeImage = findLargeImgDescr(GATEWAY_DATABASED_INCLUSIVE);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                BpmnElementTypes.Activity_2001,
                ActivityType.GATEWAY_DATA_BASED_INCLUSIVE_LITERAL.getLiteral());
        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Inclusive Data-based", //$NON-NLS-1$
                "Create an inclusive data-based gateway", smallImage, largeImage, //$NON-NLS-1$
                elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createParallel4CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(GATEWAY_PARALLEL);
        ImageDescriptor largeImage = findLargeImgDescr(GATEWAY_PARALLEL);

        final List elementTypes = new ArrayList();
        IElementTypeEx activity = ElementTypeEx.wrap(
                    BpmnElementTypes.Activity_2001,
                    ActivityType.GATEWAY_PARALLEL_LITERAL.getLiteral());

        elementTypes.add(activity);

        ToolEntry result = new NodeToolEntry("Parallel", "Create a parallel gateway", //$NON-NLS-1$ //$NON-NLS-2$
                smallImage, largeImage, elementTypes) {
        };

        return result;
    }

    /**
     * @notgenerated
     */
    private ToolEntry createCreateEmptyStartEvent7CreationTool() {
        ImageDescriptor smallImage = findSmallImgDescr(START_EMPTY);
        ImageDescriptor largeImage = findLargeImgDescr(START_EMPTY);

        final List elementTypes = new ArrayList();
        elementTypes.add(ElementTypeEx.wrap(
                (IHintedType) BpmnElementTypes.Activity_2001,
                ActivityType.EVENT_START_EMPTY_LITERAL.getLiteral()));
        final List aTypes = new ArrayList();
        //		
        // aTypes.add(ActivityType.EVENT_START_EMPTY);
        // aTypes.add(ActivityType.EVENT_START_EMPTY);

        ToolEntry result = new NodeToolEntry("Empty Start", //$NON-NLS-1$
                "CreateEventStartEmpty", smallImage, largeImage, elementTypes); //$NON-NLS-1$

        return result;
    }

    /**
     * @generated
     */
    private static class NodeToolEntry extends ToolEntry implements IStickableToolEntry {

        /**
         * @generated
         */
        private final List elementTypes;
        
        private boolean _isSticky = false;
        
        /**
         * @generated
         */
        private NodeToolEntry(String title, String description,
                ImageDescriptor smallIcon, ImageDescriptor largeIcon,
                List elementTypes) {
            super(title, description, smallIcon, largeIcon);
            this.elementTypes = elementTypes;
        }
        /**
         * @return true if in sticky mode
         * where the tool created is not unloaded once it 
         * has been used.
         */
        public boolean isSticky() {
            return _isSticky;
        }
        
        /**
         * @param isSticky True if in sticky mode
         * where the tool created is not unloaded once it 
         * has been used.
         */
        public void setIsSticky(boolean isSticky) {
            _isSticky = isSticky;
        }

        /**
         * @notgenerated
         */
        public Tool createTool() {
            AbstractTool tool = new UnspecifiedActivityTypeCreationToolEx(
                    elementTypes, !_isSticky);
            tool.setProperties(getToolProperties());
            return tool;
        }
    }

    /**
     * @generated
     */
    private static class LinkToolEntry extends ToolEntry implements IStickableToolEntry {

        /**
         * @generated
         */
        private final List relationshipTypes;
        
        private boolean _isSticky = true;

        /**
         * @generated
         */
        private LinkToolEntry(String title, String description,
                ImageDescriptor smallIcon, ImageDescriptor largeIcon,
                List relationshipTypes) {
            super(title, description, smallIcon, largeIcon);
            this.relationshipTypes = relationshipTypes;
        }
        
        /**
         * @return true if in sticky mode
         * where the tool created is not unloaded once it 
         * has been used.
         */
        public boolean isSticky() {
            return _isSticky;
        }
        
        /**
         * @param isSticky True if in sticky mode
         * where the tool created is not unloaded once it 
         * has been used.
         */
        public void setIsSticky(boolean isSticky) {
            _isSticky = isSticky;
        }


        /**
         * @notgenerated
         */
        public Tool createTool() {
            Tool tool = new UnspecifiedTypeConnectionTool(relationshipTypes) {
                
                /**
                 * Creates a connection between the two select shapes. edit parts.
                 */
                protected void createConnection() {
                    if (getCurrentViewer() instanceof GraphicalViewer) {
                        super.createConnection();
                    }
                    //nothing we are probably still above the palette
                }

                
                /**
                 * Method selectAddedObject. Select the newly added connection
                 */
                protected void selectAddedObject(EditPartViewer viewer,
                        Collection objects) {
                    final List editparts = new ArrayList();
                    final EditPart[] primaryEP = new EditPart[1];
                    for (Iterator i = objects.iterator(); i.hasNext();) {
                        Object object = i.next();
                        if (object instanceof IAdaptable) {
                            Object editPart = viewer.getEditPartRegistry().get(
                                    ((IAdaptable) object)
                                            .getAdapter(View.class));

                            if (editPart instanceof IPrimaryEditPart) {
                                editparts.add(editPart);
                            }

//uncomment to put shape in direct edit mode.
//                            // Priority is to put a shape into direct edit mode.
//                            if (editPart instanceof ShapeEditPart) {
//                                primaryEP[0] = (ShapeEditPart) editPart;
//                            }
                        }
                    }

                    if (!editparts.isEmpty()) {
                        viewer.setSelection(new StructuredSelection(editparts));

                        // next section of code was removed as EDGE-1020 fix:
                        // turn off auto edit mode after
                        // connection creation
                        
                        
                        
                    }
                }
            };
            
            tool.setProperties(getToolProperties());
            ((AbstractTool)tool).setUnloadWhenFinished(!isSticky());
            return tool;
        }
    }
    
    
//constants:
    public static final String START_IMG_URI = "/org.eclipse.stp.bpmn.edit/icons/full/";
    public static final String OBJ_16 = "obj16/activities/";
    public static final String OBJ_24 = "obj24/activities/";
    public static final String OBJ_32 = "obj32/activities/";
    public static final String OBJ_48 = "obj48/activities/";
    
    public static final String END_COMPENSATION = "end_compensation";
    public static final String END_EMPTY = "end_empty";
    public static final String END_ERROR = "end_error";
    public static final String END_MESSAGE = "end_message";
    public static final String END_TERMINATE = "end_terminate";
    public static final String GATEWAY_COMPLEX = "gateway_complex";
    public static final String GATEWAY_DATABASED_EXCLUSIVE = "gateway_databased_exclusive";
    public static final String GATEWAY_DATABASED_INCLUSIVE = "gateway_databased_inclusive";
    public static final String GATEWAY_EVENT_BASED = "gateway_event_based";
    public static final String GATEWAY_PARALLEL = "gateway_parallel";
    public static final String INTERMEDIATE_CANCEL = "intermediate_cancel";
    public static final String INTERMEDIATE_COMPENSATION = "intermediate_compensation";
    public static final String INTERMEDIATE_EMPTY = "intermediate_empty";
    public static final String INTERMEDIATE_ERROR = "intermediate_error";
    public static final String INTERMEDIATE_MESSAGE = "intermediate_message";
    public static final String INTERMEDIATE_RULE = "intermediate_rule";
    public static final String INTERMEDIATE_TIMER = "intermediate_timer";
    public static final String POOL = "pool";
    public static final String START_EMPTY = "start_empty";
    public static final String START_MESSAGE = "start_message";
    public static final String START_RULE = "start_rule";
    public static final String START_TIMER = "start_timer";
    public static final String SUB_PROCESS = "sub_process";
    public static final String SUB_PROCESS_EXPANDED = "sub_process_expanded";
    public static final String SUB_PROCESS_EXPANDED_LOOPING = "sub_process_expanded_looping";
    public static final String SUB_PROCESS_LOOPING = "sub_process_looping";
    public static final String TASK = "task";    
    public static final String TASK_LOOPING = "task_looping";    

    public static final String FLOW_CONNECTOR = "flow_connector";    
    public static final String MESSAGE_CONNECTOR = "message_connector";    

    public static final String getImgPath(String objSize, String fileName, String extension) {
        return START_IMG_URI + objSize + fileName + "." + extension;
    }
    public static final ImageDescriptor findImgDescr(String objSize, String fileName) {
        return BpmnDiagramEditorPlugin.findImageDescriptor(getImgPath(objSize, fileName, "png"));
    }
    public static final ImageDescriptor findSmallImgDescr(String fileName) {
        return BpmnDiagramEditorPlugin.findImageDescriptor(getImgPath(OBJ_16, fileName, "png"));
    }
    public static final ImageDescriptor findMediumImgDescr(String fileName) {
        return BpmnDiagramEditorPlugin.findImageDescriptor(getImgPath(OBJ_24, fileName, "png"));
    }
    public static final ImageDescriptor findLargeImgDescr(String fileName) {
        return BpmnDiagramEditorPlugin.findImageDescriptor(getImgPath(OBJ_32, fileName, "png"));
    }
    
    public static final URL getSVGURL(String fileName) {
        Bundle bundle = Platform.getBundle(BpmnEditPlugin.INSTANCE.getSymbolicName());
        return FileLocator.find(bundle, new Path("icons/full/objsvg/" + fileName + ".svg"), null);
    }
}
