/*
  * (non-Javadoc)
  * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer#
  * computeCompletionProposals
  * (org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext,
  * org.eclipse.core.runtime.IProgressMonitor)
  */
 @Override
 public List<ICompletionProposal> computeCompletionProposals(
     ContentAssistInvocationContext context, IProgressMonitor monitor) {
   JavaContentAssistInvocationContext jcontext = null;
   if (context instanceof JavaContentAssistInvocationContext) {
     jcontext = (JavaContentAssistInvocationContext) context;
     IJavaProject project = jcontext.getProject();
     if (Util.isApiProject(project)) {
       CompletionContext corecontext = jcontext.getCoreContext();
       if (corecontext.isInJavadoc()) {
         return computeJavadocProposals(jcontext, corecontext);
       }
     }
   }
   return Collections.EMPTY_LIST;
 }
 /**
  * Computes all of the Javadoc completion proposals
  *
  * @param jcontext
  * @param corecontext
  * @return the complete list of Javadoc completion proposals or an empty list, never <code>null
  *     </code>
  * @since 1.0.500
  */
 List<ICompletionProposal> computeJavadocProposals(
     JavaContentAssistInvocationContext jcontext, CompletionContext corecontext) {
   ICompilationUnit cunit = jcontext.getCompilationUnit();
   if (cunit != null) {
     try {
       int offset = jcontext.getInvocationOffset();
       IJavaElement element = cunit.getElementAt(offset);
       if (!isVisible(element)) {
         return Collections.EMPTY_LIST;
       }
       ImageDescriptor imagedesc =
           jcontext
               .getLabelProvider()
               .createImageDescriptor(
                   org.eclipse.jdt.core.CompletionProposal.create(
                       org.eclipse.jdt.core.CompletionProposal.JAVADOC_BLOCK_TAG, offset));
       fImageHandle = (imagedesc == null ? null : imagedesc.createImage());
       int type = getType(element);
       int member = IApiJavadocTag.MEMBER_NONE;
       switch (element.getElementType()) {
         case IJavaElement.METHOD:
           {
             IMethod method = (IMethod) element;
             member = IApiJavadocTag.MEMBER_METHOD;
             if (method.isConstructor()) {
               member = IApiJavadocTag.MEMBER_CONSTRUCTOR;
             }
             break;
           }
         case IJavaElement.FIELD:
           {
             member = IApiJavadocTag.MEMBER_FIELD;
             break;
           }
         default:
           break;
       }
       IApiJavadocTag[] tags = ApiPlugin.getJavadocTagManager().getTagsForType(type, member);
       int tagcount = tags.length;
       if (tagcount > 0) {
         ArrayList<ICompletionProposal> list = null;
         collectExistingTags(element, jcontext);
         String completiontext = null;
         int tokenstart = corecontext.getTokenStart();
         int length = offset - tokenstart;
         for (int i = 0; i < tagcount; i++) {
           if (!acceptTag(tags[i], element)) {
             continue;
           }
           completiontext = tags[i].getCompleteTag(type, member);
           if (appliesToContext(
               jcontext.getDocument(), completiontext, tokenstart, (length > 0 ? length : 1))) {
             if (list == null) {
               list = new ArrayList<ICompletionProposal>(tagcount - i);
             }
             list.add(
                 new APIToolsJavadocCompletionProposal(
                     corecontext, completiontext, tags[i].getTagName(), fImageHandle));
           }
         }
         if (list != null) {
           return list;
         }
       }
     } catch (JavaModelException e) {
       fErrorMessage = e.getMessage();
     }
   }
   return Collections.EMPTY_LIST;
 }
  @Override
  public List<ICompletionProposal> computeCompletionProposals(
      final ContentAssistInvocationContext context, final IProgressMonitor monitor) {
    final List<ICompletionProposal> list = new ArrayList<ICompletionProposal>();
    boolean extendContext = false;
    try {
      if (context instanceof JavaContentAssistInvocationContext) {
        final ITextViewer viewer = context.getViewer();
        final List<ScriptVariable> scriptVariables = getScriptVariables(viewer);
        if (scriptVariables.isEmpty()) {
          return list;
        }
        final CompletionContext coreContext =
            ((JavaContentAssistInvocationContext) context).getCoreContext();
        if (coreContext != null && !coreContext.isExtended()) {
          // must use reflection to set the fields
          ReflectionUtils.setPrivateField(
              InternalCompletionContext.class, "isExtended", coreContext, true);
          extendContext = true;
        }
        final ICompilationUnit unit =
            ((JavaContentAssistInvocationContext) context).getCompilationUnit();
        if (unit instanceof GroovyCompilationUnit) {
          if (((GroovyCompilationUnit) unit).getModuleNode() == null) {
            return Collections.emptyList();
          }
          final ContentAssistContext assistContext =
              new GroovyCompletionProposalComputer()
                  .createContentAssistContext(
                      (GroovyCompilationUnit) unit,
                      context.getInvocationOffset(),
                      context.getDocument());
          CharSequence prefix = null;
          try {
            prefix = context.computeIdentifierPrefix();
          } catch (final BadLocationException e) {
            BonitaStudioLog.error(e);
          }

          if (assistContext != null && assistContext.completionNode instanceof VariableExpression) {
            try {
              final VariableExpression expr = (VariableExpression) assistContext.completionNode;
              if (scriptVariables != null) {
                for (final ScriptVariable f : scriptVariables) {
                  if (expr.getName().equals(f.getName())) {
                    final IType type = javaProject.findType(f.getType());
                    if (type == null) {
                      return list;
                    }
                    for (final IMethod m : type.getMethods()) {
                      if (m.getElementName().startsWith(prefix.toString())) {
                        final GroovyCompletionProposal proposal =
                            new GroovyCompletionProposal(
                                CompletionProposal.METHOD_REF, context.getInvocationOffset());
                        proposal.setName(m.getElementName().toCharArray());
                        proposal.setCompletion(
                            m.getElementName().substring(prefix.length()).toCharArray());
                        proposal.setFlags(m.getFlags());

                        if (prefix.length() == m.getElementName().length()) {
                          proposal.setReplaceRange(
                              context.getInvocationOffset(), context.getInvocationOffset());
                          proposal.setReceiverRange(0, 0);
                        } else {
                          proposal.setReplaceRange(
                              context.getInvocationOffset() - prefix.length(),
                              context.getInvocationOffset());
                          proposal.setReceiverRange(prefix.length(), prefix.length());
                        }

                        final char[][] parametersArray =
                            new char[m.getParameterNames().length][256];
                        final List<Parameter> parameters = new ArrayList<Parameter>();
                        for (int i = 0; i < m.getParameterNames().length; i++) {
                          parametersArray[i] = m.getParameterNames()[i].toCharArray();
                          parameters.add(
                              new Parameter(
                                  ClassHelper.make(
                                      Signature.getSignatureSimpleName(m.getParameterTypes()[i])),
                                  m.getParameterNames()[i]));
                        }

                        final ClassNode classNode =
                            ClassHelper.make(m.getDeclaringType().getFullyQualifiedName());
                        proposal.setDeclarationSignature(
                            ProposalUtils.createTypeSignature(classNode));
                        proposal.setParameterNames(parametersArray);
                        if (m.getDeclaringType().getFullyQualifiedName().equals(f.getType())) {
                          proposal.setRelevance(100);
                        }

                        final MethodNode methodNode =
                            new MethodNode(
                                m.getElementName(),
                                m.getFlags(),
                                ClassHelper.make(
                                    Signature.getSignatureSimpleName(m.getReturnType())),
                                parameters.toArray(new Parameter[parameters.size()]),
                                new ClassNode[0],
                                null);
                        final char[] methodSignature =
                            ProposalUtils.createMethodSignature(methodNode);
                        proposal.setSignature(methodSignature);

                        final GroovyJavaGuessingCompletionProposal groovyProposal =
                            GroovyJavaGuessingCompletionProposal.createProposal(
                                proposal,
                                (JavaContentAssistInvocationContext) context,
                                true,
                                "Groovy",
                                ProposalFormattingOptions.newFromOptions());
                        if (groovyProposal != null) {
                          list.add(groovyProposal);
                        }
                      }
                    }
                  }
                }
              }
            } catch (final JavaModelException e) {
              BonitaStudioLog.error(e);
            }
          }
        }

        return list;
      }
    } finally {
      final CompletionContext coreContext =
          ((JavaContentAssistInvocationContext) context).getCoreContext();
      if (extendContext && coreContext != null && coreContext.isExtended()) {
        // must use reflection to set the fields
        ReflectionUtils.setPrivateField(
            InternalCompletionContext.class, "isExtended", coreContext, false);
      }
    }

    return Collections.emptyList();
  }