package com.intellij.openapi.vcs.checkout;

import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vcs.CheckoutProvider;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;

import java.io.File;

public class CheckoutAction extends AnAction {
  private final CheckoutProvider myProvider;

  public CheckoutAction(final CheckoutProvider provider) {
    myProvider = provider;
  }

  public void actionPerformed(AnActionEvent e) {
    final Project project = e.getData(DataKeys.PROJECT);
    myProvider.doCheckout(new MyListener(project));
  }

  private static void refreshVFS(final File directory) {
    ApplicationManager.getApplication().runWriteAction(new Runnable() {
      public void run() {
        final LocalFileSystem lfs = LocalFileSystem.getInstance();
        final VirtualFile vDir = lfs.refreshAndFindFileByIoFile(directory);
        assert vDir != null;
        final LocalFileSystem.WatchRequest watchRequest = lfs.addRootToWatch(vDir.getPath(), true);
        assert watchRequest != null;
        ((NewVirtualFile)vDir).markDirtyRecursively();
        vDir.refresh(false, true);
        lfs.removeWatchedRoot(watchRequest);
      }
    });
  }

  private static void processNoProject(final Project project, final File directory) {
    int rc = Messages.showYesNoDialog(project, VcsBundle.message("checkout.create.project.prompt", directory.getAbsolutePath()),
                                      VcsBundle.message("checkout.title"), Messages.getQuestionIcon());
    if (rc == 0) {
      ProjectUtil.createNewProject(project, directory.getAbsolutePath());
    }
  }

  public void update(AnActionEvent e) {
    super.update(e);
    e.getPresentation().setText(myProvider.getVcsName(), true);
  }

  private static class MyListener implements CheckoutProvider.Listener {
    private final Project myProject;
    private boolean myFoundProject = false;
    private File myFirstDirectory;

    public MyListener(final Project project) {
      myProject = project;
    }

    public void directoryCheckedOut(final File directory) {
      if (myFirstDirectory == null) {
        myFirstDirectory = directory;
      }
      if (!myFoundProject) {
        refreshVFS(directory);
        CheckoutListener[] listeners = Extensions.getExtensions(CheckoutListener.EP_NAME);
        for(CheckoutListener listener: listeners) {
          myFoundProject = listener.processCheckedOutDirectory(myProject, directory);
          if (myFoundProject) break;
        }
      }
    }

    public void checkoutCompleted() {
      if (!myFoundProject && myFirstDirectory != null) {
        processNoProject(myProject, myFirstDirectory);
      }
    }
  }
}

@@ -301,59 +301,8 @@
 er;%0A
-import com.intellij.openapi.extensions.Extensions;%0A
 impo
@@ -383,16 +383,54 @@
 ssages;%0A
+import com.intellij.openapi.util.Ref;%0A
 import c
@@ -662,16 +662,67 @@
 ualFile;
+%0Aimport com.intellij.openapi.extensions.Extensions;
 %0A%0Aimport
@@ -1101,20 +1101,27 @@
  static 
-void
+VirtualFile
  refresh
@@ -1144,24 +1144,84 @@
 irectory) %7B%0A
+    final Ref%3CVirtualFile%3E result = new Ref%3CVirtualFile%3E();%0A
     Applicat
@@ -1457,23 +1457,46 @@
         
-assert 
+result.set(vDir);%0A        if (
 vDir != 
@@ -1491,34 +1491,38 @@
 if (vDir != null
-;%0A
+) %7B%0A  
         final Lo
@@ -1613,16 +1613,18 @@
         
+  
 assert w
@@ -1644,16 +1644,18 @@
 = null;%0A
+  
         
@@ -1709,16 +1709,18 @@
         
+ 
+ 
 vDir.ref
@@ -1730,32 +1730,34 @@
 h(false, true);%0A
+  
         lfs.remo
@@ -1791,23 +1791,58 @@
 ;%0A      
-%7D%0A    %7D
+  %7D%0A      %7D%0A    %7D);%0A    return result.get(
 );%0A  %7D%0A%0A
@@ -2739,63 +2739,78 @@
 if (
+!
 myF
-irstDirectory == null) %7B%0A        myFirstDirectory = 
+oundProject) %7B%0A        final VirtualFile virtualFile = refreshVFS(
 dire
@@ -2814,24 +2814,25 @@
 irectory
+)
 ;%0A      
 %7D%0A      
@@ -2827,35 +2827,75 @@
     
+  
-%7D%0A
+if (virtualFile != null) %7B%0A  
       
+  
 if (
-!
 myF
-oundProject
+irstDirectory == null
 ) %7B%0A
@@ -2902,27 +2902,39 @@
         
+   
-refreshVFS(
+ myFirstDirectory = 
 director
@@ -2926,35 +2926,48 @@
 tory = directory
-)
 ;%0A
+          %7D%0A  
         Checkout
@@ -3049,16 +3049,18 @@
         
+ 
+ 
 for(Chec
@@ -3091,24 +3091,26 @@
 isteners) %7B%0A
+  
           my
@@ -3189,24 +3189,26 @@
 ;%0A          
+  
 if (myFoundP
@@ -3222,16 +3222,28 @@
  break;%0A
+          %7D%0A
         

fix assertion (IDEADEV-16330)