/**
 * @author Yura Cangea
 */
package com.intellij.openapi.fileChooser.impl;

import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileElement;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.util.StatusBarProgress;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.util.Comparator;

import org.jetbrains.annotations.NotNull;

public class FileTreeBuilder extends AbstractTreeBuilder {
  private final FileChooserDescriptor myChooserDescriptor;

  private VirtualFileAdapter myVirtualFileListener;


  public FileTreeBuilder(JTree tree, DefaultTreeModel treeModel,
                         AbstractTreeStructure treeStructure,
                         Comparator<NodeDescriptor> comparator,
                         FileChooserDescriptor chooserDescriptor) {
    super(tree, treeModel, treeStructure, comparator);
    myChooserDescriptor = chooserDescriptor;
    initRootNode();

    installVirtualFileListener();
  }

  private void installVirtualFileListener() {
    myVirtualFileListener = new VirtualFileAdapter() {
      public void propertyChanged(VirtualFilePropertyEvent event) {
        myUpdater.addSubtreeToUpdate(myRootNode);
      }

      public void fileCreated(VirtualFileEvent event) {
        myUpdater.addSubtreeToUpdate(myRootNode);
      }

      public void fileDeleted(VirtualFileEvent event) {
        myUpdater.addSubtreeToUpdate(myRootNode);
      }

      public void fileMoved(VirtualFileMoveEvent event) {
        myUpdater.addSubtreeToUpdate(myRootNode);
      }
    };

    VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener);
  }

  public final void dispose() {
    VirtualFileManager.getInstance().removeVirtualFileListener(myVirtualFileListener);
    super.dispose();
  }

  protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) {
    final Object element = nodeDescriptor.getElement();
    if (element != null){
      FileElement descriptor = (FileElement)element;
      VirtualFile file = descriptor.getFile();
      if (file != null){
        if (myChooserDescriptor.isChooseJarContents() && FileElement.isArchive(file)) {
          return true;
        }
        if (file.isDirectory()) {
          return true;
        }
        return false;
      }
    }
    return true;
  }

  protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) {
    return false;
  }

  protected final void expandNodeChildren(DefaultMutableTreeNode node) {
    Object element = ((NodeDescriptor)node.getUserObject()).getElement();
    if (element instanceof FileElement){
      final VirtualFile file = ((FileElement)element).getFile();
      if (file != null && file.isValid()){
        ApplicationManager.getApplication().runWriteAction(
          new Runnable() {
            public void run() {
              file.refresh(false, false);
            }
          }
        );
      }
    }
    super.expandNodeChildren(node);
  }

  @NotNull
  protected ProgressIndicator createProgressIndicator() {
    return new StatusBarProgress();
  }
}

@@ -426,43 +426,8 @@
 nt;%0A
-import com.intellij.openapi.vfs.*;%0A
 impo
@@ -538,16 +538,93 @@
 rogress;
+%0Aimport com.intellij.openapi.vfs.*;%0Aimport org.jetbrains.annotations.NotNull;
 %0A%0Aimport
@@ -763,51 +763,8 @@
 r;%0A%0A
-import org.jetbrains.annotations.NotNull;%0A%0A
 publ
@@ -2864,26 +2864,42 @@
     
-Object element
+final NodeDescriptor descriptor
  = 
-(
 (Nod
@@ -2930,17 +2930,49 @@
 Object()
-)
+;%0A    Object element = descriptor
 .getElem

extract variable