/*
 * Copyright 2000-2009 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.refactoring.changeSignature;

import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.SharedImplUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.IncorrectOperationException;

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

/**
 * @author dsl
 */
public class ChangeSignatureUtil {
  private ChangeSignatureUtil() {
  }

  public static <Parent extends PsiElement, Child extends PsiElement> void synchronizeList(Parent list,
                                                                                           final List<Child> newElements,
                                                                                           ChildrenGenerator<Parent, Child> generator,
                                                                                           final boolean[] shouldRemoveChild)
    throws IncorrectOperationException {

    ArrayList<Child> elementsToRemove = null;
    List<Child> elements;

    int index = 0;
    while (true) {
      elements = generator.getChildren(list);
      if (index == newElements.size()) break;

      if (elementsToRemove == null) {
        elementsToRemove = new ArrayList<Child>();
        for (int i = 0; i < shouldRemoveChild.length; i++) {
          if (shouldRemoveChild[i] && i < elements.size()) {
            elementsToRemove.add(elements.get(i));
          }
        }
      }

      Child oldElement = index < elements.size() ? elements.get(index) : null;
      Child newElement = newElements.get(index);
      if (newElement != null) {
        if (!newElement.equals(oldElement)) {
          if (oldElement != null && elementsToRemove.contains(oldElement)) {
            oldElement.delete();
            index--;
          }
          else {
            assert list.isWritable() : PsiUtilBase.getVirtualFile(list);
            list.addBefore(newElement, oldElement);
            if (list.equals(newElement.getParent())) {
              newElement.delete();
            }
          }
        }
      } else {
        PsiElement anchor = null;
        if (index == 0) {
          anchor = list.getFirstChild();
        } else {
          anchor = elements.get(index - 1);
        }
        final PsiElement psi = Factory
          .createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, SharedImplUtil.findCharTableByTree(list.getNode()), list.getManager())
          .getPsi();
        if (anchor != null) {
          list.addAfter(psi, anchor);
        } else {
          list.add(psi);
        }
      }
      index++;
    }
    for (int i = newElements.size(); i < elements.size(); i++) {
      Child element = elements.get(i);
      element.delete();
    }
  }

  public interface ChildrenGenerator<Parent extends PsiElement, Child extends PsiElement> {
    List<Child> getChildren(Parent parent);
  }
}

@@ -2723,32 +2723,72 @@
 %0A      %7D else %7B%0A
+        if (newElements.size() %3E 1) %7B%0A  
         PsiEleme
@@ -2796,25 +2796,20 @@
 t anchor
- = null
 ;%0A
+  
         
@@ -2822,24 +2822,26 @@
 dex == 0) %7B%0A
+  
           an
@@ -2865,24 +2865,26 @@
 rstChild();%0A
+  
         %7D el
@@ -2890,32 +2890,34 @@
 lse %7B%0A          
+  
 anchor = element
@@ -2934,16 +2934,18 @@
 x - 1);%0A
+  
         
@@ -2950,24 +2950,26 @@
   %7D%0A        
+  
 final PsiEle
@@ -2987,16 +2987,18 @@
 Factory%0A
+  
         
@@ -3127,16 +3127,18 @@
 ager())%0A
+  
         
@@ -3154,24 +3154,26 @@
 ();%0A        
+  
 if (anchor !
@@ -3174,32 +3174,34 @@
 chor != null) %7B%0A
+  
           list.a
@@ -3222,32 +3222,34 @@
 nchor);%0A        
+ 
+ 
 %7D else %7B%0A       
@@ -3233,32 +3233,34 @@
        %7D else %7B%0A
+  
           list.a
@@ -3264,24 +3264,36 @@
 t.add(psi);%0A
+          %7D%0A
         %7D%0A  

change signature: do not add comma if only one parameter added