/*
 * Copyright 2000-2013 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.codeInsight.completion;

import com.intellij.codeInsight.TailType;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.TailTypeDecorator;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.source.xml.SchemaPrefixReference;
import com.intellij.psi.impl.source.xml.TagNameReference;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.Consumer;
import com.intellij.util.ProcessingContext;
import com.intellij.xml.XmlTagNameProvider;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

/**
 * @author yole
 */
public class TagNameReferenceCompletionProvider extends CompletionProvider<CompletionParameters> {
  public static LookupElement[] getTagNameVariants(final @NotNull XmlTag tag, final String prefix) {
    List<LookupElement> elements = new ArrayList<LookupElement>();
    for (XmlTagNameProvider tagNameProvider : XmlTagNameProvider.EP_NAME.getExtensions()) {
      tagNameProvider.addTagNameVariants(elements, tag, prefix);
    }
    return elements.toArray(new LookupElement[elements.size()]);
  }

  @Override
  protected void addCompletions(@NotNull CompletionParameters parameters,
                                ProcessingContext context,
                                @NotNull CompletionResultSet result) {
    PsiReference reference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
    if (reference instanceof TagNameReference) {
      TagNameReference tagNameReference = (TagNameReference)reference;
      collectCompletionVariants(tagNameReference, result);
    }
    else if (reference instanceof SchemaPrefixReference) {
      TagNameReference tagNameReference = ((SchemaPrefixReference) reference).getTagNameReference();
      if (tagNameReference != null && !tagNameReference.isStartTagFlag()) {
        result.consume(createClosingTagLookupElement((XmlTag)tagNameReference.getElement(), true, tagNameReference.getNameElement()));
      }
    }
  }

  public static void collectCompletionVariants(TagNameReference tagNameReference,
                                               Consumer<LookupElement> consumer) {
    PsiElement element = tagNameReference.getElement();
    if (element instanceof XmlTag) {
      if (!tagNameReference.isStartTagFlag()) {
        consumer.consume(createClosingTagLookupElement((XmlTag)element, false, tagNameReference.getNameElement()));
      }
      else {
        XmlTag tag = (XmlTag) element;
        for(LookupElement variant: getTagNameVariants(tag, tag.getNamespacePrefix())) {
          consumer.consume(variant);
        }
      }
    }
  }

  public static LookupElement createClosingTagLookupElement(XmlTag tag, boolean includePrefix, ASTNode nameElement) {
    LookupElementBuilder
      builder = LookupElementBuilder.create(includePrefix || !nameElement.getText().contains(":") ? tag.getName() : tag.getLocalName());
    return TailTypeDecorator.withTail(AutoCompletionPolicy.GIVE_CHANCE_TO_OVERWRITE.applyPolicy(builder),
                                      TailType.createSimpleTailType('>'));
  }

}

@@ -1212,24 +1212,63 @@
 l.Consumer;%0A
+import com.intellij.util.PairConsumer;%0A
 import com.i
@@ -2140,32 +2140,38 @@
        @NotNull 
+final 
 CompletionResult
@@ -2192,30 +2192,52 @@
     
-PsiReference r
+LegacyCompletionContributor.processR
 eference
  = p
@@ -2232,19 +2232,18 @@
 eference
- = 
+s(
 paramete
@@ -2248,129 +2248,163 @@
 ters
-.getPosition().getContainingFile().findReferenceAt(parameters.getOffs
+, result, new PairConsumer%3CPsiReference, CompletionResultS
 et
+%3E
 ()
-);%0A    if (reference instanceof TagNameReference
+ %7B%0A      @Override%0A      public void consume(PsiReference reference, CompletionResultSet set
 ) %7B%0A
@@ -2405,32 +2405,31 @@
 et) %7B%0A      
-TagNameR
+  if (r
 eference tag
@@ -2425,36 +2425,27 @@
 ference 
-tagNameReference = (
+instanceof 
 TagNameR
@@ -2457,19 +2457,15 @@
 nce)
-reference;%0A
+ %7B%0A    
     
@@ -2492,17 +2492,18 @@
 ariants(
-t
+(T
 agNameRe
@@ -2513,23 +2513,30 @@
 ence
-, resul
+)reference, se
 t);%0A    
 %7D%0A  
@@ -2531,22 +2531,30 @@
 t);%0A    
+  
-%7D%0A
+  %7D%0A   
     
+ 
 else if 
@@ -2596,24 +2596,28 @@
 eference) %7B%0A
+    
       TagNam
@@ -2670,17 +2670,16 @@
 ference)
- 
 referenc
@@ -2706,24 +2706,28 @@
 ce();%0A      
+    
 if (tagNameR
@@ -2792,21 +2792,22 @@
         
+ 
-resul
+   se
 t.consum
@@ -2916,32 +2916,54 @@
 lement()));%0A
+          %7D%0A        %7D%0A
       %7D%0A
     %7D%0A  %7D%0A%0A 
@@ -2942,37 +2942,39 @@
       %7D%0A      %7D%0A
-
     %7D
+);
 %0A  %7D%0A%0A  public s

fix android completion test: use LegacyCompletionContributor.processReferences()