/*
 * 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.util.indexing;

import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;

import java.util.Set;

/**
 * @author peter
 */
public class AdditionalIndexableFileSet implements IndexableFileSet {

  private NotNullLazyValue<Set<VirtualFile>> myRoots = new NotNullLazyValue<Set<VirtualFile>>() {
    @NotNull
    @Override
    protected Set<VirtualFile> compute() {
      THashSet<VirtualFile> virtualFiles = new THashSet<VirtualFile>();
      if (myExtensions == null) {
        myExtensions = Extensions.getExtensions(IndexableSetContributor.EP_NAME);
      }
        for (IndexedRootsProvider provider : myExtensions) {
          virtualFiles.addAll(IndexableSetContributor.getRootsToIndex(provider));
        }
      return virtualFiles;
    }
  };

  private IndexedRootsProvider[] myExtensions;

  public AdditionalIndexableFileSet() {
  }

  public AdditionalIndexableFileSet(IndexedRootsProvider... extensions) {
    myExtensions = extensions;
  }

  public boolean isInSet(VirtualFile file) {
    for (final VirtualFile root : myRoots.getValue()) {
      if (VfsUtil.isAncestor(root, file, false)) {
        return true;
      }
    }
    return false;
  }

  public void iterateIndexableFilesIn(VirtualFile file, ContentIterator iterator) {
    if (!isInSet(file)) return;

    if (file.isDirectory()) {
      for (VirtualFile child : file.getChildren()) {
        iterateIndexableFilesIn(child, iterator);
      }
    }
    else {
      iterator.processFile(file);
    }
  }
}

@@ -737,59 +737,8 @@
 or;%0A
-import com.intellij.openapi.util.NotNullLazyValue;%0A
 impo
@@ -849,50 +849,8 @@
 Set;
-%0Aimport org.jetbrains.annotations.NotNull;
 %0A%0Aim
@@ -965,17 +965,16 @@
 leSet %7B%0A
-%0A
   privat
@@ -979,136 +979,430 @@
 ate 
-NotNullLazyValue%3CSet%3CVirtualFile%3E%3E myRoots = new NotNullLazyValue%3CSet%3CVirtualFile%3E%3E() %7B%0A    @NotNull%0A    @Override%0A    protec
+volatile Set%3CVirtualFile%3E cachedFiles;%0A  private volatile IndexedRootsProvider%5B%5D myExtensions;%0A%0A  public AdditionalIndexableFileSet(IndexedRootsProvider... extensions) %7B%0A    myExtensions = extensions;%0A  %7D%0A%0A  private Set%3CVirtualFile%3E getFiles() %7B%0A    Set%3CVirtualFile%3E files = cachedFiles;%0A    if (files == null %7C%7C filesInvalidated(files)) %7B%0A      cachedFiles = files = collectFiles();%0A    %7D%0A    return files;%0A  %7D%0A%0A  priva
 te
-d
  Set
@@ -1421,13 +1421,18 @@
 %3E co
-mpute
+llectFiles
 () %7B
@@ -1436,18 +1436,16 @@
 ) %7B%0A    
- 
- 
 THashSet
@@ -1502,18 +1502,16 @@
 ile%3E();%0A
-  
     if (
@@ -1540,18 +1540,16 @@
 %7B%0A      
-  
 myExtens
@@ -1618,24 +1618,18 @@
 E);%0A    
- 
- 
 %7D%0A
-    
     for 
@@ -1683,20 +1683,16 @@
 %7B%0A      
-    
 virtualF
@@ -1759,24 +1759,18 @@
 ));%0A    
-    %7D%0A  
+%7D%0A
     retu
@@ -1792,215 +1792,241 @@
 ;%0A  
- 
- %7D%0A  %7D;%0A%0A  private IndexedRootsProvider%5B%5D myExtensions;%0A%0A  public AdditionalIndexableFileSet() %7B%0A  %7D%0A%0A  public AdditionalIndexableFileSet(IndexedRootsProvider... extensions) %7B%0A    myExtensions = extensions;
+%7D%0A%0A  public static boolean filesInvalidated(Set%3CVirtualFile%3E files) %7B%0A    for (VirtualFile file : files) %7B%0A      if (!file.isValid()) %7B%0A        return true;%0A      %7D%0A    %7D%0A    return false;%0A  %7D%0A%0A  public AdditionalIndexableFileSet() %7B
 %0A  %7D
@@ -2110,24 +2110,16 @@
 t : 
-myRoots.getValue
+getFiles
 ()) 

fix invalid virtual file access when indexing files from additional roots