protected Collection<org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal>
     handleEnumAttribute(
         org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedTerminal expectedTerminal,
         org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedStructuralFeature
             expectedFeature,
         EEnum enumType,
         String prefix,
         EObject container) {
   Collection<EEnumLiteral> enumLiterals = enumType.getELiterals();
   Collection<org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal> result =
       new LinkedHashSet<
           org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal>();
   for (EEnumLiteral literal : enumLiterals) {
     String unResolvedLiteral = literal.getLiteral();
     // use token resolver to get de-resolved value of the literal
     org.emftext.language.xpath3.resource.xpath3.IXpath3TokenResolverFactory tokenResolverFactory =
         metaInformation.getTokenResolverFactory();
     org.emftext.language.xpath3.resource.xpath3.IXpath3TokenResolver tokenResolver =
         tokenResolverFactory.createTokenResolver(expectedFeature.getTokenName());
     String resolvedLiteral =
         tokenResolver.deResolve(unResolvedLiteral, expectedFeature.getFeature(), container);
     boolean matchesPrefix = matches(resolvedLiteral, prefix);
     result.add(
         new org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal(
             expectedTerminal,
             resolvedLiteral,
             prefix,
             matchesPrefix,
             expectedFeature.getFeature(),
             container));
   }
   return result;
 }
 protected Collection<org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal>
     handleAttribute(
         org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedTerminal expectedTerminal,
         org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedStructuralFeature
             expectedFeature,
         EObject container,
         EAttribute attribute,
         String prefix) {
   Collection<org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal> resultSet =
       new LinkedHashSet<
           org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal>();
   Object[] defaultValues = attributeValueProvider.getDefaultValues(attribute);
   if (defaultValues != null) {
     for (Object defaultValue : defaultValues) {
       if (defaultValue != null) {
         org.emftext.language.xpath3.resource.xpath3.IXpath3TokenResolverFactory
             tokenResolverFactory = metaInformation.getTokenResolverFactory();
         String tokenName = expectedFeature.getTokenName();
         if (tokenName != null) {
           org.emftext.language.xpath3.resource.xpath3.IXpath3TokenResolver tokenResolver =
               tokenResolverFactory.createTokenResolver(tokenName);
           if (tokenResolver != null) {
             String defaultValueAsString =
                 tokenResolver.deResolve(defaultValue, attribute, container);
             boolean matchesPrefix = matches(defaultValueAsString, prefix);
             resultSet.add(
                 new org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal(
                     expectedTerminal,
                     defaultValueAsString,
                     prefix,
                     matchesPrefix,
                     expectedFeature.getFeature(),
                     container));
           }
         }
       }
     }
   }
   return resultSet;
 }
  protected Collection<org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal>
      deriveProposals(
          final org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedTerminal
              expectedTerminal,
          String content,
          org.emftext.language.xpath3.resource.xpath3.IXpath3TextResource resource,
          int cursorOffset) {
    org.emftext.language.xpath3.resource.xpath3.IXpath3ExpectedElement expectedElement =
        (org.emftext.language.xpath3.resource.xpath3.IXpath3ExpectedElement)
            expectedTerminal.getTerminal();
    if (expectedElement
        instanceof org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedCsString) {
      org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedCsString csString =
          (org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedCsString) expectedElement;
      return handleKeyword(
          expectedTerminal,
          csString,
          expectedTerminal.getPrefix(),
          expectedTerminal.getContainer());
    } else if (expectedElement
        instanceof org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedBooleanTerminal) {
      org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedBooleanTerminal
          expectedBooleanTerminal =
              (org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedBooleanTerminal)
                  expectedElement;
      return handleBooleanTerminal(
          expectedTerminal, expectedBooleanTerminal, expectedTerminal.getPrefix());
    } else if (expectedElement
        instanceof
        org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedEnumerationTerminal) {
      org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedEnumerationTerminal
          expectedEnumerationTerminal =
              (org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedEnumerationTerminal)
                  expectedElement;
      return handleEnumerationTerminal(
          expectedTerminal, expectedEnumerationTerminal, expectedTerminal.getPrefix());
    } else if (expectedElement
        instanceof
        org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedStructuralFeature) {
      final org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedStructuralFeature
          expectedFeature =
              (org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedStructuralFeature)
                  expectedElement;
      final EStructuralFeature feature = expectedFeature.getFeature();
      final EClassifier featureType = feature.getEType();
      final EObject container = findCorrectContainer(expectedTerminal);

      // Here it gets really crazy. We need to modify the model in a way that reflects
      // the state the model would be in, if the expected terminal were present. After
      // computing the corresponding completion proposals, the original state of the
      // model is restored. This procedure is required, because different models can be
      // required for different completion situations. This can be particularly observed
      // when the user has not yet typed a character that starts an element to be
      // completed.
      final Collection<org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal>
          proposals =
              new ArrayList<
                  org.emftext.language.xpath3.resource.xpath3.ui.Xpath3CompletionProposal>();
      expectedTerminal.materialize(
          new Runnable() {

            public void run() {
              if (feature instanceof EReference) {
                EReference reference = (EReference) feature;
                if (featureType instanceof EClass) {
                  if (reference.isContainment()) {
                    // the FOLLOW set should contain only non-containment references
                    assert false;
                  } else {
                    proposals.addAll(
                        handleNCReference(
                            expectedTerminal,
                            container,
                            reference,
                            expectedTerminal.getPrefix(),
                            expectedFeature.getTokenName()));
                  }
                }
              } else if (feature instanceof EAttribute) {
                EAttribute attribute = (EAttribute) feature;
                if (featureType instanceof EEnum) {
                  EEnum enumType = (EEnum) featureType;
                  proposals.addAll(
                      handleEnumAttribute(
                          expectedTerminal,
                          expectedFeature,
                          enumType,
                          expectedTerminal.getPrefix(),
                          container));
                } else {
                  // handle EAttributes (derive default value depending on the type of the
                  // attribute, figure out token resolver, and call deResolve())
                  proposals.addAll(
                      handleAttribute(
                          expectedTerminal,
                          expectedFeature,
                          container,
                          attribute,
                          expectedTerminal.getPrefix()));
                }
              } else {
                // there should be no other subclass of EStructuralFeature
                assert false;
              }
            }
          });
      // Return the proposals that were computed in the closure call.
      return proposals;
    } else {
      // there should be no other class implementing IExpectedElement
      assert false;
    }
    return Collections.emptyList();
  }