Index: lucene/src/java/org/apache/lucene/index/IndexUpgrader.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/IndexUpgrader.java	(revision 1211424)
+++ lucene/src/java/org/apache/lucene/index/IndexUpgrader.java	(working copy)
@@ -54,36 +54,56 @@
   private static void printUsage() {
     System.err.println("Upgrades an index so all segments created with a previous Lucene version are rewritten.");
     System.err.println("Usage:");
-    System.err.println("  java " + IndexUpgrader.class.getName() + " [-delete-prior-commits] [-verbose] indexDir");
+    System.err.println("  java " + IndexUpgrader.class.getName() + " [-delete-prior-commits] [-verbose] [-dir-impl X] indexDir");
     System.err.println("This tool keeps only the last commit in an index; for this");
     System.err.println("reason, if the incoming index has more than one commit, the tool");
     System.err.println("refuses to run by default. Specify -delete-prior-commits to override");
     System.err.println("this, allowing the tool to delete all but the last commit.");
+    System.err.println("Specify a " + FSDirectory.class.getSimpleName() + 
+        " implementation through the -dir-impl option to forse its use. If no package is specified the " 
+        + FSDirectory.class.getPackage().getName() + " package will be used.");
     System.err.println("WARNING: This tool may reorder document IDs!");
     System.exit(1);
   }
 
   @SuppressWarnings("deprecation")
   public static void main(String[] args) throws IOException {
-    String dir = null;
+    String path = null;
     boolean deletePriorCommits = false;
     PrintStream out = null;
-    for (String arg : args) {
+    String dirImpl = null;
+    int i = 0;
+    while (i<args.length) {
+      String arg = args[i];
       if ("-delete-prior-commits".equals(arg)) {
         deletePriorCommits = true;
       } else if ("-verbose".equals(arg)) {
         out = System.out;
-      } else if (dir == null) {
-        dir = arg;
-      } else {
+      } else if (path == null) {
+        path = arg;
+      } else if ("-dir-impl".equals(arg)) {
+        if (i == args.length - 1) {
+          System.out.println("ERROR: missing value for -dir-impl option");
+          System.exit(1);
+        }
+        i++;
+        dirImpl = args[i];
+      }else {
         printUsage();
       }
+      i++;
     }
-    if (dir == null) {
+    if (path == null) {
       printUsage();
     }
     
-    new IndexUpgrader(FSDirectory.open(new File(dir)), Version.LUCENE_CURRENT, out, deletePriorCommits).upgrade();
+    Directory dir = null;
+    if (dirImpl == null) {
+      dir = FSDirectory.open(new File(path));
+    } else {
+      dir = FSDirectory.open(new File(path), dirImpl);
+    }
+    new IndexUpgrader(dir, Version.LUCENE_CURRENT, out, deletePriorCommits).upgrade();
   }
   
   private final Directory dir;
Index: lucene/src/java/org/apache/lucene/index/IndexReader.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/IndexReader.java	(revision 1211424)
+++ lucene/src/java/org/apache/lucene/index/IndexReader.java	(working copy)
@@ -1322,17 +1322,28 @@
   public static void main(String [] args) {
     String filename = null;
     boolean extract = false;
+    String dirImpl = null;
 
-    for (int i = 0; i < args.length; ++i) {
-      if (args[i].equals("-extract")) {
+    int j = 0;
+    while(j < args.length) {
+      String arg = args[j];
+      if ("-extract".equals(arg)) {
         extract = true;
+      } else if ("-dir-impl".equals(arg)) {
+        if (j == args.length - 1) {
+          System.out.println("ERROR: missing value for -dir-impl option");
+          System.exit(1);
+        }
+        j++;
+        dirImpl = args[j];
       } else if (filename == null) {
-        filename = args[i];
+        filename = arg;
       }
+      j++;
     }
 
     if (filename == null) {
-      System.out.println("Usage: org.apache.lucene.index.IndexReader [-extract] <cfsfile>");
+      System.out.println("Usage: org.apache.lucene.index.IndexReader [-extract] [-dir-impl X] <cfsfile>");
       return;
     }
 
@@ -1344,7 +1355,12 @@
       File file = new File(filename);
       String dirname = file.getAbsoluteFile().getParent();
       filename = file.getName();
-      dir = FSDirectory.open(new File(dirname));
+      if (dirImpl == null) {
+        dir = FSDirectory.open(new File(dirname));
+      } else {
+        dir = FSDirectory.open(new File(dirname), dirImpl);
+      }
+      
       cfr = new CompoundFileDirectory(dir, filename, IOContext.DEFAULT, false);
 
       String [] files = cfr.listAll();
Index: lucene/src/java/org/apache/lucene/index/CheckIndex.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/CheckIndex.java	(revision 1211424)
+++ lucene/src/java/org/apache/lucene/index/CheckIndex.java	(working copy)
@@ -17,15 +17,6 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.document.FieldType; // for javadocs
-import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.IOContext;
-import org.apache.lucene.store.IndexInput;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.index.codecs.Codec;
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintStream;
@@ -37,11 +28,20 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.FieldType;
 import org.apache.lucene.index.codecs.BlockTreeTermsReader;
+import org.apache.lucene.index.codecs.Codec;
 import org.apache.lucene.index.codecs.PerDocValues;
 import org.apache.lucene.index.values.IndexDocValues;
 import org.apache.lucene.index.values.IndexDocValues.Source;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.FSDirectory;
+import org.apache.lucene.store.IOContext;
+import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.FixedBitSet;
@@ -1408,41 +1408,48 @@
     boolean verbose = false;
     List<String> onlySegments = new ArrayList<String>();
     String indexPath = null;
+    String dirImpl = null;
     int i = 0;
     while(i < args.length) {
-      if (args[i].equals("-fix")) {
+      String arg = args[i];
+      if ("-fix".equals(arg)) {
         doFix = true;
-        i++;
-      } else if (args[i].equals("-codec")) {
+      } else if ("-codec".equals(arg)) {
         if (i == args.length-1) {
           System.out.println("ERROR: missing name for -codec option");
           System.exit(1);
         }
-        codec = Codec.forName(args[i+1]);
-        i+=2;
-      } else if (args[i].equals("-verbose")) {
+        i++;
+        codec = Codec.forName(args[i]);
+      } else if (arg.equals("-verbose")) {
         verbose = true;
-        i++;
-      } else if (args[i].equals("-segment")) {
+      } else if (arg.equals("-segment")) {
         if (i == args.length-1) {
           System.out.println("ERROR: missing name for -segment option");
           System.exit(1);
         }
-        onlySegments.add(args[i+1]);
-        i += 2;
+        i++;
+        onlySegments.add(args[i]);
+      } else if ("-dir-impl".equals(arg)) {
+        if (i == args.length - 1) {
+          System.out.println("ERROR: missing value for -dir-impl option");
+          System.exit(1);
+        }
+        i++;
+        dirImpl = args[i];
       } else {
         if (indexPath != null) {
           System.out.println("ERROR: unexpected extra argument '" + args[i] + "'");
           System.exit(1);
         }
         indexPath = args[i];
-        i++;
       }
+      i++;
     }
 
     if (indexPath == null) {
       System.out.println("\nERROR: index path not specified");
-      System.out.println("\nUsage: java org.apache.lucene.index.CheckIndex pathToIndex [-fix] [-segment X] [-segment Y]\n" +
+      System.out.println("\nUsage: java org.apache.lucene.index.CheckIndex pathToIndex [-fix] [-segment X] [-segment Y] [-dir-impl X]\n" +
                          "\n" +
                          "  -fix: actually write a new segments_N file, removing any problematic segments\n" +
                          "  -codec X: when fixing, codec to write the new segments_N file with\n" +
@@ -1450,7 +1457,8 @@
                          "  -segment X: only check the specified segments.  This can be specified multiple\n" + 
                          "              times, to check more than one segment, eg '-segment _2 -segment _a'.\n" +
                          "              You can't use this with the -fix option\n" +
-                         "\n" + 
+                         "  -dir-impl X: use a specific " + FSDirectory.class.getSimpleName() + " implementation. " +
+                         		"If no package is specified the " + FSDirectory.class.getPackage().getName() + " package will be used.\n" +
                          "**WARNING**: -fix should only be used on an emergency basis as it will cause\n" +
                          "documents (perhaps many) to be permanently removed from the index.  Always make\n" +
                          "a backup copy of your index before running this!  Do not run this tool on an index\n" +
@@ -1480,7 +1488,11 @@
     System.out.println("\nOpening index @ " + indexPath + "\n");
     Directory dir = null;
     try {
-      dir = FSDirectory.open(new File(indexPath));
+      if (dirImpl == null) {
+        dir = FSDirectory.open(new File(indexPath));
+      } else {
+        dir = FSDirectory.open(new File(indexPath), dirImpl);
+      }
     } catch (Throwable t) {
       System.out.println("ERROR: could not open directory \"" + indexPath + "\"; exiting");
       t.printStackTrace(System.out);
Index: lucene/src/java/org/apache/lucene/store/FSDirectory.java
===================================================================
--- lucene/src/java/org/apache/lucene/store/FSDirectory.java	(revision 1211424)
+++ lucene/src/java/org/apache/lucene/store/FSDirectory.java	(working copy)
@@ -17,20 +17,22 @@
  * limitations under the License.
  */
 
+import static java.util.Collections.synchronizedSet;
+
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.RandomAccessFile;
-
+import java.lang.reflect.Constructor;
 import java.util.Collection;
-import static java.util.Collections.synchronizedSet;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.Future;
 
+import org.apache.commons.lang.StringUtils;
+import org.apache.lucene.util.Constants;
 import org.apache.lucene.util.ThreadInterruptedException;
-import org.apache.lucene.util.Constants;
 
 /**
  * <a name="subclasses"/>
@@ -170,8 +172,40 @@
    *
    * <p>See <a href="#subclasses">above</a> */
   public static FSDirectory open(File path) throws IOException {
-    return open(path, null);
+    return open(path, (LockFactory)null);
   }
+  
+  
+  public static FSDirectory open(File path, String dirImpl) throws IOException {
+    
+    if (StringUtils.isEmpty(dirImpl)) {
+      throw new IllegalArgumentException("The " + FSDirectory.class.getSimpleName() + " implementation cannot be null or empty");
+    }
+    
+    if (dirImpl.indexOf('.') == -1) {
+      dirImpl = FSDirectory.class.getPackage().getName() + "." + dirImpl;
+    }
+    
+    Class<? extends FSDirectory> dirClass;
+    try {
+      dirClass = Class.forName(dirImpl).asSubclass(FSDirectory.class);
+    } catch (ClassNotFoundException e) {
+      throw new IllegalArgumentException(FSDirectory.class.getSimpleName() + " implementation not found: " + dirImpl, e);
+    }
+    
+    Constructor<? extends FSDirectory> constructor;
+    try {
+      constructor = dirClass.getConstructor(File.class);
+    } catch (NoSuchMethodException e) {
+      throw new IllegalArgumentException(dirImpl + " constructor with " + File.class.getSimpleName() + " as parameter not found", e);
+    }
+    try {
+      return constructor.newInstance(path);
+    } catch (Exception e) {
+      throw new IllegalArgumentException("Error creating " + dirImpl + " instance", e);
+    } 
+  }
+  
 
   /** Just like {@link #open(File)}, but allows you to
    *  also specify a custom {@link LockFactory}. */
