private void findFields(
      char[] token, boolean canCompleteEmptyToken, List<IField> fields, int kind, List names) {
    if (fields == null || fields.size() == 0) return;

    int length = token.length;
    // String tok = new String(token);
    if (canCompleteEmptyToken || length > 0) {
      for (int i = 0; i < fields.size(); i++) {
        IField field = fields.get(i);
        String qname = (String) names.get(i);
        String name = qname;
        if (DEBUG) {
          System.out.println("Completion:" + qname); // $NON-NLS-1$
        }
        if (length <= name.length() && CharOperation.prefixEquals(token, name, false)) {
          int relevance = computeBaseRelevance();
          relevance += computeRelevanceForInterestingProposal();
          relevance += computeRelevanceForCaseMatching(token, name);
          relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no

          // accept result
          this.noProposal = false;
          if (!this.requestor.isIgnored(kind)) {
            CompletionProposal proposal = this.createProposal(kind, this.actualCompletionPosition);
            proposal.setModelElement(field);
            proposal.setName(name);
            proposal.setCompletion(qname);
            proposal.setRelevance(relevance);
            accept(proposal);
          }
        }
      }
    }
  }
    @Override
    public void accept(CompletionProposal proposal) {
      assertTrue(proposal instanceof RefSearchCompletionProposal);
      RefSearchCompletionProposal refProposal = (RefSearchCompletionProposal) proposal;

      assertTrue(proposal.getCompletionLocation() == offset);
      assertTrue(proposal.getReplaceStart() == offset);
      assertTrue(proposal.getReplaceEnd() - proposal.getReplaceStart() == rplLen);
      INamedElement defUnit = refProposal.getExtraInfo();
      results.add(defUnit);
    }
 public void accept(CompletionProposal proposal) {
   proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
   this.requestor.accept(proposal);
   if (DEBUG) {
     this.printDebug(proposal);
   }
 }
  protected void findMethods(
      char[] token, boolean canCompleteEmptyToken, List<IMethod> methods, int kind) {
    if (methods == null || methods.size() == 0) return;

    int length = token.length;
    String tok = new String(token);
    if (canCompleteEmptyToken || length > 0) {
      for (int i = 0; i < methods.size(); i++) {
        IMethod method = methods.get(i);
        String qname = processMethodName(method, tok);
        String name = qname;
        if (DEBUG) {
          System.out.println("Completion:" + qname); // $NON-NLS-1$
        }
        if (length <= name.length() && CharOperation.prefixEquals(token, name, false)) {
          int relevance = computeBaseRelevance();
          relevance += computeRelevanceForInterestingProposal();
          relevance += computeRelevanceForCaseMatching(token, name);
          relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no

          // accept result
          this.noProposal = false;
          if (!this.requestor.isIgnored(kind)) {
            CompletionProposal proposal = this.createProposal(kind, this.actualCompletionPosition);
            // proposal.setSignature(getSignature(typeBinding));
            // proposal.setPackageName(q);
            // proposal.setTypeName(displayName);
            proposal.setModelElement(method);
            try {
              proposal.setFlags(method.getFlags());
            } catch (ModelException e1) {
              if (DLTKCore.DEBUG) {
                e1.printStackTrace();
              }
            }
            String[] arguments = null;

            try {
              arguments = method.getParameterNames();
            } catch (ModelException e) {
              if (DLTKCore.DEBUG) {
                e.printStackTrace();
              }
            }
            if (arguments != null && arguments.length > 0) {
              proposal.setParameterNames(arguments);
            }

            proposal.setName(name);
            proposal.setCompletion(name);
            // proposal.setFlags(Flags.AccDefault);
            proposal.setRelevance(relevance);
            accept(proposal);
          }
        }
      }
    }
  }
  private ScriptCompletionProposal generateTwigProposal(CompletionProposal typeProposal) {

    String completion = new String(typeProposal.getCompletion());
    int replaceStart = typeProposal.getReplaceStart();
    int length = getLength(typeProposal);
    Image image =
        getImage(
            ((TwigCompletionProposalLabelProvider) getLabelProvider())
                .createTypeImageDescriptor(typeProposal));

    String displayString =
        ((TwigCompletionProposalLabelProvider) getLabelProvider())
            .createTypeProposalLabel(typeProposal);

    ScriptCompletionProposal scriptProposal =
        new EmptyCompletionProposal(completion, replaceStart, length, image, displayString, 0);

    return scriptProposal;
  }
  protected void findLocalMethods(
      char[] token, boolean canCompleteEmptyToken, List methods, List methodNames) {
    if (methods == null || methods.size() == 0) return;

    int length = token.length;
    if (canCompleteEmptyToken || length > 0) {
      for (int i = 0; i < methods.size(); i++) {
        MethodDeclaration method = (MethodDeclaration) methods.get(i);
        String name = ((String) (methodNames.get(i)));
        if (length <= name.length() && CharOperation.prefixEquals(token, name, false)) {
          int relevance = computeBaseRelevance();
          relevance += computeRelevanceForInterestingProposal();
          relevance += computeRelevanceForCaseMatching(token, name);
          relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no

          // accept result
          this.noProposal = false;
          if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
            CompletionProposal proposal =
                this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
            // proposal.setSignature(getSignature(typeBinding));
            // proposal.setPackageName(q);
            // proposal.setTypeName(displayName);
            List arguments = method.getArguments();
            if (arguments != null && arguments.size() > 0) {
              String[] args = new String[arguments.size()];
              for (int j = 0; j < arguments.size(); ++j) {
                args[j] = ((Argument) arguments.get(j)).getName();
              }
              proposal.setParameterNames(args);
            }

            proposal.setName(name);
            proposal.setCompletion(name);
            // proposal.setFlags(Flags.AccDefault);
            proposal.setRelevance(relevance);
            accept(proposal);
          }
        }
      }
    }
  }
  protected void findElements(
      char[] token,
      String[] choices,
      boolean canCompleteEmptyToken,
      boolean provideDollar,
      int kind) {
    if (choices == null || choices.length == 0) return;

    int length = token.length;
    if (canCompleteEmptyToken || length > 0) {
      for (int i = 0; i < choices.length; i++) {
        String co = choices[i];
        if (!provideDollar && co.length() > 1 && co.charAt(0) == '$') {
          co = co.substring(1);
        }
        if (length <= co.length() && CharOperation.prefixEquals(token, co, false)) {
          int relevance = computeBaseRelevance();
          relevance += computeRelevanceForInterestingProposal();
          relevance += computeRelevanceForCaseMatching(token, co);
          relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no

          // accept result
          this.noProposal = false;

          if (!this.requestor.isIgnored(kind)) {
            CompletionProposal proposal = this.createProposal(kind, this.actualCompletionPosition);
            // proposal.setSignature(getSignature(typeBinding));
            // proposal.setPackageName(q);
            // proposal.setTypeName(displayName);
            proposal.setName(co);
            proposal.setCompletion(co);

            // proposal.setFlags(Flags.AccDefault);
            proposal.setRelevance(relevance);
            accept(proposal);
          }
        }
      }
    }
  }
  public void findTypes(char[] token, boolean canCompleteEmptyToken, List<IType> types) {
    if (types == null || types.size() == 0) return;

    int length = token.length;
    String tok = new String(token);
    if (canCompleteEmptyToken || length > 0) {
      for (int i = 0; i < types.size(); i++) {
        IType type = types.get(i);
        String qname = processTypeName(type, tok);
        String name = qname;
        if (DEBUG) {
          System.out.println("Completion:" + qname); // $NON-NLS-1$
        }
        if (length <= name.length() && CharOperation.prefixEquals(token, name, false)) {
          int relevance = computeBaseRelevance();
          relevance += computeRelevanceForInterestingProposal();
          relevance += computeRelevanceForCaseMatching(token, name);
          relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no

          // accept result
          this.noProposal = false;
          if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {

            CompletionProposal proposal =
                this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
            // proposal.setSignature(getSignature(typeBinding));
            // proposal.setPackageName(q);
            // proposal.setTypeName(displayName);
            proposal.setModelElement(type);
            proposal.setName(name);
            proposal.setCompletion(name);
            // proposal.setFlags(Flags.AccDefault);
            proposal.setRelevance(relevance);
            accept(proposal);
          }
        }
      }
    }
  }
  public void findKeywords(char[] keyword, String[] choices, boolean canCompleteEmptyToken) {
    if (choices == null || choices.length == 0) return;

    int length = keyword.length;
    if (canCompleteEmptyToken || length > 0) {
      for (int i = 0; i < choices.length; i++) {
        if (length <= choices[i].length()
            && CharOperation.prefixEquals(keyword, choices[i], false)) {
          int relevance = computeBaseRelevance();

          relevance += computeRelevanceForInterestingProposal();
          relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
          relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no
          /*
           * access restriction for keywords
           */

          // if (CharOperation.equals(choices[i], Keywords.TRUE)
          // || CharOperation.equals(choices[i], Keywords.FALSE)) {
          // relevance +=
          // computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
          // relevance += computeRelevanceForQualification(false);
          // }
          this.noProposal = false;
          if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
            CompletionProposal proposal =
                this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
            proposal.setName(choices[i]);
            proposal.setCompletion(choices[i]);
            proposal.setRelevance(relevance);
            accept(proposal);
          }
        }
      }
    }
  }
  @Override
  protected IScriptCompletionProposal createScriptCompletionProposal(CompletionProposal proposal) {

    IModelElement element = proposal.getModelElement();

    if (element == null) {
      return null;
    }

    // creates a proposal for a route
    if (element.getClass() == Tag.class) {
      return createTagProposal(proposal);
    } else if (element.getClass() == Filter.class) {
      return createFilterProposal(proposal);
    } else if (element.getClass() == Function.class) {
      return createFunctionProposal(proposal);
    } else if (element.getClass() == Test.class) {
      return createTestProposal(proposal);
    }

    return super.createScriptCompletionProposal(proposal);
  }
  protected CompletionProposal createProposal(int kind, int completionOffset) {
    CompletionProposal proposal = CompletionProposal.create(kind, completionOffset - this.offset);

    return proposal;
  }
 protected void printDebug(CompletionProposal proposal) {
   StringBuffer buffer = new StringBuffer();
   buffer.append("COMPLETION - "); // $NON-NLS-1$
   switch (proposal.getKind()) {
     case CompletionProposal.FIELD_REF:
       buffer.append("FIELD_REF"); // $NON-NLS-1$
       break;
     case CompletionProposal.KEYWORD:
       buffer.append("KEYWORD"); // $NON-NLS-1$
       break;
     case CompletionProposal.LABEL_REF:
       buffer.append("LABEL_REF"); // $NON-NLS-1$
       break;
     case CompletionProposal.LOCAL_VARIABLE_REF:
       buffer.append("LOCAL_VARIABLE_REF"); // $NON-NLS-1$
       break;
     case CompletionProposal.METHOD_DECLARATION:
       buffer.append("METHOD_DECLARATION"); // $NON-NLS-1$
       break;
     case CompletionProposal.METHOD_REF:
       buffer.append("METHOD_REF"); // $NON-NLS-1$
       break;
     case CompletionProposal.PACKAGE_REF:
       buffer.append("PACKAGE_REF"); // $NON-NLS-1$
       break;
     case CompletionProposal.TYPE_REF:
       buffer.append("TYPE_REF"); // $NON-NLS-1$
       break;
     case CompletionProposal.VARIABLE_DECLARATION:
       buffer.append("VARIABLE_DECLARATION"); // $NON-NLS-1$
       break;
     case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
       buffer.append("POTENTIAL_METHOD_DECLARATION"); // $NON-NLS-1$
       break;
     case CompletionProposal.METHOD_NAME_REFERENCE:
       buffer.append("METHOD_NAME_REFERENCE"); // $NON-NLS-1$
       break;
     default:
       buffer.append("PROPOSAL"); // $NON-NLS-1$
       break;
   }
   if (VERBOSE) {
     buffer.append("{\n"); // $NON-NLS-1$
     buffer
         .append("\tCompletion[")
         .append(proposal.getCompletion() == null ? "null" : proposal.getCompletion())
         .append("]\n"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
     buffer
         .append("\tDeclarationKey[")
         .append(proposal.getDeclarationKey() == null ? "null" : proposal.getDeclarationKey())
         .append("]\n"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
     buffer
         .append("\tKey[")
         .append(proposal.getKey() == null ? "null" : proposal.getKey())
         .append("]\n"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
     buffer
         .append("\tName[")
         .append(proposal.getName() == null ? "null" : proposal.getName())
         .append("]\n"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
     buffer
         .append("\tCompletionLocation[")
         .append(proposal.getCompletionLocation())
         .append("]\n"); // $NON-NLS-1$ //$NON-NLS-2$
     int start = proposal.getReplaceStart();
     int end = proposal.getReplaceEnd();
     buffer.append("\tReplaceStart[").append(start).append("]"); // $NON-NLS-1$ //$NON-NLS-2$
     buffer.append("-ReplaceEnd[").append(end).append("]\n"); // $NON-NLS-1$ //$NON-NLS-2$
     if (this.source != null)
       buffer
           .append("\tReplacedText[")
           .append(this.source, start, end - start)
           .append("]\n"); // $NON-NLS-1$ //$NON-NLS-2$
     buffer
         .append("\tTokenStart[")
         .append(proposal.getTokenStart())
         .append("]"); // $NON-NLS-1$ //$NON-NLS-2$
     buffer
         .append("-TokenEnd[")
         .append(proposal.getTokenEnd())
         .append("]\n"); // $NON-NLS-1$ //$NON-NLS-2$
     buffer
         .append("\tRelevance[")
         .append(proposal.getRelevance())
         .append("]\n"); // $NON-NLS-1$ //$NON-NLS-2$
     buffer.append("}\n"); // $NON-NLS-1$
   } else {
     if (proposal.getCompletion() != null) {
       buffer.append(' ').append('"').append(proposal.getCompletion()).append('"');
     }
   }
   System.out.println(buffer.toString());
 }