Index: src/org/armedbear/lisp/IkvmSite.java
===================================================================
--- src/org/armedbear/lisp/IkvmSite.java	(revision 0)
+++ src/org/armedbear/lisp/IkvmSite.java	(revision 0)
@@ -0,0 +1,244 @@
+/*
+ * IkvmSite.java
+ *
+ * Copyright (C) 2003-2005 Peter Graves
+ * $Id: Site.java 11391 2008-11-15 22:38:34Z vvoutilainen $
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module.  An independent module is a module which is not derived from
+ * or based on this library.  If you modify this library, you may extend
+ * this exception to your version of the library, but you are not
+ * obligated to do so.  If you do not wish to do so, delete this
+ * exception statement from your version.
+ */
+
+package org.armedbear.lisp;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+
+public final class IkvmSite extends Lisp {
+
+  /**
+   * Unpack and create a temporary file from a .NET Assembly if needed
+   * 
+   * @param {@link java.io.File} jfile
+   * @return temporary {@link java.io.File} unpacked from a .NET Assembly
+   */
+  public static File ikvmFileSafe(File jfile) {
+    //  if (!Site.isIKVMDll()) return filename;
+    try {
+      final File ifile = ikvmFile(jfile.getPath());
+      if (ifile.exists()) return ifile;
+    } catch (IOException e) {
+    }
+    return jfile;
+  }
+
+  final static HashMap extractionMap = new HashMap();
+
+  /**
+   * Unpack and create a temporary file from a .NET Assembly
+   * 
+   * @param {@link java.lang.String} filename
+   * @return temporary {@link java.io.File} unpacked from a .NET Assembly
+   */
+  public static File ikvmFile(String filename) throws IOException {
+    File file = new File(filename);
+    //  System.err.println("// IKVM = " + file);        
+    if (file.exists()) return file;
+    // directories are real even when they do not yet exist
+    try {
+      if (file.isDirectory()) return file;
+    } catch (Throwable dotnetOnly) {
+
+    }
+    //  if (!Site.isIKVMDll()) return file;
+    // if (file.getPath().endsWith("top-level.abcl")) return file;
+    {
+      File knownFile = (File) extractionMap.get(filename);
+      if (knownFile != null) return knownFile;
+    }
+
+    URL res = Lisp.class.getResource(filename);
+    if (res == null) {
+      if (Utilities.isPlatformWindows) {
+        String revSlash = filename.replace("\\", "/");
+        //someone stripped the "/" ?
+        if (revSlash.charAt(0) != '/') revSlash = "/" + revSlash;
+        if (!revSlash.equals(filename)) {
+          res = Lisp.class.getResource(revSlash);
+        }
+      }
+    }
+    if (res == null) {
+      // System.err.println("// No File = " + file);            
+      return file;//throw new FileNotFoundException(filename);
+    }
+    // System.err.println("// IKVM = " + file);            
+    if (res.getProtocol().equals("ikvmres")) {
+      URLConnection connection = res.openConnection();
+      InputStream in = connection.getInputStream();
+      if (in != null) {
+        {
+          String ikvmFileWithExt = new File(filename).getName();
+          int index = ikvmFileWithExt.lastIndexOf(File.separatorChar);
+          if (index > 0) ikvmFileWithExt = ikvmFileWithExt.substring(index);
+          //  index = ext.lastIndexOf('.');
+          //if (index > 0) ext = ext.substring(index);
+          file = new File(IKVM_LISP_TEMP, ikvmFileWithExt);
+          //  file = File.createTempFile(IKVM_LISP_TEMP.getParent(), ext);//.getTempFile(cacheDir);
+          //System.err.println("// IKVM Unpacking Dll file " + filename + " to " + file);//IKVM_LISP_TEMP.getParent() +"$"+ ext);
+        }
+        if (!file.exists()) {
+          file.getParentFile().mkdirs();
+        }
+        System.out.println(";;IKVM baking " + file + " from " + filename);
+        OutputStream out = new FileOutputStream(file);
+        byte[] buf = new byte[4096];
+        int bytesRead;
+        in = new DataInputStream(in);
+        //          int total = 0;
+        while ((bytesRead = in.read(buf)) > 0) {
+          //            System.err.println("// read="+bytesRead);
+          //            int print = 10;
+          //            if (bytesRead<print) print = bytesRead;
+          //            for (int printi=0;printi<print;printi++) {
+          //              System.out.println(" // byte="+buf[printi] + " c="+((char)buf[printi]));
+          //            }
+          //            total += bytesRead;
+
+          out.write(buf, 0, bytesRead);
+        }
+        //          System.err.println("// write="+total);
+        out.close();
+        in.close();
+        extractionMap.put(filename, file);
+        //        System.err.println("// zipFileName 1.1 = " + file);            
+        return file;
+      }
+    }
+    return file;
+  }
+
+  private static final String IKVM_LISP_HOME;
+  private static final File IKVM_LISP_TEMP;
+
+  private static boolean knowsAboutIKVM = false;
+  private static boolean isIKVM = false;
+  private static boolean isIKVMDll = false;
+
+  public static synchronized boolean isIKVM() /*throws ConditionThrowable*/{
+    if (!knowsAboutIKVM) {
+      knowsAboutIKVM = true;
+      String vmname = System.getProperty("java.vm.name");
+      if (vmname == null || !vmname.toLowerCase().contains("ikvm")) return false;
+      isIKVM = true;
+      try {
+        addIkvmFeature();
+      } catch (ConditionThrowable e) {
+      }
+      URL url = Lisp.class.getResource("boot.lisp");
+      if (url != null) {
+        String protocol = url.getProtocol();
+        if (protocol != null && protocol.equals("ikvmres")) {
+          isIKVMDll = true;
+
+        }
+      }
+    }
+    return isIKVM;
+  }
+
+  /**
+   * 
+   */
+  private static void addIkvmFeature() throws ConditionThrowable {
+    // TODO Auto-generated method stub
+    Symbol featureVar = Symbol.FEATURES;
+    LispObject features = featureVar.symbolValue();
+    features = features.push(Lisp.internKeyword("IKVM"));
+    featureVar.setSymbolValue(features);
+  }
+
+  public static boolean isIKVMDll() {
+    return isIKVM() && isIKVMDll;
+  }
+
+  static {
+    String lispHome = null;
+    File lispTemp = null;
+    isIKVM();
+    URL url = Lisp.class.getResource("boot.lisp");
+    if (url != null) {
+      String protocol = url.getProtocol();
+      if (protocol != null && (protocol.equals("file") || (protocol.equals("ikvmres")))) {
+        String path = url.getPath();
+        int index = path.lastIndexOf('/');
+        if (index >= 0) {
+          lispHome = path.substring(0, index + 1);
+          if (Utilities.isPlatformWindows) {
+            if (lispHome.length() > 0 && lispHome.charAt(0) == '/') lispHome = lispHome.substring(1);
+          }
+        }
+      }
+    }
+    //System.out.println("// IKVM Lisp home = " + lispHome);
+    try {
+      lispTemp = File.createTempFile("ikvm", null).getParentFile();
+      File subdir = new File(lispTemp.getAbsolutePath()+"/ikvm");
+    	  subdir.mkdirs();
+    	  if (subdir.isDirectory())
+    		  lispTemp = subdir;      
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+    IKVM_LISP_TEMP = lispTemp;
+    IKVM_LISP_HOME = lispHome;
+  }
+
+  public static final String getIKVMLispHome() {
+    return IKVM_LISP_HOME;
+  }
+
+  // ### *ikvm-lisp-home*
+  private static final Symbol _IKVM_LISP_HOME_ = exportSpecial("*IKVM-LISP-HOME*", PACKAGE_EXT, NIL);
+
+  static {
+    try {
+      String s = getIKVMLispHome();
+      if (s != null) _IKVM_LISP_HOME_.setSymbolValue(new Pathname(s));
+    } catch (Throwable t) {
+      Debug.trace(t);
+    }
+  }
+}
\ No newline at end of file
Index: src/org/armedbear/lisp/Complex.java
===================================================================
--- src/org/armedbear/lisp/Complex.java	(revision 11724)
+++ src/org/armedbear/lisp/Complex.java	(working copy)
@@ -304,6 +304,7 @@
 
   private static Method hypotMethod = null;
   static { try {
+	  if (!IkvmSite.isIKVM())
       hypotMethod = 
           Class.forName("java.lang.Math")
           .getMethod("hypot", new Class[] { Double.TYPE, Double.TYPE });
Index: src/org/armedbear/lisp/Nil.java
===================================================================
--- src/org/armedbear/lisp/Nil.java	(revision 11724)
+++ src/org/armedbear/lisp/Nil.java	(working copy)
@@ -35,6 +35,7 @@
 
 public final class Nil extends Symbol
 {
+  static final Nil NIL =  new Nil(PACKAGE_CL);
     public Nil(Package pkg)
     {
         super("NIL", pkg);
Index: src/org/armedbear/lisp/Lisp.java
===================================================================
--- src/org/armedbear/lisp/Lisp.java	(revision 11724)
+++ src/org/armedbear/lisp/Lisp.java	(working copy)
@@ -80,7 +80,7 @@
   // ### nil
   // Constructing NIL forces the Symbol class to be loaded (since Nil extends
   // Symbol).
-  public static final LispObject NIL = new Nil(PACKAGE_CL);
+  public static final LispObject NIL = Nil.NIL;
 
   // We need NIL before we can call usePackage().
   static
@@ -1023,7 +1023,7 @@
                               zipFileName = zipFileName.substring(1);
 			  }
 			zipFileName = URLDecoder.decode(zipFileName, "UTF-8");
-                        ZipFile zipFile = new ZipFile(zipFileName);
+                        ZipFile zipFile = new ZipFile(IkvmSite.ikvmFile(zipFileName));
                         try
                           {
                             ZipEntry entry = zipFile.getEntry(entryName);
@@ -1059,7 +1059,11 @@
         return error(new LispError("Unable to load " + namestring));
       }
     Pathname pathname = new Pathname(namestring);
-    final File file = Utilities.getFile(pathname, defaultPathname);
+    File file = Utilities.getFile(pathname, defaultPathname);
+    if (file != null && !file.isFile()) {
+    	 // maybe IKVM?
+    	 file = IkvmSite.ikvmFileSafe(file);
+    }
     if (file != null && file.isFile())
       {
         // The .cls file exists.
@@ -1087,7 +1091,7 @@
       {
         LispObject loadTruename = Symbol.LOAD_TRUENAME.symbolValue(thread);
         String zipFileName = ((Pathname)loadTruename).getNamestring();
-        ZipFile zipFile = new ZipFile(zipFileName);
+        ZipFile zipFile = new ZipFile(IkvmSite.ikvmFile(zipFileName));
         try
           {
             ZipEntry entry = zipFile.getEntry(namestring);
Index: src/org/armedbear/lisp/Load.java
===================================================================
--- src/org/armedbear/lisp/Load.java	(revision 11724)
+++ src/org/armedbear/lisp/Load.java	(working copy)
@@ -64,8 +64,8 @@
 	    String extension = getExtension(filename);
 	    if (extension == null) {
 		// No extension specified. Try appending ".lisp" or ".abcl".
-		File lispFile = new File(dir, filename.concat(".lisp"));
-		File abclFile = new File(dir, filename.concat(".abcl"));
+		File lispFile = IkvmSite.ikvmFileSafe(new File(dir, filename.concat(".lisp")));
+		File abclFile = IkvmSite.ikvmFileSafe(new File(dir, filename.concat(".abcl")));
 		if (lispFile.isFile() && abclFile.isFile()) {
 		    if (abclFile.lastModified() > lispFile.lastModified()) {
 			return abclFile;
@@ -246,7 +246,7 @@
             final String dir = Site.getLispHome();
             try {
                 if (dir != null) {
-                    File file = new File(dir, s);
+                    File file = IkvmSite.ikvmFileSafe(new File(dir, s));
                     if (file.isFile()) {
                         // File exists. For system files, we know the extension
                         // will be .abcl if it is a compiled file.
@@ -336,7 +336,7 @@
         }
         return error(new LispError("File not found: " + filename));
     }
-
+        
     // ### *fasl-version*
     // internal symbol
     private static final Symbol _FASL_VERSION_ =
Index: src/org/armedbear/lisp/Pathname.java
===================================================================
--- src/org/armedbear/lisp/Pathname.java	(revision 11724)
+++ src/org/armedbear/lisp/Pathname.java	(working copy)
@@ -88,6 +88,14 @@
                 init(s.substring(5));
                 return;
             }
+        } else if ("ikvmres".equals(protocol)) {
+            String s = url.getPath();
+            if (s != null && s.startsWith("file:")) {
+                init(s.substring(5));
+                return;
+            } //Else
+           init(s);
+           return;
         }
         error(new LispError("Unsupported URL: \"" + url.toString() + '"'));
     }
@@ -1330,7 +1338,7 @@
             if (originalNamestring != null && newNamestring != null) {
                 final File source = new File(originalNamestring);
                 final File destination = new File(newNamestring);
-                if (Utilities.isPlatformWindows) {
+                if (Utilities.isPlatformWindows || IkvmSite.isIKVM()) {
                     if (destination.isFile())
                         destination.delete();
                 }
