de.gebit.integrity.ui.contentassist.DSLProposalProvider.java Source code

Java tutorial

Introduction

Here is the source code for de.gebit.integrity.ui.contentassist.DSLProposalProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
/*
 * generated by Xtext
 */
package de.gebit.integrity.ui.contentassist;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.core.runtime.Status;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.ClassFile;
import org.eclipse.jdt.internal.core.CompilationUnit;
import org.eclipse.jface.internal.text.html.BrowserInformationControl;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.util.jdt.IJavaElementFinder;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal;
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext;
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor;
import org.eclipse.xtext.ui.shared.internal.Activator;

import com.google.inject.Inject;
import com.google.inject.Injector;

import de.gebit.integrity.dsl.ArbitraryParameterOrResultName;
import de.gebit.integrity.dsl.Call;
import de.gebit.integrity.dsl.CallDefinition;
import de.gebit.integrity.dsl.KeyValuePair;
import de.gebit.integrity.dsl.MethodReference;
import de.gebit.integrity.dsl.NamedResult;
import de.gebit.integrity.dsl.NestedObject;
import de.gebit.integrity.dsl.PackageDefinition;
import de.gebit.integrity.dsl.Parameter;
import de.gebit.integrity.dsl.ParameterName;
import de.gebit.integrity.dsl.ParameterTableHeader;
import de.gebit.integrity.dsl.ParameterTableValue;
import de.gebit.integrity.dsl.ResultName;
import de.gebit.integrity.dsl.ResultTableHeader;
import de.gebit.integrity.dsl.Suite;
import de.gebit.integrity.dsl.SuiteDefinition;
import de.gebit.integrity.dsl.SuiteParameter;
import de.gebit.integrity.dsl.TableTest;
import de.gebit.integrity.dsl.TableTestRow;
import de.gebit.integrity.dsl.Test;
import de.gebit.integrity.dsl.TestDefinition;
import de.gebit.integrity.dsl.TypedNestedObject;
import de.gebit.integrity.dsl.ValueOrEnumValueOrOperationCollection;
import de.gebit.integrity.dsl.Variable;
import de.gebit.integrity.fixtures.ArbitraryParameterEnumerator;
import de.gebit.integrity.fixtures.ArbitraryParameterEnumerator.ArbitraryParameterDefinition;
import de.gebit.integrity.fixtures.ArbitraryParameterFixture;
import de.gebit.integrity.fixtures.CustomProposalFixture;
import de.gebit.integrity.fixtures.CustomProposalProvider;
import de.gebit.integrity.fixtures.CustomProposalProvider.CustomProposalDefinition;
import de.gebit.integrity.operations.UnexecutableException;
import de.gebit.integrity.parameter.conversion.UnresolvableVariableHandling;
import de.gebit.integrity.parameter.resolving.ParameterResolver;
import de.gebit.integrity.services.DSLGrammarAccess;
import de.gebit.integrity.ui.utils.FixtureTypeWrapper;
import de.gebit.integrity.ui.utils.IntegrityDSLUIUtil;
import de.gebit.integrity.ui.utils.IntegrityDSLUIUtil.FieldDescription;
import de.gebit.integrity.ui.utils.IntegrityDSLUIUtil.ResolvedTypeName;
import de.gebit.integrity.ui.utils.JavadocUtil;
import de.gebit.integrity.utils.IntegrityDSLUtil;
import de.gebit.integrity.utils.ParamAnnotationTypeTriplet;
import de.gebit.integrity.utils.ParameterUtil.UnresolvableVariableException;
import de.gebit.integrity.utils.ResultFieldTuple;

/**
 * This class is the extension point to implement custom proposal provider, aka "content assist".
 * 
 * see http://www.eclipse.org/Xtext/documentation/latest/xtext.html#contentAssist on how to customize content assistant
 * 
 * @author Rene Schneider - initial API and implementation
 */
@SuppressWarnings("restriction")
public class DSLProposalProvider extends AbstractDSLProposalProvider {

    /**
     * The element finder.
     */
    @Inject
    private IJavaElementFinder elementFinder;

    /**
     * The grammar access.
     */
    @Inject
    private DSLGrammarAccess grammarAccess;

    /**
     * The parameter resolver to use.
     */
    @Inject
    private ParameterResolver parameterResolver;

    /**
     * The injector to use.
     */
    @Inject
    private Injector injector;

    /**
     * This is added to the proposal priorities from fixture proposal providers to ensure they're listed top in the list
     * when they return 0 as priority.
     */
    private static final int DEFAULT_PROPOSAL_BASE = 10000;

    /**
     * Creates a proposal (basically resembles the overridden method, but creates an
     * {@link IntegrityConfigurableCompletionProposal} instead, which stores the {@link ContentAssistContext}.
     */
    @Override
    protected ConfigurableCompletionProposal doCreateProposal(String aProposal, StyledString aDisplayString,
            Image anImage, int aPriority, ContentAssistContext aContext) {
        int tempReplacementOffset = aContext.getReplaceRegion().getOffset();
        int tempReplacementLength = aContext.getReplaceRegion().getLength();
        ConfigurableCompletionProposal tempResult = new IntegrityConfigurableCompletionProposal(aProposal,
                tempReplacementOffset, tempReplacementLength, aProposal.length(), anImage, aDisplayString, null,
                aContext);
        tempResult.setPriority(aPriority);
        tempResult.setMatcher(aContext.getMatcher());
        tempResult.setReplaceContextLength(aContext.getReplaceContextLength());
        return tempResult;
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeTest_Parameters(EObject aModel, Assignment anAssignment, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        super.completeTest_Parameters(aModel, anAssignment, aContext, anAcceptor);

        Test tempTest = (Test) aModel;

        completeTestParametersInternal(tempTest, aContext, anAcceptor);
        if (tempTest.getDefinition() != null
                && isArbitraryParameterFixture(tempTest.getDefinition().getFixtureMethod())) {
            completeArbitraryParameterOrResultNameInternal(aModel, aContext, anAcceptor, null, true, null, null);
        }
    }

    private void completeTestParametersInternal(Test aTest, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        TestDefinition tempTestDef = aTest.getDefinition();
        if (tempTestDef != null) {
            Set<String> tempAlreadyUsedParameters = new HashSet<String>();
            for (Parameter tempParameter : aTest.getParameters()) {
                tempAlreadyUsedParameters
                        .add(IntegrityDSLUtil.getParamNameStringFromParameterName(tempParameter.getName()));
            }
            completeParametersInternal(tempAlreadyUsedParameters, tempTestDef.getFixtureMethod(), null, true,
                    aContext, anAcceptor);
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeCall_Parameters(EObject aModel, Assignment anAssignment, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        super.completeCall_Parameters(aModel, anAssignment, aContext, anAcceptor);

        Call tempCall = (Call) aModel;

        completeCallParametersInternal(tempCall, aContext, anAcceptor);
        if (tempCall.getDefinition() != null
                && isArbitraryParameterFixture(tempCall.getDefinition().getFixtureMethod())) {
            completeArbitraryParameterOrResultNameInternal(aModel, aContext, anAcceptor, null, true, null, null);
        }
    }

    private void completeCallParametersInternal(Call aCall, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        CallDefinition tempCallDef = aCall.getDefinition();
        if (tempCallDef != null) {
            Set<String> tempAlreadyUsedParameters = new HashSet<String>();
            for (Parameter tempParameter : aCall.getParameters()) {
                tempAlreadyUsedParameters
                        .add(IntegrityDSLUtil.getParamNameStringFromParameterName(tempParameter.getName()));
            }
            completeParametersInternal(tempAlreadyUsedParameters, tempCallDef.getFixtureMethod(), null, true,
                    aContext, anAcceptor);
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void complete_NL(EObject aModel, RuleCall aRuleCall, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        super.complete_NL(aModel, aRuleCall, aContext, anAcceptor);

        // boolean tempLeadingPlusSign = aContext.getPrefix() != null && aContext.getPrefix().startsWith("+");

        if (aModel instanceof Test) {
            Test tempTest = (Test) aModel;

            if (aRuleCall == grammarAccess.getTestAccess().getNLParserRuleCall_3_0()) {
                // We're inside the parameters group
                completeTestParametersInternal(tempTest, aContext, anAcceptor);
                if (tempTest.getDefinition() != null
                        && isArbitraryParameterFixture(tempTest.getDefinition().getFixtureMethod())) {
                    completeArbitraryParameterOrResultNameInternal(aModel, aContext, anAcceptor, null, true, null,
                            null);
                }
            } else if (aRuleCall == grammarAccess.getTestAccess().getNLParserRuleCall_4_0()) {
                // We're inside the named results group
                TestDefinition tempDefinition = tempTest.getDefinition();
                if (tempDefinition != null) {
                    MethodReference tempMethodRef = tempDefinition.getFixtureMethod();
                    if (tempMethodRef != null) {
                        Set<String> tempAlreadyUsedResults = new HashSet<String>();
                        for (NamedResult tempNamedResult : tempTest.getResults()) {
                            tempAlreadyUsedResults.add(IntegrityDSLUtil
                                    .getExpectedResultNameStringFromTestResultName(tempNamedResult.getName()));
                        }

                        completeNamedResultsInternal(tempAlreadyUsedResults, tempMethodRef, null, aContext,
                                anAcceptor);
                        if (isArbitraryParameterFixture(tempMethodRef)) {
                            completeArbitraryParameterOrResultNameInternal(aModel, aContext, anAcceptor, null, true,
                                    null, null);
                        }
                    }
                }
            }
        } else if (aModel instanceof Call) {
            Call tempCall = (Call) aModel;

            if (aRuleCall == grammarAccess.getCallAccess().getNLParserRuleCall_4_0()) {
                // We're inside the parameters group
                completeCallParametersInternal(tempCall, aContext, anAcceptor);
                if (tempCall.getDefinition() != null
                        && isArbitraryParameterFixture(tempCall.getDefinition().getFixtureMethod())) {
                    completeArbitraryParameterOrResultNameInternal(aModel, aContext, anAcceptor, null, true, null,
                            null);
                }
            }
        } else if (aModel instanceof TableTest) {
            TableTest tempTest = (TableTest) aModel;

            if (aRuleCall == grammarAccess.getTableTestAccess().getNLParserRuleCall_3_0()) {
                // We're inside the parameters group
                completeTableTestParametersInternal(tempTest, aContext, anAcceptor);
            }
        } else if (aModel instanceof Parameter) {
            completeParameterValueInternal((Parameter) aModel, aContext, anAcceptor);
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeTableTest_Parameters(EObject aModel, Assignment anAssignment, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        super.completeTableTest_Parameters(aModel, anAssignment, aContext, anAcceptor);

        completeTableTestParametersInternal((TableTest) aModel, aContext, anAcceptor);
    }

    private void completeTableTestParametersInternal(TableTest aTest, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        TestDefinition tempTestDef = aTest.getDefinition();
        if (tempTestDef != null) {
            Set<String> tempAlreadyUsedParameters = new HashSet<String>();
            for (Parameter tempParameter : aTest.getParameters()) {
                tempAlreadyUsedParameters
                        .add(IntegrityDSLUtil.getParamNameStringFromParameterName(tempParameter.getName()));
            }
            for (ParameterTableHeader tempHeader : aTest.getParameterHeaders()) {
                tempAlreadyUsedParameters
                        .add(IntegrityDSLUtil.getParamNameStringFromParameterName(tempHeader.getName()));
            }

            completeParametersInternal(tempAlreadyUsedParameters, tempTestDef.getFixtureMethod(), null, true,
                    aContext, anAcceptor);
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeTableTest_ParameterHeaders(EObject aModel, Assignment anAssignment,
            ContentAssistContext aContext, ICompletionProposalAcceptor anAcceptor) {
        super.completeTableTest_ParameterHeaders(aModel, anAssignment, aContext, anAcceptor);

        completeParameterAndResultHeaderInternal(aModel, aContext, anAcceptor, true);
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeParameterTableHeader_Name(EObject aModel, Assignment anAssignment,
            ContentAssistContext aContext, ICompletionProposalAcceptor anAcceptor) {
        super.completeParameterTableHeader_Name(aModel, anAssignment, aContext, anAcceptor);

        completeParameterAndResultHeaderInternal(aModel, aContext, anAcceptor, true);
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeResultTableHeader_Name(EObject aModel, Assignment anAssignment,
            ContentAssistContext aContext, ICompletionProposalAcceptor anAcceptor) {
        super.completeResultTableHeader_Name(aModel, anAssignment, aContext, anAcceptor);

        completeParameterAndResultHeaderInternal(aModel, aContext, anAcceptor, false);
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeTableTest_ResultHeaders(EObject aModel, Assignment anAssignment,
            ContentAssistContext aContext, ICompletionProposalAcceptor anAcceptor) {
        super.completeTableTest_ResultHeaders(aModel, anAssignment, aContext, anAcceptor);

        completeParameterAndResultHeaderInternal(aModel, aContext, anAcceptor, false);
    }

    private void completeParameterAndResultHeaderInternal(Object aModel, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor, boolean anIncludeParametersFlag) {
        TableTest tempTableTest = null;
        if (aModel instanceof TableTest) {
            tempTableTest = (TableTest) aModel;
        } else {
            tempTableTest = (TableTest) NodeModelUtils.findActualSemanticObjectFor(aContext.getCurrentNode());
        }

        if (tempTableTest != null) {
            TestDefinition tempTestDef = tempTableTest.getDefinition();
            if (tempTestDef != null) {
                MethodReference tempMethod = tempTestDef.getFixtureMethod();
                if (tempMethod != null) {
                    if (anIncludeParametersFlag) {
                        Set<String> tempAlreadyUsedParameters = new HashSet<String>();
                        for (Parameter tempParameter : tempTableTest.getParameters()) {
                            tempAlreadyUsedParameters.add(
                                    IntegrityDSLUtil.getParamNameStringFromParameterName(tempParameter.getName()));
                        }
                        for (ParameterTableHeader tempParameterHeader : tempTableTest.getParameterHeaders()) {
                            tempAlreadyUsedParameters.add(IntegrityDSLUtil
                                    .getParamNameStringFromParameterName(tempParameterHeader.getName()));
                        }
                        completeParametersInternal(tempAlreadyUsedParameters, tempMethod, null, false, aContext,
                                anAcceptor);
                    }

                    Set<String> tempAlreadyUsedResults = new HashSet<String>();
                    for (ResultTableHeader tempResultHeader : tempTableTest.getResultHeaders()) {
                        tempAlreadyUsedResults.add(IntegrityDSLUtil
                                .getExpectedResultNameStringFromTestResultName(tempResultHeader.getName()));
                    }
                    completeNamedResultsInternal(tempAlreadyUsedResults, tempMethod, null, aContext, anAcceptor);

                    if (isArbitraryParameterFixture(tempMethod)) {
                        if (anIncludeParametersFlag) {
                            completeArbitraryParameterOrResultNameInternal(tempTableTest, aContext, anAcceptor,
                                    null, false, null, null);
                        }
                        completeArbitraryParameterOrResultNameInternal(tempTableTest, aContext, anAcceptor, null,
                                true, null, null);
                    }
                }
            }
        }
    }

    private void completeParametersInternal(Set<String> someAlreadyUsedParameters, MethodReference aMethod,
            String aPrefix, boolean anAddColonFlag, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {

        if (aMethod == null || aMethod.getMethod() == null) {
            return;
        }

        Map<String, String> tempJavadocMap = JavadocUtil.getMethodParamJavadoc(aMethod.getMethod(), elementFinder);

        List<ParamAnnotationTypeTriplet> tempParamList = IntegrityDSLUtil
                .getAllParamNamesFromFixtureMethod(aMethod);
        for (ParamAnnotationTypeTriplet tempParam : tempParamList) {
            if (!someAlreadyUsedParameters.contains(tempParam.getParamName())) {
                String tempJavadocDescription = tempJavadocMap != null
                        ? tempJavadocMap.get(tempParam.getJavaParamName())
                        : null;
                String tempDisplayText = null;
                if (tempJavadocDescription != null) {
                    tempDisplayText = tempParam.getParamName() + ": " + tempJavadocDescription;
                } else {
                    tempDisplayText = tempParam.getParamName();
                }
                anAcceptor.accept(createCompletionProposal(
                        (aPrefix != null ? aPrefix : "") + tempParam.getParamName() + (anAddColonFlag ? ":" : ""),
                        tempDisplayText, null, aContext));
            }
        }
    }

    private void completeNamedResultsInternal(Set<String> someAlreadyUsedResults, MethodReference aMethod,
            String aPrefix, ContentAssistContext aContext, ICompletionProposalAcceptor anAcceptor) {

        if (aMethod == null || aMethod.getMethod() == null) {
            return;
        }

        List<ResultFieldTuple> tempResultFields = IntegrityDSLUtil.getAllResultNamesFromFixtureMethod(aMethod);
        for (ResultFieldTuple tempResult : tempResultFields) {
            if (!someAlreadyUsedResults.contains(tempResult.getResultName())) {
                String tempJavadocDescription = JavadocUtil.getJvmFieldJavadoc(tempResult.getField(),
                        elementFinder);
                String tempDisplayText = tempResult.getResultName();

                ICompletionProposal tempCompletionProposal = createCompletionProposal(
                        (aPrefix != null ? aPrefix : "") + tempResult.getResultName() + " = ", tempDisplayText,
                        null, aContext);
                if (tempCompletionProposal instanceof ConfigurableCompletionProposal) {
                    if (tempJavadocDescription != null) {
                        ((ConfigurableCompletionProposal) tempCompletionProposal)
                                .setAdditionalProposalInfo(tempJavadocDescription);
                    }
                }
                anAcceptor.accept(tempCompletionProposal);
            }
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeArbitraryParameterOrResultName_Identifier(EObject aModel, Assignment anAssignment,
            ContentAssistContext aContext, ICompletionProposalAcceptor anAcceptor) {
        super.completeArbitraryParameterOrResultName_Identifier(aModel, anAssignment, aContext, anAcceptor);

        EObject tempContainer = null;
        if (aModel instanceof Parameter) {
            tempContainer = aModel.eContainer();
        } else if (aModel instanceof ArbitraryParameterOrResultName) {
            tempContainer = aModel.eContainer().eContainer();
        } else if (aModel instanceof NamedResult) {
            tempContainer = aModel.eContainer();
        } else {
            // assume the model is already the outer container we search for
            tempContainer = aModel;
        }

        completeArbitraryParameterOrResultNameInternal(tempContainer, aContext, anAcceptor, null, false, null,
                null);
    }

    private void completeArbitraryParameterOrResultNameInternal(EObject aModel, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor, Boolean anIsResultFlag, boolean aPrefixPlusSignFlag,
            List<String> aParameterPath, Set<String> someAlreadyUsedNestedParameters) {
        // We need these parameter and result maps in order to sort out proposals for parameters/results already given
        Map<String, Object> tempParameterMap = null;
        Map<String, Object> tempExpectedResultMap = null;
        MethodReference tempMethodReference = null;
        try {
            if (aModel instanceof Test) {
                Test tempTest = (Test) aModel;
                tempParameterMap = parameterResolver.createParameterMap(tempTest, true,
                        UnresolvableVariableHandling.KEEP_UNRESOLVED);
                tempExpectedResultMap = parameterResolver.createExpectedResultMap(tempTest, true);
                tempMethodReference = tempTest.getDefinition().getFixtureMethod();
            } else if (aModel instanceof TableTest) {
                TableTest tempTest = (TableTest) aModel;
                tempParameterMap = parameterResolver.createParameterMap(tempTest, null, true,
                        UnresolvableVariableHandling.KEEP_UNRESOLVED);
                tempExpectedResultMap = new LinkedHashMap<String, Object>();
                for (ResultTableHeader tempHeader : tempTest.getResultHeaders()) {
                    tempExpectedResultMap.put(
                            IntegrityDSLUtil.getExpectedResultNameStringFromTestResultName(tempHeader.getName()),
                            null);
                }
                tempMethodReference = tempTest.getDefinition().getFixtureMethod();
            } else if (aModel instanceof Call) {
                Call tempCall = (Call) aModel;
                tempParameterMap = parameterResolver.createParameterMap(tempCall.getParameters(), true,
                        UnresolvableVariableHandling.KEEP_UNRESOLVED);
                tempMethodReference = tempCall.getDefinition().getFixtureMethod();
            }
        } catch (InstantiationException exc) {
            // cannot occur, since thrown by operation execution which is not performed here
            exc.printStackTrace();
        } catch (ClassNotFoundException exc) {
            // cannot occur, since thrown by operation execution which is not performed here
            exc.printStackTrace();
        } catch (UnexecutableException exc) {
            // cannot occur, since thrown by operation execution which is not performed here
            exc.printStackTrace();
        }

        if (tempParameterMap != null && tempMethodReference != null && tempMethodReference.getType() != null) {
            try {
                IType tempJDTType = resolveJDTTypeForJvmType(tempMethodReference.getType());
                FixtureTypeWrapper tempFixtureClassWrapper = wrapType(tempJDTType);

                ArbitraryParameterEnumerator tempEnumerator = tempFixtureClassWrapper
                        .instantiateArbitraryParameterEnumerator();
                if (tempEnumerator != null) {
                    resolveVariables(tempParameterMap);

                    tempFixtureClassWrapper.convertParameterValuesToFixtureDefinedTypes(
                            tempMethodReference.getMethod().getSimpleName(), tempParameterMap, aParameterPath,
                            false);

                    if (aParameterPath == null) {
                        // This is the "classic" path, if we're directly creating a parameter. We dont need the already
                        // used nested param set here.

                        // first fetch the arbitrary parameter names...
                        List<ArbitraryParameterDefinition> tempParameterDescriptions = tempEnumerator
                                .defineArbitraryParameters(tempMethodReference.getMethod().getSimpleName(),
                                        tempParameterMap, aParameterPath);
                        if (tempParameterDescriptions != null) {
                            for (ArbitraryParameterDefinition tempParameterDescription : tempParameterDescriptions) {
                                String tempName = tempParameterDescription.getName();
                                if (!tempParameterMap.containsKey(tempName)) {
                                    String tempDescription = tempName + ": ";
                                    if (tempParameterDescription.getDescription() != null) {
                                        tempDescription += " (" + tempParameterDescription.getDescription() + ")";
                                    }
                                    String tempPrefix = aPrefixPlusSignFlag ? "+" : "";
                                    String tempSuffix = (aModel instanceof TableTest) ? ""
                                            : (tempParameterDescription.getSuffix() != null
                                                    ? tempParameterDescription.getSuffix().getText()
                                                    : ": ");
                                    if (!(aModel instanceof TableTest)
                                            && tempParameterDescription.isNestedObjectParam()) {
                                        tempSuffix += "{}";
                                    }

                                    anAcceptor.accept(createCompletionProposal(tempPrefix + tempName + tempSuffix,
                                            tempPrefix + tempDescription, null, aContext));
                                }
                            }
                        }

                        // ...then add the arbitrary result names
                        if (tempExpectedResultMap != null) {
                            List<ArbitraryParameterDefinition> tempResultDescriptions = tempEnumerator
                                    .defineArbitraryResults(tempMethodReference.getMethod().getSimpleName(),
                                            tempParameterMap, aParameterPath);
                            if (tempResultDescriptions != null) {
                                for (ArbitraryParameterDefinition tempResultDescription : tempResultDescriptions) {
                                    String tempName = tempResultDescription.getName();
                                    if (!tempExpectedResultMap.containsKey(tempName)) {
                                        String tempDescription = tempName + " = ?";
                                        if (tempResultDescription.getDescription() != null) {
                                            tempDescription += " (" + tempResultDescription.getDescription() + ")";
                                        }
                                        String tempPrefix = aPrefixPlusSignFlag ? "+" : "";
                                        String tempSuffix = tempResultDescription.getSuffix() != null
                                                ? tempResultDescription.getSuffix().getText()
                                                : " = ";
                                        if (tempResultDescription.isNestedObjectParam()) {
                                            tempSuffix += "{}";
                                        }
                                        anAcceptor
                                                .accept(createCompletionProposal(tempPrefix + tempName + tempSuffix,
                                                        tempPrefix + tempDescription, null, aContext));
                                    }
                                }
                            }
                        }
                    } else {
                        // This is the path to take if we were given a subparameter path, which means we're actually
                        // inside a nested parameter object, either used as a result or as a parameter.

                        List<ArbitraryParameterDefinition> tempParameterDescriptions = null;
                        if (Boolean.FALSE.equals(anIsResultFlag)) {
                            tempParameterDescriptions = tempEnumerator.defineArbitraryParameters(
                                    tempMethodReference.getMethod().getSimpleName(), tempParameterMap,
                                    aParameterPath);
                        } else if (Boolean.TRUE.equals(anIsResultFlag)) {
                            tempParameterDescriptions = tempEnumerator.defineArbitraryResults(
                                    tempMethodReference.getMethod().getSimpleName(), tempParameterMap,
                                    aParameterPath);
                        }

                        if (tempParameterDescriptions != null) {
                            for (ArbitraryParameterDefinition tempParameterDescription : tempParameterDescriptions) {
                                if (tempParameterDescription.hasSubdefinitions()) {
                                    ArbitraryParameterDefinition tempDefinition = tempParameterDescription
                                            .getSubdefinitionByPath(aParameterPath);
                                    if (tempDefinition != null && tempDefinition.hasSubdefinitions()) {
                                        for (ArbitraryParameterDefinition tempSubdefinition : tempDefinition
                                                .getSubdefinitions()) {
                                            String tempDescription = tempSubdefinition.getName();
                                            if (!someAlreadyUsedNestedParameters.contains(tempDescription)) {
                                                if (tempSubdefinition.getDescription() != null) {
                                                    tempDescription += ": " + tempSubdefinition.getDescription();
                                                }
                                                String tempSuffix = ": ";
                                                if (tempSubdefinition.isNestedObjectParam()) {
                                                    tempSuffix += "{}";
                                                }
                                                anAcceptor.accept(createCompletionProposal(
                                                        tempSubdefinition.getName() + tempSuffix, tempDescription,
                                                        null, aContext));
                                            }
                                        }
                                    }
                                }
                            }
                        }

                    }
                }
            } catch (JavaModelException exc) {
                exc.printStackTrace();
            } catch (UnexecutableException exc) {
                // cannot occur, since thrown by operation execution which is not performed here
                exc.printStackTrace();
            } catch (Throwable exc) {
                // This should catch anything else, especially errors in the enumerators' code
                Activator.getDefault().getLog().log(new Status(Status.ERROR, "de.gebit.integrity.dsl.ui",
                        "An exception was caught during arbitrary parameter/result enumeration", exc));
            }
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeKeyValuePair_Identifier(EObject aModel, Assignment anAssignment,
            ContentAssistContext aContext, ICompletionProposalAcceptor anAcceptor) {
        super.completeKeyValuePair_Identifier(aModel, anAssignment, aContext, anAcceptor);

        completeKeyValuePairInternal(aModel, aContext, anAcceptor);
    }

    private void completeKeyValuePairInternal(EObject aModel, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        if ((aModel instanceof NestedObject) && (aModel.eContainer() instanceof TypedNestedObject)) {
            // Once we've begun entering data into a typed nested objects' inner nested object, Xtext seems to ignore
            // the "typed" wrapper and request proposals for the inner nested object directly. This code deals with
            // that situation.
            completeKeyValuePairInternal(aModel.eContainer(), aContext, anAcceptor);
            return;
        }

        Set<String> tempAlreadyUsedKeys = new HashSet<String>();
        if (aModel instanceof NestedObject) {
            for (KeyValuePair tempPair : ((NestedObject) aModel).getAttributes()) {
                tempAlreadyUsedKeys.add(IntegrityDSLUtil.getIdentifierFromKeyValuePair(tempPair));
            }
        } else if ((aModel instanceof TypedNestedObject)
                && ((TypedNestedObject) aModel).getNestedObject() != null) {
            for (KeyValuePair tempPair : ((TypedNestedObject) aModel).getNestedObject().getAttributes()) {
                tempAlreadyUsedKeys.add(IntegrityDSLUtil.getIdentifierFromKeyValuePair(tempPair));
            }
        }

        List<String> tempParameterPath = new ArrayList<String>();
        EObject tempOwner = determineNestedObjectOwner(aModel, tempParameterPath);
        Collections.reverse(tempParameterPath);
        TypedNestedObject tempRootTypedNestedObject = determineRootTypedNestedObject(aModel, null);

        if ((tempOwner instanceof Test) || (tempOwner instanceof Call) || (tempOwner instanceof TableTest)) {
            Boolean tempIsResult = IntegrityDSLUtil.isResult(aModel);
            IType tempRootType = null;

            if (tempRootTypedNestedObject != null
                    && ((TypedNestedObject) tempRootTypedNestedObject).getType() != null) {
                // In case of typed nested objects, the root type is already known
                try {
                    tempRootType = resolveJDTTypeForJvmType(
                            ((TypedNestedObject) tempRootTypedNestedObject).getType().getType());
                } catch (JavaModelException exc) {
                    throw new RuntimeException(exc);
                }
            }

            // The following code deals with Java Bean classes used for nested param storage
            MethodReference tempMethodReference = IntegrityDSLUtil.getMethodReferenceForAction(tempOwner);
            if (tempMethodReference != null && tempMethodReference.getMethod() != null) {
                if (isArbitraryParameterFixture(tempMethodReference)) {
                    // The arbitrary stuff requires a lot of boilerplate functionality, thus we use the arbitrary param
                    // method here as well
                    completeArbitraryParameterOrResultNameInternal(tempOwner, aContext, anAcceptor, tempIsResult,
                            false, tempParameterPath, tempAlreadyUsedKeys);
                }

                if (tempParameterPath.size() > 0) {
                    if (tempRootType == null) {
                        // If the root type is not yet known from this being a typed nested object, it must be
                        // determined by looking at the fixture methods' parameter types
                        String tempParamName = tempParameterPath.get(0);

                        if (tempParamName == null) {
                            // this must be the default result
                            tempRootType = IntegrityDSLUIUtil.findTypeByName(
                                    tempMethodReference.getMethod().getReturnType().getQualifiedName());
                        } else {
                            // First, search for parameters...
                            List<ParamAnnotationTypeTriplet> tempParamList = IntegrityDSLUtil
                                    .getAllParamNamesFromFixtureMethod(tempMethodReference);
                            for (ParamAnnotationTypeTriplet tempPossibleParam : tempParamList) {
                                if (tempParamName.equals(tempPossibleParam.getParamName())) {
                                    if (tempPossibleParam != null && tempPossibleParam.getType() != null
                                            && tempPossibleParam.getType().getType() != null) {
                                        String tempQualifiedName = tempPossibleParam.getType().getType()
                                                .getQualifiedName();
                                        // The qualified name can contain brackets here if it is an array. We don't care
                                        // for arrays for the purpose of proposal providing, so we strip the array
                                        // brackets.
                                        if (tempQualifiedName.endsWith("[]")) {
                                            tempQualifiedName = tempQualifiedName.substring(0,
                                                    tempQualifiedName.length() - 2);
                                        }

                                        tempRootType = IntegrityDSLUIUtil.findTypeByName(tempQualifiedName);
                                    }
                                    break;
                                }
                            }

                            if (tempRootType == null) {
                                // If nothing was found, look into named test results
                                List<ResultFieldTuple> tempResultList = IntegrityDSLUtil
                                        .getAllResultNamesFromFixtureMethod(tempMethodReference);
                                for (ResultFieldTuple tempPossibleResult : tempResultList) {
                                    if (tempParamName.equals(tempPossibleResult.getResultName())) {
                                        if (tempPossibleResult != null && tempPossibleResult.getField() != null) {
                                            String tempQualifiedName = tempPossibleResult.getField()
                                                    .getQualifiedName();
                                            // The qualified name can contain brackets here if it is an array. We don't
                                            // care
                                            // for arrays for the purpose of proposal providing, so we strip the array
                                            // brackets.
                                            if (tempQualifiedName.endsWith("[]")) {
                                                tempQualifiedName = tempQualifiedName.substring(0,
                                                        tempQualifiedName.length() - 2);
                                            }
                                            tempRootType = IntegrityDSLUIUtil.findTypeByName(tempQualifiedName);
                                        }
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    IType tempTypeInFocus = tempRootType;
                    try {
                        if (tempTypeInFocus != null) {
                            int tempDepth = 1;
                            while (tempDepth < tempParameterPath.size()) {
                                String tempPathSegment = tempParameterPath.get(tempDepth);
                                IField tempField = IntegrityDSLUIUtil.findFieldByName(tempTypeInFocus,
                                        tempPathSegment);

                                if (tempField == null) {
                                    // we should have found another field, but couldn't!
                                    tempTypeInFocus = null;
                                } else {
                                    ResolvedTypeName tempResolvedTypeName = IntegrityDSLUIUtil
                                            .getResolvedTypeName(tempField.getTypeSignature(), tempTypeInFocus);
                                    if (tempResolvedTypeName.getGenericParameterTypes() == null) {
                                        tempTypeInFocus = IntegrityDSLUIUtil
                                                .findTypeByName(tempResolvedTypeName.getRawType());
                                    } else {
                                        // We support 1 single generic parameter only here, since that's enough to deal
                                        // with the also-supported collections like List<Integer> or Set<Boolean>
                                        tempTypeInFocus = IntegrityDSLUIUtil.findTypeByName(
                                                tempResolvedTypeName.getGenericParameterTypes()[0].getRawType());
                                    }
                                }
                                tempDepth++;
                            }

                            if (tempTypeInFocus != null) {
                                // Okay, we have reached our goal - the fields of this type are our proposals
                                for (FieldDescription tempField : IntegrityDSLUIUtil.getAllFields(tempTypeInFocus,
                                        true)) {
                                    String tempJavadocDescription = tempField.getJavaDoc();
                                    String tempDisplayText = tempField.getFieldName();

                                    if (!tempAlreadyUsedKeys.contains(tempField.getFieldName())) {
                                        ICompletionProposal tempCompletionProposal = createCompletionProposal(
                                                tempField.getFieldName() + ": ", tempDisplayText, null, aContext);

                                        if (tempCompletionProposal instanceof ConfigurableCompletionProposal) {
                                            if (tempJavadocDescription != null) {
                                                ((ConfigurableCompletionProposal) tempCompletionProposal)
                                                        .setAdditionalProposalInfo(tempJavadocDescription);
                                            }
                                        }
                                        anAcceptor.accept(tempCompletionProposal);
                                    }
                                }
                            }
                        }
                    } catch (JavaModelException exc) {
                        // TODO Auto-generated catch block
                        exc.printStackTrace();
                    }
                }
            }
        }
    }

    private EObject determineNestedObjectOwner(EObject aNestedObject, List<String> aParameterPath) {
        EObject tempParent = aNestedObject.eContainer();
        if (tempParent instanceof KeyValuePair) {
            String tempIdentifier = IntegrityDSLUtil.getIdentifierFromKeyValuePair((KeyValuePair) tempParent);
            aParameterPath.add(tempIdentifier);
            if (tempParent.eContainer() instanceof NestedObject) {
                return determineNestedObjectOwner((NestedObject) tempParent.eContainer(), aParameterPath);
            }
        } else if (tempParent instanceof Parameter) {
            aParameterPath
                    .add(IntegrityDSLUtil.getParamNameStringFromParameterName(((Parameter) tempParent).getName()));
        } else if (tempParent instanceof NamedResult) {
            aParameterPath.add(IntegrityDSLUtil
                    .getExpectedResultNameStringFromTestResultName(((NamedResult) tempParent).getName()));
        } else if (tempParent instanceof ParameterTableValue) {
            // in case of tabletests we need to trace the table cell to its header
            EObject tempHeaderCell = IntegrityDSLUtil.getTableHeaderForTableCell((ParameterTableValue) tempParent);
            if (tempHeaderCell instanceof ParameterTableHeader) {
                aParameterPath.add(IntegrityDSLUtil
                        .getParamNameStringFromParameterName(((ParameterTableHeader) tempHeaderCell).getName()));
            } else if (tempHeaderCell instanceof ResultTableHeader) {
                aParameterPath.add(IntegrityDSLUtil.getExpectedResultNameStringFromTestResultName(
                        ((ResultTableHeader) tempHeaderCell).getName()));
            } else if (tempHeaderCell instanceof TableTest) {
                // default result column case
                aParameterPath.add(null);
            }
        } else if (tempParent instanceof Test) {
            if (aNestedObject == ((Test) tempParent).getResult()) {
                // default result case
                aParameterPath.add(null);
            }
            return tempParent;
        } else if (tempParent instanceof Call) {
            return tempParent;
        } else if (tempParent instanceof TableTest) {
            return tempParent;
        } else {
            if ((tempParent instanceof SuiteDefinition) || (tempParent instanceof PackageDefinition)) {
                return null;
            }
        }

        return determineNestedObjectOwner(tempParent, aParameterPath);
    }

    private TypedNestedObject determineRootTypedNestedObject(EObject aNestedObject, TypedNestedObject aLastFound) {
        EObject tempParent = aNestedObject.eContainer();

        if (tempParent == null) {
            return aLastFound;
        } else {
            if (aNestedObject instanceof TypedNestedObject) {
                return determineRootTypedNestedObject(tempParent, (TypedNestedObject) aNestedObject);
            } else {
                return determineRootTypedNestedObject(tempParent, aLastFound);
            }
        }
    }

    /**
     * Resolves all variable values in the given map.
     * 
     * @param aParameterMap
     */
    private void resolveVariables(Map<String, Object> aParameterMap) {
        for (Entry<String, Object> tempEntry : aParameterMap.entrySet()) {
            if (tempEntry.getValue() instanceof Variable) {
                tempEntry.setValue(parameterResolver.resolveStatically((Variable) tempEntry.getValue(), null));
            }
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeTest_Result(EObject aModel, Assignment anAssignment, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        super.completeTest_Result(aModel, anAssignment, aContext, anAcceptor);

        if (aModel instanceof Test) {
            Test tempTest = (Test) aModel;
            MethodReference tempMethod = tempTest.getDefinition().getFixtureMethod();
            List<Parameter> tempAllParameters = tempTest.getParameters();

            if (tempMethod != null) {

                if (isCustomProposalFixture(tempMethod)) {
                    try {
                        IType tempJDTType = resolveJDTTypeForJvmType(tempMethod.getType());
                        FixtureTypeWrapper tempFixtureClassWrapper = wrapType(tempJDTType);

                        Map<String, Object> tempParamMap = parameterResolver.createParameterMap(tempAllParameters,
                                true, UnresolvableVariableHandling.KEEP_UNRESOLVED);

                        Object tempResultValue = tempFixtureClassWrapper.convertResultValueToFixtureDefinedType(
                                tempMethod.getMethod().getSimpleName(), null, tempTest.getResult());

                        completeCustomProposalResultValuesInternal(null, tempMethod, tempResultValue, tempParamMap,
                                null, aContext, anAcceptor);
                    } catch (JavaModelException exc) {
                        exc.printStackTrace();
                    } catch (ClassNotFoundException exc) {
                        exc.printStackTrace();
                    } catch (UnexecutableException exc) {
                        exc.printStackTrace();
                    } catch (InstantiationException exc) {
                        exc.printStackTrace();
                    }
                }

                if (isArbitraryParameterFixture(tempMethod)) {
                    completeArbitraryParameterOrResultNameInternal(aModel, aContext, anAcceptor, null, false, null,
                            null);
                }
            }
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeNamedResult_Value(EObject aModel, Assignment anAssignment, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        super.completeNamedResult_Value(aModel, anAssignment, aContext, anAcceptor);

        if (aModel instanceof NamedResult) {
            NamedResult tempResult = (NamedResult) aModel;
            Test tempTest = (Test) tempResult.eContainer();
            MethodReference tempMethod = tempTest.getDefinition().getFixtureMethod();
            List<Parameter> tempAllParameters = tempTest.getParameters();

            if (tempMethod != null && isCustomProposalFixture(tempMethod)) {
                try {
                    IType tempJDTType = resolveJDTTypeForJvmType(tempMethod.getType());
                    FixtureTypeWrapper tempFixtureClassWrapper = wrapType(tempJDTType);

                    Map<String, Object> tempParamMap = parameterResolver.createParameterMap(tempAllParameters, true,
                            UnresolvableVariableHandling.KEEP_UNRESOLVED);

                    Object tempResultValue = tempFixtureClassWrapper.convertResultValueToFixtureDefinedType(
                            tempMethod.getMethod().getSimpleName(), tempResult.getName(), tempResult.getValue());

                    completeCustomProposalResultValuesInternal(tempResult.getName(), tempMethod, tempResultValue,
                            tempParamMap, null, aContext, anAcceptor);
                } catch (JavaModelException exc) {
                    exc.printStackTrace();
                } catch (ClassNotFoundException exc) {
                    // cannot occur, since thrown by operation execution which is not performed here
                    exc.printStackTrace();
                } catch (UnexecutableException exc) {
                    // cannot occur, since thrown by operation execution which is not performed here
                    exc.printStackTrace();
                } catch (InstantiationException exc) {
                    // cannot occur, since thrown by operation execution which is not performed here
                    exc.printStackTrace();
                }
            }
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeParameter_Value(EObject aModel, Assignment anAssignment, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        super.completeParameter_Value(aModel, anAssignment, aContext, anAcceptor);

        if (aModel instanceof Parameter) {
            completeParameterValueInternal((Parameter) aModel, aContext, anAcceptor);
        }
    }

    private void completeParameterValueInternal(Parameter aParameter, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        Parameter tempParam = (Parameter) aParameter;

        MethodReference tempMethod = null;
        List<Parameter> tempAllParameters = null;
        if (tempParam.eContainer() instanceof Test) {
            Test tempTest = (Test) tempParam.eContainer();
            tempMethod = tempTest.getDefinition().getFixtureMethod();
            tempAllParameters = tempTest.getParameters();
        } else if (tempParam.eContainer() instanceof Call) {
            Call tempCall = (Call) tempParam.eContainer();
            tempMethod = tempCall.getDefinition().getFixtureMethod();
            tempAllParameters = tempCall.getParameters();
        } else if (tempParam.eContainer() instanceof TableTest) {
            TableTest tempTableTest = (TableTest) tempParam.eContainer();
            tempMethod = tempTableTest.getDefinition().getFixtureMethod();
            tempAllParameters = tempTableTest.getParameters();
        }

        if (tempMethod != null && isCustomProposalFixture(tempMethod)) {
            try {
                Map<String, Object> tempParamMap = parameterResolver.createParameterMap(tempAllParameters, true,
                        UnresolvableVariableHandling.KEEP_UNRESOLVED);
                completeParameterValuesInternal(tempParam.getName(), tempMethod, tempParamMap, null, aContext,
                        anAcceptor);
            } catch (InstantiationException exc) {
                // cannot occur, since thrown by operation execution which is not performed here
                exc.printStackTrace();
            } catch (ClassNotFoundException exc) {
                // cannot occur, since thrown by operation execution which is not performed here
                exc.printStackTrace();
            } catch (UnexecutableException exc) {
                // cannot occur, since thrown by operation execution which is not performed here
                exc.printStackTrace();
            }
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeTableTestRow_Values(EObject aModel, Assignment anAssignment, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        super.completeTableTestRow_Values(aModel, anAssignment, aContext, anAcceptor);

        if (aModel instanceof TableTestRow) {
            TableTestRow tempRow = (TableTestRow) aModel;
            TableTest tempTest = (TableTest) tempRow.eContainer();
            MethodReference tempMethod = tempTest.getDefinition().getFixtureMethod();

            if (tempMethod != null && isCustomProposalFixture(tempMethod)) {
                EObject tempSemanticObject = NodeModelUtils.findActualSemanticObjectFor(aContext.getCurrentNode());
                int tempColumn = -1;
                if (tempSemanticObject instanceof ParameterTableValue) {
                    // we're inside an empty parameter table value
                    tempColumn = tempRow.getValues().indexOf(tempSemanticObject);

                } else if (tempSemanticObject == tempRow) {
                    if ("".equals(aContext.getPrefix())) {
                        // we're at the last (still opened and not really started) parameter table value
                        tempColumn = tempRow.getValues().size();
                    } else {
                        // we're at the last parameter table value
                        tempColumn = tempRow.getValues().size() - 1;
                    }
                }

                if (tempColumn >= 0) {
                    if (tempColumn < tempTest.getParameterHeaders().size()) {
                        try {
                            Map<String, Object> tempParamMap = parameterResolver.createParameterMap(tempTest,
                                    tempRow, true, UnresolvableVariableHandling.KEEP_UNRESOLVED);

                            completeParameterValuesInternal(
                                    tempTest.getParameterHeaders().get(tempColumn).getName(), tempMethod,
                                    tempParamMap, null, aContext, anAcceptor);
                        } catch (InstantiationException exc) {
                            // cannot occur, since thrown by operation execution which is not performed here
                            exc.printStackTrace();
                        } catch (ClassNotFoundException exc) {
                            // cannot occur, since thrown by operation execution which is not performed here
                            exc.printStackTrace();
                        } catch (UnexecutableException exc) {
                            // cannot occur, since thrown by operation execution which is not performed here
                            exc.printStackTrace();
                        }
                    } else {
                        // we might be in the range of the result columns
                        int tempResultColumn = tempColumn - tempTest.getParameterHeaders().size();
                        boolean tempDefaultResultExists = tempTest.getDefaultResultColumn() != null;
                        if (tempResultColumn >= 0 && tempResultColumn < tempTest.getResultHeaders().size()
                                + (tempDefaultResultExists ? 1 : 0)) {
                            try {
                                ResultName tempResultName = null;
                                if (tempResultColumn < tempTest.getResultHeaders().size()) {
                                    tempResultName = tempTest.getResultHeaders().get(tempResultColumn).getName();
                                }

                                ValueOrEnumValueOrOperationCollection tempResultValue = null;
                                if (tempColumn < tempRow.getValues().size()) {
                                    tempResultValue = tempRow.getValues().get(tempColumn).getValue();
                                }
                                Object tempConvertedResultValue = null;
                                if (tempResultValue != null) {
                                    IType tempJDTType = resolveJDTTypeForJvmType(tempMethod.getType());
                                    FixtureTypeWrapper tempFixtureClassWrapper = wrapType(tempJDTType);

                                    tempConvertedResultValue = tempFixtureClassWrapper
                                            .convertResultValueToFixtureDefinedType(
                                                    tempMethod.getMethod().getSimpleName(), tempResultName,
                                                    tempResultValue);

                                }

                                Map<String, Object> tempParamMap = parameterResolver.createParameterMap(tempTest,
                                        tempRow, true, UnresolvableVariableHandling.KEEP_UNRESOLVED);

                                completeCustomProposalResultValuesInternal(tempResultName, tempMethod,
                                        tempConvertedResultValue, tempParamMap, null, aContext, anAcceptor);
                            } catch (JavaModelException exc) {
                                exc.printStackTrace();
                            } catch (ClassNotFoundException exc) {
                                // cannot occur, since thrown by operation execution which is not performed here
                                exc.printStackTrace();
                            } catch (UnexecutableException exc) {
                                // cannot occur, since thrown by operation execution which is not performed here
                                exc.printStackTrace();
                            } catch (InstantiationException exc) {
                                // cannot occur, since thrown by operation execution which is not performed here
                                exc.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeParameterTableValue_Value(EObject aModel, Assignment anAssignment,
            ContentAssistContext aContext, ICompletionProposalAcceptor anAcceptor) {
        super.completeParameterTableValue_Value(aModel, anAssignment, aContext, anAcceptor);

        if (aModel instanceof ParameterTableValue) {
            ParameterTableValue tempParam = (ParameterTableValue) aModel;

            TableTestRow tempRow = (TableTestRow) tempParam.eContainer();
            TableTest tempTest = (TableTest) tempRow.eContainer();
            MethodReference tempMethod = tempTest.getDefinition().getFixtureMethod();

            if (tempMethod != null) {
                int tempColumn = tempRow.getValues().indexOf(tempParam);
                if (tempColumn >= 0 && tempColumn < tempTest.getParameterHeaders().size()) {
                    try {
                        Map<String, Object> tempParamMap = parameterResolver.createParameterMap(tempTest, tempRow,
                                true, UnresolvableVariableHandling.KEEP_UNRESOLVED);

                        completeParameterValuesInternal(tempTest.getParameterHeaders().get(tempColumn).getName(),
                                tempMethod, tempParamMap, null, aContext, anAcceptor);
                    } catch (InstantiationException exc) {
                        // cannot occur, since thrown by operation execution which is not performed here
                        exc.printStackTrace();
                    } catch (ClassNotFoundException exc) {
                        // cannot occur, since thrown by operation execution which is not performed here
                        exc.printStackTrace();
                    } catch (UnexecutableException exc) {
                        // cannot occur, since thrown by operation execution which is not performed here
                        exc.printStackTrace();
                    }
                }
            }
        }
    }

    @Override
    // SUPPRESS CHECKSTYLE MethodName
    public void completeSuiteParameter_Name(EObject aModel, Assignment anAssignment,
            final ContentAssistContext aContext, final ICompletionProposalAcceptor anAcceptor) {
        // filter out everything except suite parameters of the suite that is currently being called
        super.completeSuiteParameter_Name(aModel, anAssignment, aContext, new ICompletionProposalAcceptor() {

            @Override
            public void accept(ICompletionProposal aProposal) {
                if (aContext.getCurrentModel() instanceof Suite) {
                    Suite tempCurrentSuiteCall = (Suite) aContext.getCurrentModel();
                    SuiteDefinition tempCurrentSuiteDef = (tempCurrentSuiteCall).getDefinition();
                    if (aProposal instanceof IntegrityConfigurableCompletionProposal) {
                        SuiteDefinition tempSuiteDef = ((IntegrityConfigurableCompletionProposal) aProposal)
                                .getSuiteDefiningProposedParameter();
                        if (tempSuiteDef == tempCurrentSuiteDef) {
                            ConfigurableCompletionProposal tempProposal = (ConfigurableCompletionProposal) aProposal;

                            // now filter out the ones that are already present in the call
                            boolean tempAlreadyUsed = false;
                            for (SuiteParameter tempAlreadyUsedParam : tempCurrentSuiteCall.getParameters()) {
                                if (tempProposal.getReplacementString()
                                        .equals(tempAlreadyUsedParam.getName().getName())) {
                                    tempAlreadyUsed = true;
                                    break;
                                }
                            }
                            if (!tempAlreadyUsed) {
                                tempProposal.setReplacementString(tempProposal.getReplacementString() + ": ");

                                // For some reason, Xtext doesn't get the cursor positions quite right on these
                                // proposals, so we calculate them manually here
                                tempProposal.setCursorPosition(tempProposal.getReplacementString().length());

                                anAcceptor.accept(aProposal);
                            }
                        }
                    }
                }
            }

            @Override
            public boolean canAcceptMoreProposals() {
                return anAcceptor.canAcceptMoreProposals();
            }

        });
    }

    private boolean isCustomProposalFixture(MethodReference aMethod) {
        if (aMethod == null) {
            return false;
        }

        for (JvmTypeReference tempRef : aMethod.getMethod().getDeclaringType().getSuperTypes()) {
            if (tempRef.getQualifiedName().equals(CustomProposalFixture.class.getName())) {
                return true;
            }
        }

        return false;
    }

    private boolean isArbitraryParameterFixture(MethodReference aMethod) {
        if (aMethod == null) {
            return false;
        }

        for (JvmTypeReference tempRef : aMethod.getMethod().getDeclaringType().getSuperTypes()) {
            if (tempRef.getQualifiedName().equals(ArbitraryParameterFixture.class.getName())) {
                return true;
            }
        }

        return false;
    }

    private void completeParameterValuesInternal(ParameterName aParameter, MethodReference aMethod,
            Map<String, Object> aParamMap, List<String> aParameterPath, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        try {
            IType tempJDTType = resolveJDTTypeForJvmType(aMethod.getType());
            FixtureTypeWrapper tempFixtureClassWrapper = wrapType(tempJDTType);

            CustomProposalProvider tempProposalProvider = tempFixtureClassWrapper
                    .instantiateCustomProposalProvider();
            if (tempProposalProvider == null) {
                return;
            }

            resolveVariables(aParamMap);
            tempFixtureClassWrapper.convertParameterValuesToFixtureDefinedTypes(aMethod.getMethod().getSimpleName(),
                    aParamMap, aParameterPath, true);

            List<CustomProposalDefinition> tempProposals = tempProposalProvider.defineParameterProposals(
                    aMethod.getMethod().getSimpleName(),
                    IntegrityDSLUtil.getParamNameStringFromParameterName(aParameter), aParamMap);

            acceptCustomProposals(tempProposals, aContext, anAcceptor);
        } catch (JavaModelException exc) {
            exc.printStackTrace();
        } catch (UnresolvableVariableException exc) {
            exc.printStackTrace();
        } catch (UnexecutableException exc) {
            exc.printStackTrace();
        }
    }

    private void completeCustomProposalResultValuesInternal(ResultName aResult, MethodReference aMethod,
            Object aResultValue, Map<String, Object> aParamMap, List<String> aParameterPath,
            ContentAssistContext aContext, ICompletionProposalAcceptor anAcceptor) {
        try {
            IType tempJDTType = resolveJDTTypeForJvmType(aMethod.getType());
            FixtureTypeWrapper tempFixtureClassWrapper = wrapType(tempJDTType);

            CustomProposalProvider tempProposalProvider = tempFixtureClassWrapper
                    .instantiateCustomProposalProvider();
            if (tempProposalProvider == null) {
                return;
            }

            resolveVariables(aParamMap);
            tempFixtureClassWrapper.convertParameterValuesToFixtureDefinedTypes(aMethod.getMethod().getSimpleName(),
                    aParamMap, aParameterPath, true);

            List<CustomProposalDefinition> tempProposals = tempProposalProvider
                    .defineResultProposals(aMethod.getMethod().getSimpleName(),
                            aResult != null
                                    ? IntegrityDSLUtil.getExpectedResultNameStringFromTestResultName(aResult)
                                    : null,
                            aResultValue, aParamMap);

            acceptCustomProposals(tempProposals, aContext, anAcceptor);
        } catch (JavaModelException exc) {
            exc.printStackTrace();
        } catch (UnresolvableVariableException exc) {
            exc.printStackTrace();
        } catch (UnexecutableException exc) {
            exc.printStackTrace();
        } catch (Throwable exc) {
            // This should catch anything else, especially errors in the enumerators' code
            Activator.getDefault().getLog().log(new Status(Status.ERROR, "de.gebit.integrity.dsl.ui",
                    "An exception was caught during custom proposal enumeration", exc));
        }
    }

    private void acceptCustomProposals(List<CustomProposalDefinition> someProposals, ContentAssistContext aContext,
            ICompletionProposalAcceptor anAcceptor) {
        if (someProposals == null) {
            return;
        }

        for (final CustomProposalDefinition tempProposal : someProposals) {
            if (tempProposal.getValue() == null) {
                continue;
            }

            String tempPrefix = "";
            if (tempProposal.getDoPrefixFiltering()) {
                tempPrefix = aContext.getPrefix();
            }

            ICompletionProposal tempCompletionProposal = createCompletionProposal(tempProposal.getValue(),
                    new StyledString(tempProposal.getDisplayValue() != null ? tempProposal.getDisplayValue()
                            : tempProposal.getValue()),
                    null, tempProposal.getPriority() + DEFAULT_PROPOSAL_BASE, tempPrefix, aContext);
            if (tempCompletionProposal instanceof IntegrityConfigurableCompletionProposal) {
                if (tempProposal.getHtmlDescription() != null && isBrowserInformationControlIsAvailable()) {
                    ((IntegrityConfigurableCompletionProposal) tempCompletionProposal)
                            .setAdditionalProposalInfo(tempProposal.getHtmlDescription());
                    ((IntegrityConfigurableCompletionProposal) tempCompletionProposal)
                            .setUseHtmlAdditionalProposalInfo(true);
                } else if (tempProposal.getPlainDescription() != null) {
                    ((IntegrityConfigurableCompletionProposal) tempCompletionProposal)
                            .setAdditionalProposalInfo(tempProposal.getPlainDescription());
                }
            }

            anAcceptor.accept(tempCompletionProposal);
        }
    }

    private static boolean isBrowserInformationControlIsAvailable() {
        return BrowserInformationControl.isAvailable(Display.getDefault().getActiveShell());
    }

    private IType resolveJDTTypeForJvmType(JvmType aType) throws JavaModelException {
        IJavaElement tempSourceMethod = (IJavaElement) elementFinder.findElementFor(aType);

        if (tempSourceMethod.getParent() instanceof CompilationUnit) {
            CompilationUnit tempCompilationUnit = (CompilationUnit) tempSourceMethod.getParent();
            return tempCompilationUnit.getTypes()[0];
        } else if (tempSourceMethod.getParent() instanceof ClassFile) {
            ClassFile tempClassFile = (ClassFile) tempSourceMethod.getParent();
            tempClassFile.open(null);
            return tempClassFile.getType();
        }

        return null;
    }

    /**
     * Wraps an {@link IType} in a {@link FixtureTypeWrapper}.
     * 
     * @param aType
     *            the type to wrap
     * @return the resulting wrapper instance
     */
    protected FixtureTypeWrapper wrapType(IType aType) {
        FixtureTypeWrapper tempWrapper = new FixtureTypeWrapper(aType);
        injector.injectMembers(tempWrapper);
        return tempWrapper;
    }

}