package com.intellij.psi.impl.file;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.util.IncorrectOperationException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class PsiFileImplUtil {
  private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.PsiFileImplUtil");

  public static PsiFile setName(final PsiFile file, String newName) throws IncorrectOperationException {
    VirtualFile vFile = file.getViewProvider().getVirtualFile();
    PsiManagerImpl manager = (PsiManagerImpl)file.getManager();

    try{
      final FileDocumentManager fdm = FileDocumentManager.getInstance();
      final Document doc = fdm.getCachedDocument(vFile);
      if (doc != null) {
        EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance();
        
        String trailer = editorSettings.getStripTrailingSpaces();
        editorSettings.setStripTrailingSpaces(EditorSettingsExternalizable.STRIP_TRAILING_SPACES_NONE);
        try {
          fdm.saveDocument(doc);
        }
        finally {
          editorSettings.setStripTrailingSpaces(trailer);
        }
      }
      
      vFile.rename(manager, newName);
    }
    catch(IOException e){
      throw new IncorrectOperationException(e.toString(),e);
    }

    return file.getViewProvider().isPhysical() ? manager.findFile(vFile) : file;
  }

  public static void checkSetName(PsiFile file, String name) throws IncorrectOperationException {
    VirtualFile vFile = file.getVirtualFile();
    VirtualFile parentFile = vFile.getParent();
    if (parentFile == null) return;
    VirtualFile child = parentFile.findChild(name);
    if (child != null && !child.equals(vFile)){
      throw new IncorrectOperationException("File " + child.getPresentableUrl() + " already exists.");
    }
  }

  public static void doDelete(final PsiFile file) throws IncorrectOperationException {
    final PsiManagerImpl manager = (PsiManagerImpl)file.getManager();

    final VirtualFile vFile = file.getVirtualFile();
    try{
      vFile.delete(manager);
    }
    catch(IOException e){
      throw new IncorrectOperationException(e.toString(),e);
    }
  }

  public static PsiFile[] getPsiFilesByVirtualFiles(VirtualFile[] files, PsiManager manager) {
    List<PsiFile> psiFiles = new ArrayList<PsiFile>();
    for (VirtualFile file : files) {
      PsiFile psiFile = manager.findFile(file);
      if (psiFile != null) {
        psiFiles.add(psiFile);
      }
    }
    return psiFiles.toArray(new PsiFile[psiFiles.size()]);
  }

  public static PsiFile[] getPsiFilesByVirtualFiles(List<VirtualFile> files, PsiManager manager) {
    List<PsiFile> psiFiles = new ArrayList<PsiFile>();

    for (VirtualFile file : files) {
      PsiFile psiFile = manager.findFile(file);
      if (psiFile != null) {
        psiFiles.add(psiFile);
      }
    }
    return psiFiles.toArray(new PsiFile[psiFiles.size()]);
  }
}

@@ -242,32 +242,184 @@
 ocumentManager;%0A
+import com.intellij.openapi.fileTypes.FileType;%0Aimport com.intellij.openapi.fileTypes.FileTypeManager;%0Aimport com.intellij.openapi.fileTypes.FileTypes;%0A
 import com.intel
@@ -443,24 +443,24 @@
 irtualFile;%0A
-
 import com.i
@@ -1071,24 +1071,320 @@
 ;%0A%0A    try%7B%0A
+      final FileType newFileType = FileTypeManager.getInstance().getFileTypeByFileName(newName);%0A      if (FileTypes.UNKNOWN.equals(newFileType) %7C%7C newFileType.isBinary()) %7B%0A        // before the file becomes unknown or a binary (thus, not openable in the editor), save it to prevent data loss%0A  
       final 
@@ -1446,24 +1446,26 @@
 ce();%0A      
+  
 final Docume
@@ -1499,24 +1499,26 @@
 ent(vFile);%0A
+  
       if (do
@@ -1538,16 +1538,18 @@
         
+  
 EditorSe
@@ -1638,25 +1638,28 @@
         
-%0A
+  %0A 
         
 String t
@@ -1650,16 +1650,17 @@
         
+ 
 String t
@@ -1705,24 +1705,26 @@
 ngSpaces();%0A
+  
         edit
@@ -1815,16 +1815,18 @@
 _NONE);%0A
+  
         
@@ -1841,16 +1841,18 @@
         
+  
 fdm.save
@@ -1866,32 +1866,34 @@
 t(doc);%0A        
+  
 %7D%0A        finall
@@ -1882,24 +1882,26 @@
   %7D%0A        
+ 
+ 
 finally %7B%0A  
@@ -1894,24 +1894,26 @@
   finally %7B%0A
+  
           ed
@@ -1954,24 +1954,36 @@
 s(trailer);%0A
+          %7D%0A
         %7D%0A  
@@ -1988,22 +1988,16 @@
       %7D%0A
-      
 %0A      v

save file content before rename only if after rename the file type will become unknown to idea or binary