org.key_project.sed.key.ui.launch.MainLaunchConfigurationComposite.java Source code

Java tutorial

Introduction

Here is the source code for org.key_project.sed.key.ui.launch.MainLaunchConfigurationComposite.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Karlsruhe Institute of Technology, Germany
 *                    Technical University Darmstadt, Germany
 *                    Chalmers University of Technology, Sweden
 * 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:
 *    Technical University Darmstadt - initial API and implementation and/or initial documentation
 *******************************************************************************/

package org.key_project.sed.key.ui.launch;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab;
import org.eclipse.jdt.internal.debug.ui.contentassist.IJavaDebugContentAssistContext;
import org.eclipse.jdt.internal.debug.ui.contentassist.TypeContext;
import org.eclipse.jdt.internal.debug.ui.launcher.AbstractJavaMainTab;
import org.eclipse.jdt.internal.debug.ui.launcher.DebugTypeSelectionDialog;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
import org.key_project.key4eclipse.common.ui.dialog.ContractSelectionDialog;
import org.key_project.key4eclipse.common.ui.provider.ImmutableCollectionContentProvider;
import org.key_project.key4eclipse.starter.core.property.KeYResourceProperties;
import org.key_project.key4eclipse.starter.core.util.KeYUtil;
import org.key_project.sed.key.core.launch.KeYLaunchSettings;
import org.key_project.sed.key.core.util.KeySEDUtil;
import org.key_project.sed.key.ui.jdt.AllOperationsSearchEngine;
import org.key_project.sed.key.ui.jdt.AllTypesSearchEngine;
import org.key_project.sed.key.ui.util.LogUtil;
import org.key_project.util.eclipse.WorkbenchUtil;
import org.key_project.util.eclipse.swt.SWTUtil;
import org.key_project.util.eclipse.swt.viewer.FileExtensionViewerFilter;
import org.key_project.util.java.ObjectUtil;
import org.key_project.util.java.StringUtil;
import org.key_project.util.java.thread.AbstractRunnableWithProgressAndResult;
import org.key_project.util.java.thread.IRunnableWithProgressAndResult;
import org.key_project.util.jdt.JDTUtil;

import de.uka.ilkd.key.collection.ImmutableSet;
import de.uka.ilkd.key.java.Position;
import de.uka.ilkd.key.java.Services;
import de.uka.ilkd.key.java.abstraction.KeYJavaType;
import de.uka.ilkd.key.logic.op.IProgramMethod;
import de.uka.ilkd.key.proof.init.InitConfig;
import de.uka.ilkd.key.speclang.FunctionalOperationContract;
import de.uka.ilkd.key.symbolic_execution.util.KeYEnvironment;

/**
 * Contains the controls to define a project, type, method and a contract to debug.
 * @author Martin Hentschel
 */
@SuppressWarnings("restriction")
public class MainLaunchConfigurationComposite extends AbstractTabbedPropertiesAndLaunchConfigurationTabComposite {
    /**
     * Radio button to start a new debug session.
     */
    private Button newDebugSessionButton;

    /**
     * Radio button to continue an existing debug session (*.proof file).
     */
    private Button continueDebugSessionButton;

    /**
     * Shows {@link #newDebugSessionComposite} or {@link #continueDebugSessionComposite}.
     */
    private Composite newOrContinueComposite;

    /**
     * {@link StackLayout} used in {@link #newOrContinueComposite}.
     */
    private StackLayout newOrContinueCompositeLayout;

    /**
     * Contains the UI controls to start a new debug session.
     */
    private Composite newDebugSessionComposite;

    /**
     * Contains the UI controls to continue an existing debug session.
     */
    private Composite continueDebugSessionComposite;

    /**
     * Defines the proof file to continue.
     */
    private Text proofFileText;

    /**
     * Defines the project that contains the type to debug.
     */
    private Text projectText;

    /**
     * Defines the type to debug.
     */
    private Text typeText;

    /**
     * Defines the method to debug.
     */
    private Text methodText;

    /**
     * Defines to execute the complete method body.
     */
    private Button executeMethodBodyButton;

    /**
     * Defines to execute a selected range within the method body.
     */
    private Button executeMethodRangeButton;

    /**
     * The start line.
     */
    private Text startLineText;

    /**
     * The start column.
     */
    private Text startColumnText;

    /**
     * The end line.
     */
    private Text endLineText;

    /**
     * The end column.
     */
    private Text endColumnText;

    /**
     * Defines that a default contract will be generated.
     */
    private Button useGeneratedContractButton;

    /**
     * Defines that one existing contract will be used.
     */
    private Button useExistingContractButton;

    /**
     * Defines the existing contract to use.
     */
    private Text existingContractText;

    /**
     * Last loaded {@link InitConfig}.
     */
    private InitConfig initConfig;

    /**
     * The name of the project that is loaded in {@link #initConfig}.
     */
    private String initConfigProject;

    /**
     * {@link Button} to browse a contract.
     */
    private Button browseContractButton;

    /**
     * Edits the custom precondition.
     */
    private JavaSnippetSourceViewer preconditionViewer;

    /**
     * Contains the controls to define an existing contract.
     */
    private Composite existingContractComposite;

    /**
     * Shows the controls to define a precondition.
     */
    private Composite preconditionComposite;

    /**
     * Shows {@link #preconditionComposite} if {@link #useGeneratedContractButton}
     * is selected or {@link #existingContractComposite} if {@link #useExistingContractButton} is selected.
     */
    private Composite contractComposite;

    /**
     * {@link StackLayout} used in {@link #contractComposite}.
     */
    private StackLayout contractCompositeLayout;

    /**
     * Constructor.
     * @param parent The parent {@link Composite}.
     * @param style The style.
     * @param parentTab An optional {@link AbstractTabbedPropertiesAndLaunchConfigurationTab} to make this {@link Composite} editable.
     * @param widgetFactory An optional {@link TabbedPropertySheetWidgetFactory} to use.
     */
    public MainLaunchConfigurationComposite(Composite parent, int style,
            AbstractTabbedPropertiesAndLaunchConfigurationTab parentTab,
            TabbedPropertySheetWidgetFactory widgetFactory) {
        super(parent, style, parentTab);
        setLayout(new FillLayout());
        if (widgetFactory == null) {
            widgetFactory = new NoFormTabbedPropertySheetWidgetFactory();
        }
        // Content composite
        Composite composite = widgetFactory.createFlatFormComposite(this);
        composite.setLayout(new GridLayout(1, false));
        // New continue radio button composite
        Composite newOrConitnueRadioButtonComposite = widgetFactory.createComposite(composite);
        newOrConitnueRadioButtonComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        newOrConitnueRadioButtonComposite.setLayout(new GridLayout(2, false));
        newDebugSessionButton = widgetFactory.createButton(newOrConitnueRadioButtonComposite, "New debug session",
                SWT.RADIO);
        newDebugSessionButton.setEnabled(isEditable());
        newDebugSessionButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (newDebugSessionButton.getSelection()) {
                    updateShownSessionComposite();
                    updateLaunchConfigurationDialog();
                }
            }
        });
        continueDebugSessionButton = widgetFactory.createButton(newOrConitnueRadioButtonComposite,
                "Continue debug session (*." + KeYUtil.PROOF_FILE_EXTENSION + " file)", SWT.RADIO);
        continueDebugSessionButton.setEnabled(isEditable());
        continueDebugSessionButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (continueDebugSessionButton.getSelection()) {
                    updateShownSessionComposite();
                    updateLaunchConfigurationDialog();
                }
            }
        });
        // New or continue composite
        newOrContinueCompositeLayout = new StackLayout();
        newOrContinueComposite = widgetFactory.createComposite(composite);
        newOrContinueComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
        newOrContinueComposite.setLayout(newOrContinueCompositeLayout);
        // Continue debug session composite
        continueDebugSessionComposite = widgetFactory.createComposite(newOrContinueComposite);
        continueDebugSessionComposite.setLayout(new GridLayout(1, false));
        // New debug session composite
        newDebugSessionComposite = widgetFactory.createComposite(newOrContinueComposite);
        newDebugSessionComposite.setLayout(new GridLayout(1, false));
        newOrContinueCompositeLayout.topControl = newDebugSessionComposite;
        // Existing file group
        Group existingFileGroup = widgetFactory.createGroup(continueDebugSessionComposite,
                "Existing *." + KeYUtil.PROOF_FILE_EXTENSION + " file");
        existingFileGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        existingFileGroup.setLayout(new GridLayout(isEditable() ? 3 : 2, false));
        widgetFactory.createLabel(existingFileGroup, "&File");
        proofFileText = widgetFactory.createText(existingFileGroup, null);
        proofFileText.setEditable(isEditable());
        proofFileText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        proofFileText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        if (isEditable()) {
            Button browseProofFileButton = widgetFactory.createButton(existingFileGroup, "B&rowse", SWT.PUSH);
            browseProofFileButton.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    browseProofFile();
                }
            });
        }
        // Project
        Group projectGroup = widgetFactory.createGroup(newDebugSessionComposite, "Project");
        projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        projectGroup.setLayout(new GridLayout(isEditable() ? 3 : 2, false));
        widgetFactory.createLabel(projectGroup, "&Project name");
        projectText = widgetFactory.createText(projectGroup, null);
        projectText.setEditable(isEditable());
        projectText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        projectText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                unsetInitConfig();
                updateLaunchConfigurationDialog();
            }
        });
        if (isEditable()) {
            Button browseProjectButton = widgetFactory.createButton(projectGroup, "B&rowse", SWT.PUSH);
            browseProjectButton.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    browseProject();
                }
            });
        }
        // Java
        Group javaGroup = widgetFactory.createGroup(newDebugSessionComposite, "Java");
        javaGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        javaGroup.setLayout(new GridLayout(isEditable() ? 3 : 2, false));
        widgetFactory.createLabel(javaGroup, "&Type");
        typeText = widgetFactory.createText(javaGroup, null);
        typeText.setEditable(isEditable());
        typeText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        typeText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        if (isEditable()) {
            Button browseTypeButton = widgetFactory.createButton(javaGroup, "&Browse", SWT.PUSH);
            browseTypeButton.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    browseType();
                }
            });
        }
        widgetFactory.createLabel(javaGroup, "&Method");
        methodText = widgetFactory.createText(javaGroup, null);
        methodText.setEditable(isEditable());
        methodText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        methodText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                updateLaunchConfigurationDialog();
                updatePreconditionViewerComposite();
            }
        });
        if (isEditable()) {
            Button browseMethodButton = widgetFactory.createButton(javaGroup, "Bro&wse", SWT.PUSH);
            browseMethodButton.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    browseMethod();
                }
            });
        }
        widgetFactory.createLabel(javaGroup, "Range");
        Composite rangeComposite = widgetFactory.createPlainComposite(javaGroup, SWT.NONE);
        rangeComposite.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, true, true, 2, 1));
        rangeComposite.setLayout(new GridLayout(9, false));
        executeMethodBodyButton = widgetFactory.createButton(rangeComposite, "Complete method bod&y", SWT.RADIO);
        executeMethodBodyButton.setEnabled(isEditable());
        executeMethodBodyButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                updateRangeTextEditableState();
                updateLaunchConfigurationDialog();
            }
        });
        executeMethodRangeButton = widgetFactory.createButton(rangeComposite, "R&ange from", SWT.RADIO);
        executeMethodRangeButton.setEnabled(isEditable());
        executeMethodRangeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                updateRangeTextEditableState();
                updateLaunchConfigurationDialog();
            }
        });
        startLineText = widgetFactory.createText(rangeComposite, null);
        GridData fixedSizeGridData = new GridData(GridData.CENTER, GridData.CENTER, false, false);
        fixedSizeGridData.widthHint = 50;
        fixedSizeGridData.grabExcessHorizontalSpace = false;
        startLineText.setLayoutData(fixedSizeGridData);
        startLineText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        widgetFactory.createLabel(rangeComposite, ":");
        startColumnText = widgetFactory.createText(rangeComposite, null);
        startColumnText.setLayoutData(fixedSizeGridData);
        startColumnText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        widgetFactory.createLabel(rangeComposite, "to");
        endLineText = widgetFactory.createText(rangeComposite, null);
        endLineText.setLayoutData(fixedSizeGridData);
        endLineText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        widgetFactory.createLabel(rangeComposite, ":");
        endColumnText = widgetFactory.createText(rangeComposite, null);
        endColumnText.setLayoutData(fixedSizeGridData);
        endColumnText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        // Verification
        Group verificationGroup = widgetFactory.createGroup(newDebugSessionComposite, "Verification");
        verificationGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
        verificationGroup.setLayout(new GridLayout(1, false));
        Composite usedContractComposite = widgetFactory.createPlainComposite(verificationGroup, SWT.NONE);
        usedContractComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        usedContractComposite.setLayout(new GridLayout(2, false));
        useGeneratedContractButton = widgetFactory.createButton(usedContractComposite, "Use &generated contract",
                SWT.RADIO);
        useGeneratedContractButton.setEnabled(isEditable());
        useGeneratedContractButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (useGeneratedContractButton.getSelection()) {
                    updateLaunchConfigurationDialog();
                    updateShownContractComposite();
                }
            }
        });
        useExistingContractButton = widgetFactory.createButton(usedContractComposite, "Use &existing contract",
                SWT.RADIO);
        useExistingContractButton.setEnabled(isEditable());
        useExistingContractButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (useExistingContractButton.getSelection()) {
                    updateLaunchConfigurationDialog();
                    updateShownContractComposite();
                }
            }
        });

        contractCompositeLayout = new StackLayout();
        contractComposite = widgetFactory.createPlainComposite(verificationGroup, SWT.NONE);
        contractComposite.setLayout(contractCompositeLayout);
        contractComposite.setLayoutData(new GridData(GridData.FILL_BOTH));

        existingContractComposite = widgetFactory.createPlainComposite(contractComposite, SWT.NONE);
        existingContractComposite.setLayout(new GridLayout(isEditable() ? 3 : 2, false));
        widgetFactory.createLabel(existingContractComposite, "Contr&act");
        existingContractText = widgetFactory.createText(existingContractComposite, null);
        existingContractText.setEditable(isEditable());
        existingContractText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        existingContractText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        if (isEditable()) {
            browseContractButton = widgetFactory.createButton(existingContractComposite, "Brow&se", SWT.PUSH);
            browseContractButton.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    browseContract();
                }
            });
        }

        preconditionComposite = widgetFactory.createPlainComposite(contractComposite, SWT.NONE);
        GridLayout preconditionCompositeLayout = new GridLayout(2, false);
        preconditionComposite.setLayout(preconditionCompositeLayout);
        Label preconditionLabel = widgetFactory.createLabel(preconditionComposite, "Prec&ondition");
        preconditionLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false));
        int preconditionViewerCompositeStyle = SWT.BORDER;
        if (isEditable()) {
            preconditionViewerCompositeStyle |= SWT.V_SCROLL | SWT.H_SCROLL;
        }
        preconditionViewer = new JavaSnippetSourceViewer(preconditionComposite, preconditionViewerCompositeStyle);
        preconditionViewer.setEditable(isEditable());
        preconditionViewer.addPropertyChangeListener(JavaSnippetSourceViewer.PROP_TEXT,
                new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent e) {
                        updateLaunchConfigurationDialog();
                    }
                });
        if (isEditable() && preconditionViewer.getDecoractionImage() != null) {
            preconditionCompositeLayout.horizontalSpacing += preconditionViewer.getDecoractionImage()
                    .getImageData().width;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void dispose() {
        preconditionViewer.dispose();
        super.dispose();
    }

    /**
     * Updates the enabled state of the range text fields.
     */
    protected void updateRangeTextEditableState() {
        boolean executeMethodRange = isExecuteMethodRange();
        startLineText.setEditable(executeMethodRange && isEditable());
        startColumnText.setEditable(executeMethodRange && isEditable());
        endLineText.setEditable(executeMethodRange && isEditable());
        endColumnText.setEditable(executeMethodRange && isEditable());
        // Update used contract if required
        if (executeMethodRange && !useGeneratedContractButton.getSelection()) {
            useGeneratedContractButton.setSelection(true);
            useExistingContractButton.setSelection(false);
            updateShownContractComposite();
        }
        useExistingContractButton.setEnabled(!executeMethodRange && isEditable());
    }

    /**
     * Updates the shown contract.
     */
    protected void updateShownContractComposite() {
        // Update shown top control of stack layout
        boolean useExistingContract = useExistingContractButton.getSelection();
        if (useExistingContract) {
            contractCompositeLayout.topControl = existingContractComposite;
        } else {
            contractCompositeLayout.topControl = preconditionComposite;
        }
        // Layout ui
        contractComposite.layout();
    }

    /**
     * Updates the shown controls to start a new debug session or
     * to continue an existing one saved as *.proof file.
     */
    protected void updateShownSessionComposite() {
        // Update shown top control of stack layout
        boolean newDebugSession = newDebugSessionButton.getSelection();
        if (newDebugSession) {
            newOrContinueCompositeLayout.topControl = newDebugSessionComposite;
        } else {
            newOrContinueCompositeLayout.topControl = continueDebugSessionComposite;
        }
        // Layout ui
        newOrContinueComposite.layout();
    }

    /**
     * Unsets the loaded {@link InitConfig}.
     */
    protected void unsetInitConfig() {
        if (!ObjectUtil.equals(initConfigProject, projectText.getText())) {
            initConfig = null;
            initConfigProject = null;
        }
    }

    /**
     * Opens a dialog to select a contract for the specified method.
     */
    public void browseContract() {
        try {
            final IMethod method = getMethod();
            if (method != null && method.exists()) {
                IProject project = method.getResource().getProject();
                // Get source paths from class path
                final File location = KeYResourceProperties.getSourceClassPathLocation(project);
                final File bootClassPath = KeYResourceProperties.getKeYBootClassPathLocation(project);
                final List<File> classPaths = KeYResourceProperties.getKeYClassPathEntries(project);
                // Load location
                if (initConfig == null) {
                    IRunnableWithProgressAndResult<InitConfig> run = new AbstractRunnableWithProgressAndResult<InitConfig>() {
                        @Override
                        public void run(IProgressMonitor monitor)
                                throws InvocationTargetException, InterruptedException {
                            KeYEnvironment<?> environment = null;
                            try {
                                SWTUtil.checkCanceled(monitor);
                                monitor.beginTask("Receiving contracts.", IProgressMonitor.UNKNOWN);
                                SWTUtil.checkCanceled(monitor);
                                environment = KeYEnvironment.load(location, classPaths, bootClassPath);
                                SWTUtil.checkCanceled(monitor);
                                setResult(environment.getInitConfig());
                                monitor.done();
                            } catch (OperationCanceledException e) {
                                throw e;
                            } catch (Exception e) {
                                throw new InvocationTargetException(e, e.getMessage());
                            } finally {
                                if (environment != null) {
                                    environment.dispose();
                                }
                            }
                        }
                    };
                    getLaunchConfigurationDialog().run(true, false, run);
                    initConfig = run.getResult();
                    initConfigProject = project.getName();
                }
                if (initConfig != null) {
                    // Get method to proof in KeY
                    IProgramMethod pm = KeYUtil.getProgramMethod(method, initConfig.getServices().getJavaInfo());
                    if (pm != null) {
                        KeYJavaType type = pm.getContainerType();
                        ImmutableSet<FunctionalOperationContract> operationContracts = initConfig.getServices()
                                .getSpecificationRepository().getOperationContracts(type, pm);
                        // Open selection dialog
                        Services services = initConfig.getServices();
                        ContractSelectionDialog dialog = new ContractSelectionDialog(getShell(),
                                ImmutableCollectionContentProvider.getInstance(), services);
                        dialog.setTitle("Contract selection");
                        dialog.setMessage("Select a contract to debug.");
                        dialog.setInput(operationContracts);
                        FunctionalOperationContract selectedContract = KeySEDUtil.findContract(operationContracts,
                                getContractId());
                        if (selectedContract != null) {
                            dialog.setInitialSelections(new Object[] { selectedContract });
                        }
                        if (dialog.open() == ContractSelectionDialog.OK) {
                            Object result = dialog.getFirstResult();
                            if (result instanceof FunctionalOperationContract) {
                                FunctionalOperationContract foc = (FunctionalOperationContract) result;
                                existingContractText.setText(foc.getName());
                            }
                        }
                    } else {
                        throw new IllegalStateException(
                                "Can't find method \"" + JDTUtil.getQualifiedMethodLabel(method) + "\" in KeY.");
                    }
                }
            }
        } catch (Exception e) {
            LogUtil.getLogger().logError(e);
            LogUtil.getLogger().openErrorDialog(getShell(), e);
        }
    }

    /**
     * Opens a dialog to select a *.proof file.
     */
    public void browseProofFile() {
        IFile selectedFile = getProofFile();
        IFile[] files = WorkbenchUtil.openFileSelection(getShell(), "File Selection",
                "Select a *." + KeYUtil.PROOF_FILE_EXTENSION + " file.", false,
                selectedFile != null && selectedFile.exists() ? new Object[] { selectedFile } : null,
                Collections.singleton(
                        new FileExtensionViewerFilter(true, new String[] { KeYUtil.PROOF_FILE_EXTENSION })));
        if (files != null && files.length == 1) {
            proofFileText.setText(files[0].getFullPath().toString());
        }
    }

    /**
     * Returns the selected proof file.
     * @return The selected proof file.
     */
    protected IFile getProofFile() {
        try {
            String selectedText = proofFileText.getText();
            IFile selectedFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(selectedText));
            if (selectedFile != null && selectedFile.exists()) {
                return selectedFile;
            } else {
                return null;
            }
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * <p>
     * Opens the dialog to select a Java project.
     * </p>
     * <p>
     * The implementation is oriented at {@link AbstractJavaMainTab#handleProjectButtonSelected()}
     * and {@link AbstractJavaMainTab#chooseJavaProject()}.
     * </p>
     */
    public void browseProject() {
        ILabelProvider labelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
        ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), labelProvider);
        dialog.setTitle("Project Selection");
        dialog.setMessage("Select a project to constrain your search.");
        try {
            dialog.setElements(JDTUtil.getAllJavaProjects());
        } catch (JavaModelException jme) {
            LogUtil.getLogger().logError(jme);
        }
        IJavaProject javaProject = getJavaProject();
        if (javaProject != null) {
            dialog.setInitialSelections(new Object[] { javaProject });
        }
        if (dialog.open() == ElementListSelectionDialog.OK) {
            IJavaProject project = (IJavaProject) dialog.getFirstResult();
            projectText.setText(project.getElementName());
        }
    }

    /**
     * Returns the selected {@link IJavaProject} or {@code null} if no one is defined.
     * @return The selected {@link IJavaProject} or {@code null} if no one is defined.
     */
    protected IJavaProject getJavaProject() {
        String projectName = projectText.getText().trim();
        return JDTUtil.getJavaProject(projectName);
    }

    /**
     * <p>
     * Opens the dialog to select a Java type ({@link IType}).
     * </p>
     * <p>
     * The implementation is oriented at {@link JavaMainTab#handleSearchButtonSelected()}.
     * </p>
     */
    public void browseType() {
        try {
            // Search all Java types
            IJavaProject selectedProject = getJavaProject();
            IJavaElement[] elements;
            if (selectedProject != null && selectedProject.exists()) {
                elements = new IJavaElement[] { selectedProject };
            } else {
                elements = JDTUtil.getAllJavaProjects();
            }
            if (elements == null) {
                elements = new IJavaElement[] {};
            }
            IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(elements, IJavaSearchScope.SOURCES);
            AllTypesSearchEngine engine = new AllTypesSearchEngine();
            IType[] types = engine.searchTypes(getLaunchConfigurationDialog(), searchScope);
            // Open selection dialog
            DebugTypeSelectionDialog mmsd = new DebugTypeSelectionDialog(getShell(), types, "Select Type");
            IType selectedType = getType();
            if (selectedType != null) {
                mmsd.setInitialElementSelections(Collections.singletonList(selectedType));
            }
            if (mmsd.open() == DebugTypeSelectionDialog.OK) {
                Object[] results = mmsd.getResult();
                if (results != null && results.length >= 1 && results[0] instanceof IType) {
                    IType type = (IType) results[0];
                    projectText.setText(type.getJavaProject().getElementName());
                    typeText.setText(type.getFullyQualifiedName());
                }
            }
        } catch (Exception e) {
            LogUtil.getLogger().logError(e);
            LogUtil.getLogger().openErrorDialog(getShell(), e);
        }
    }

    /**
     * Returns the currently selected Java type ({@link IType}) or {@code null} if no one is selected.
     * @return The currently selected Java type ({@link IType}) or {@code null} if no one is selected.
     */
    protected IType getType() {
        try {
            String text = typeText.getText().trim();
            if (!text.isEmpty()) {
                IJavaProject project = getJavaProject();
                if (project != null) {
                    return project.findType(text);
                } else {
                    return null;
                }
            } else {
                return null;
            }
        } catch (JavaModelException e) {
            return null;
        }
    }

    /**
     * Returns the ID of the existing contract.
     * @return The ID of the existing contract.
     */
    protected String getContractId() {
        return existingContractText.getText();
    }

    /**
     * Opens a dialog to select a Java method ({@link IMethod}).
     */
    public void browseMethod() {
        try {
            // Search all Java types
            IType selectedType = getType();
            IJavaElement[] elements;
            if (selectedType != null && selectedType.exists()) {
                elements = new IJavaElement[] { selectedType };
            } else {
                elements = JDTUtil.getAllJavaProjects();
            }
            if (elements == null) {
                elements = new IJavaElement[] {};
            }
            IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(elements, IJavaSearchScope.SOURCES);
            AllOperationsSearchEngine engine = new AllOperationsSearchEngine();
            IMethod[] methods = engine.searchOperations(getLaunchConfigurationDialog(), searchScope);
            // Open selection dialog
            ILabelProvider labelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
            ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), labelProvider);
            dialog.setTitle("Method Selection");
            dialog.setMessage("Select a method to debug.");
            dialog.setElements(methods);
            IMethod oldMethod = getMethod();
            if (oldMethod != null) {
                dialog.setInitialSelections(new Object[] { oldMethod });
            }
            if (dialog.open() == ElementListSelectionDialog.OK) {
                IMethod newMethod = (IMethod) dialog.getFirstResult();
                projectText.setText(KeySEDUtil.getProjectValue(newMethod));
                typeText.setText(KeySEDUtil.getTypeValue(newMethod));
                methodText.setText(KeySEDUtil.getMethodValue(newMethod));
            }
        } catch (Exception e) {
            LogUtil.getLogger().logError(e);
            LogUtil.getLogger().openErrorDialog(getShell(), e);
        }
    }

    /**
     * Returns the selected Java method ({@link IMethod}) or {@code null}
     * if no one is selected.
     * @return The selected Java method or {@code null} if no one is selected.
     */
    protected IMethod getMethod() {
        try {
            String text = methodText.getText().trim();
            if (!text.isEmpty()) {
                IType type = getType();
                if (type != null) {
                    return JDTUtil.getElementForQualifiedMethodLabel(type.getMethods(), text);
                } else {
                    return null;
                }
            } else {
                return null;
            }
        } catch (JavaModelException e) {
            return null;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getNotValidMessage() {
        String message = null;
        if (newDebugSessionButton.getSelection()) {
            // Validate Java project
            if (message == null) {
                IJavaProject project = getJavaProject();
                if (project == null || !project.exists()) {
                    message = "No existing Java project selected.";
                }
            }
            // Validate type
            if (message == null) {
                IType type = getType();
                if (type == null || !type.exists()) {
                    message = "No existing type selected.";
                }
            }
            // Validate method
            IMethod method = null;
            if (message == null) {
                method = getMethod();
                if (method == null || !method.exists()) {
                    message = "No existing method selected.";
                }
            }
            // Validate method range
            if (message == null && isExecuteMethodRange()) {
                // Make sure that line and columns of method range are valid integers
                int startLine = 0;
                try {
                    startLine = getMethodRangeStartLine();
                } catch (NumberFormatException e) {
                    message = "Start line of method range \"" + startLineText.getText() + "\" is no valid integer.";
                }
                int startColumn = 0;
                if (message == null) {
                    try {
                        startColumn = getMethodRangeStartColumn();
                    } catch (NumberFormatException e) {
                        message = "Start column of method range \"" + startColumnText.getText()
                                + "\" is no valid integer.";
                    }
                }
                int endLine = 0;
                if (message == null) {
                    try {
                        endLine = getMethodRangeEndLine();
                    } catch (NumberFormatException e) {
                        message = "To line of method range \"" + endLineText.getText() + "\" is no valid integer.";
                    }
                }
                int endColumn = 0;
                if (message == null) {
                    try {
                        endColumn = getMethodRangeEndColumn();
                    } catch (NumberFormatException e) {
                        message = "To column of method range \"" + endColumnText.getText()
                                + "\" is no valid integer.";
                    }
                }
                // Make sure that defined start and end are in method's source range
                if (message == null) {
                    try {
                        ISourceRange methodSourceRange = method.getSourceRange();
                        Position methodStartPosition = KeYUtil.getCursorPositionForOffset(method,
                                methodSourceRange.getOffset());
                        Position methodEndPosition = KeYUtil.getCursorPositionForOffset(method,
                                methodSourceRange.getOffset() + methodSourceRange.getLength());
                        Position startPosition = new KeYUtil.CursorPosition(startLine, startColumn);
                        if (startPosition.compareTo(methodStartPosition) < 0) {
                            message = "From method range (" + startPosition + ") must be greater or equal to \""
                                    + methodStartPosition + "\".";
                        }
                        if (message == null && startPosition.compareTo(methodEndPosition) > 0) {
                            message = "From method range (" + startPosition + ") must be lower or equal to \""
                                    + methodEndPosition + "\".";
                        }
                        Position endPosition = new KeYUtil.CursorPosition(endLine, endColumn);
                        if (message == null && endPosition.compareTo(methodEndPosition) > 0) {
                            message = "To method range (" + endPosition + ") must be lower or equal to \""
                                    + methodEndPosition + "\".";
                        }
                        if (message == null && endPosition.compareTo(methodStartPosition) < 0) {
                            message = "To method range (" + endPosition + ") must be greater or equal to \""
                                    + methodStartPosition + "\".";
                        }
                        // Make sure that end is after start
                        if (message == null && startPosition.compareTo(endPosition) > 0) {
                            message = "Method range to (" + startPosition
                                    + ") must be greater or equal to method range from (" + endPosition + ").";
                        }
                    } catch (Exception e) {
                        message = e.getMessage();
                    }
                }
            }
            // Validate contract
            if (message == null) {
                if (useExistingContractButton.getSelection()) {
                    if (StringUtil.isTrimmedEmpty(getContractId())) {
                        message = "No existing contract defined.";
                    }
                }
            }
        } else {
            // Validate proof file
            String proofText = proofFileText.getText();
            if (StringUtil.isEmpty(proofText)) {
                message = "No proof file to continue defined.";
            } else {
                IFile proofFile = getProofFile();
                if (proofFile != null && proofFile.exists()) {
                    if (!KeYUtil.PROOF_FILE_EXTENSION.equals(proofFile.getFileExtension())) {
                        message = "Proof file \"" + proofFile.getFullPath().toString()
                                + "\" has not the expected file extension \"" + KeYUtil.PROOF_FILE_EXTENSION
                                + "\".";
                    }
                } else {
                    message = "Proof file \"" + proofText + "\" don't exist.";
                }
            }
        }
        return message;
    }

    /**
     * Checks if a method range should be used.
     * @return {@code true} use method range, {@code false} use complete method body.
     */
    protected boolean isExecuteMethodRange() {
        return executeMethodRangeButton.getSelection();
    }

    /**
     * Returns the start line of the method range.
     * @return The start line of the method range.
     * @throws NumberFormatException Occurred Exception
     */
    protected int getMethodRangeStartLine() throws NumberFormatException {
        return Integer.parseInt(startLineText.getText());
    }

    /**
     * Returns the start column of the method range.
     * @return The start column of the method range.
     * @throws NumberFormatException Occurred Exception
     */
    protected int getMethodRangeStartColumn() throws NumberFormatException {
        return Integer.parseInt(startColumnText.getText());
    }

    /**
     * Returns the end line of the method range.
     * @return The end line of the method range.
     * @throws NumberFormatException Occurred Exception
     */
    protected int getMethodRangeEndLine() throws NumberFormatException {
        return Integer.parseInt(endLineText.getText());
    }

    /**
     * Returns the end column of the method range.
     * @return The end column of the method range.
     * @throws NumberFormatException Occurred Exception
     */
    protected int getMethodRangeEndColumn() throws NumberFormatException {
        return Integer.parseInt(endColumnText.getText());
    }

    /**
     * Updates the precondition viewer composite by setting the
     * correct context for content assistant.
     */
    protected void updatePreconditionViewerComposite() {
        IJavaDebugContentAssistContext context = null;
        if (getType() == null) {
            context = new TypeContext(null, -1);
        } else {
            int position = -1;
            IMethod method = getMethod();
            if (method != null) {
                try {
                    Block body = JDTUtil.getMethodBody(method);
                    if (body != null) {
                        position = body.getStartPosition() + 1; // Go inside the method body directly after {
                    }
                    try {
                        if (isExecuteMethodRange()) {
                            int offset = KeYUtil.getOffsetForCursorPosition(method, getMethodRangeStartLine(),
                                    getMethodRangeStartColumn());
                            if (offset >= 0) {
                                position = offset;
                            }
                        }
                    } catch (Exception e) {
                        // Nothing to do, use method body position
                    }
                } catch (JavaModelException e) {
                    LogUtil.getLogger().logError(e);
                }
            }
            context = new TypeContext(getType(), position);
        }
        preconditionViewer.setContentAssistContext(context);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void initializeFrom(ILaunchConfiguration configuration) {
        try {
            boolean newDebugSession = KeySEDUtil.isNewDebugSession(configuration);
            newDebugSessionButton.setSelection(newDebugSession);
            continueDebugSessionButton.setSelection(!newDebugSession);
            SWTUtil.setText(proofFileText, KeySEDUtil.getFileToLoadValue(configuration));
            SWTUtil.setText(projectText, KeySEDUtil.getProjectValue(configuration));
            SWTUtil.setText(typeText, KeySEDUtil.getTypeValue(configuration));
            SWTUtil.setText(methodText, KeySEDUtil.getMethodValue(configuration));
            boolean useExistingContract = KeySEDUtil.isUseExistingContractValue(configuration);
            useGeneratedContractButton.setSelection(!useExistingContract);
            useExistingContractButton.setSelection(useExistingContract);
            SWTUtil.setText(existingContractText, KeySEDUtil.getExistingContractValue(configuration));
            preconditionViewer.setText(KeySEDUtil.getPrecondition(configuration));
            boolean executeMethodRange = KeySEDUtil.isExecuteMethodRange(configuration);
            executeMethodBodyButton.setSelection(!executeMethodRange);
            executeMethodRangeButton.setSelection(executeMethodRange);
            startLineText.setText(KeySEDUtil.getMethodRangeStartLine(configuration) + StringUtil.EMPTY_STRING);
            startColumnText.setText(KeySEDUtil.getMethodRangeStartColumn(configuration) + StringUtil.EMPTY_STRING);
            endLineText.setText(KeySEDUtil.getMethodRangeEndLine(configuration) + StringUtil.EMPTY_STRING);
            endColumnText.setText(KeySEDUtil.getMethodRangeEndColumn(configuration) + StringUtil.EMPTY_STRING);
            updateShownSessionComposite();
            updateRangeTextEditableState();
            updateShownContractComposite();
            updatePreconditionViewerComposite();
        } catch (CoreException e) {
            LogUtil.getLogger().logError(e);
        }
    }

    /**
     * Shows the content of the given {@link KeYLaunchSettings}.
     * @param settings The {@link KeYLaunchSettings} to show.
     */
    public void initializeFrom(KeYLaunchSettings settings) {
        boolean newDebugSession = settings.isNewDebugSession();
        newDebugSessionButton.setSelection(newDebugSession);
        continueDebugSessionButton.setSelection(!newDebugSession);
        SWTUtil.setText(proofFileText, settings.getProofFileToContinue());
        IMethod method = settings.getMethod();
        SWTUtil.setText(projectText, KeySEDUtil.getProjectValue(method));
        SWTUtil.setText(typeText, KeySEDUtil.getTypeValue(method));
        SWTUtil.setText(methodText, settings.getMethodSignature());
        boolean useExistingContract = settings.isUseExistingContract();
        useGeneratedContractButton.setSelection(!useExistingContract);
        useExistingContractButton.setSelection(useExistingContract);
        SWTUtil.setText(existingContractText, settings.getExistingContract());
        preconditionViewer.setText(settings.getPrecondition());
        boolean executeMethodRange = settings.isExecuteMethodRange();
        executeMethodBodyButton.setSelection(!executeMethodRange);
        executeMethodRangeButton.setSelection(executeMethodRange);
        Position startPosition = settings.getMethodRangeStart();
        if (startPosition != null) {
            startLineText.setText(startPosition.getLine() + StringUtil.EMPTY_STRING);
            startColumnText.setText(startPosition.getColumn() + StringUtil.EMPTY_STRING);
        }
        Position endPosition = settings.getMethodRangeEnd();
        if (endPosition != null) {
            endLineText.setText(endPosition.getLine() + StringUtil.EMPTY_STRING);
            endColumnText.setText(endPosition.getColumn() + StringUtil.EMPTY_STRING);
        }
        updateShownSessionComposite();
        updateRangeTextEditableState();
        updateShownContractComposite();
        updatePreconditionViewerComposite();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void performApply(ILaunchConfigurationWorkingCopy configuration) {
        configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_NEW_DEBUG_SESSION,
                newDebugSessionButton.getSelection());
        configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_FILE_TO_LOAD,
                proofFileText.getText());
        configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_PROJECT, projectText.getText());
        configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_TYPE, typeText.getText());
        configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_METHOD, methodText.getText());
        configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_USE_EXISTING_CONTRACT,
                useExistingContractButton.getSelection());
        configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_EXISTING_CONTRACT,
                existingContractText.getText());
        configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_PRECONDITION,
                preconditionViewer.getText());
        configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_EXECUTE_METHOD_RANGE,
                isExecuteMethodRange());
        try {
            configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_METHOD_RANGE_START_LINE,
                    getMethodRangeStartLine());
        } catch (NumberFormatException e) {
            configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_METHOD_RANGE_START_LINE,
                    StringUtil.EMPTY_STRING);
        }
        try {
            configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_METHOD_RANGE_START_COLUMN,
                    getMethodRangeStartColumn());
        } catch (NumberFormatException e) {
            configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_METHOD_RANGE_START_COLUMN,
                    StringUtil.EMPTY_STRING);
        }
        try {
            configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_METHOD_RANGE_END_LINE,
                    getMethodRangeEndLine());
        } catch (NumberFormatException e) {
            configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_METHOD_RANGE_END_LINE,
                    StringUtil.EMPTY_STRING);
        }
        try {
            configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_METHOD_RANGE_END_COLUMN,
                    getMethodRangeEndColumn());
        } catch (NumberFormatException e) {
            configuration.setAttribute(KeySEDUtil.LAUNCH_CONFIGURATION_TYPE_ATTRIBUTE_METHOD_RANGE_END_COLUMN,
                    StringUtil.EMPTY_STRING);
        }
    }
}