diff --git a/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java b/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java
index f4fc2320939baea748d7e7236b238df5eefae080..a749e97a1458b010acd6189bcdf521cf6bc8ff96 100644
--- a/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java
+++ b/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java
@@ -16,24 +16,31 @@ package freenet.support.CPUInformation;
  */
 public interface AMDCPUInfo extends CPUInfo {
     /**
-     * @return true iff the CPU present in the machine is at least an 'k6' CPU
+     * @return true if the CPU present in the machine is at least an 'k6' CPU
      */
     public boolean IsK6Compatible();
     /**
-     * @return true iff the CPU present in the machine is at least an 'k6-2' CPU
+     * @return true if the CPU present in the machine is at least an 'k6-2' CPU
      */
     public boolean IsK6_2_Compatible();
     /**
-     * @return true iff the CPU present in the machine is at least an 'k6-3' CPU
+     * @return true if the CPU present in the machine is at least an 'k6-3' CPU
      */
     public boolean IsK6_3_Compatible();
-
     /**
-     * @return true iff the CPU present in the machine is at least an 'k7' CPU (Atlhon, Duron etc. and better)
+     * @return true if the CPU present in the machine is at least an 'geode' CPU
+     */
+    boolean IsGeodeCompatible();
+    /**
+     * @return true if the CPU present in the machine is at least an 'k7' CPU (Atlhon, Duron etc. and better)
      */
     public boolean IsAthlonCompatible();
     /**
-     * @return true iff the CPU present in the machine is at least an 'k8' CPU (Atlhon 64, Opteron etc. and better)
+     * @return true if the CPU present in the machine is at least an 'k8' CPU (Atlhon 64, Opteron etc. and better)
      */
     public boolean IsAthlon64Compatible();
+    /**
+     * @return true if the CPU present in the machine is at least an 'k8' CPU (Atlhon 64, Opteron etc. and better)
+     */
+	public boolean IsBobcatCompatible();
 }
diff --git a/core/java/src/freenet/support/CPUInformation/AMDInfoImpl.java b/core/java/src/freenet/support/CPUInformation/AMDInfoImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..bfbb3e9b62806b85a2a6809d056186f56c54a147
--- /dev/null
+++ b/core/java/src/freenet/support/CPUInformation/AMDInfoImpl.java
@@ -0,0 +1,357 @@
+package freenet.support.CPUInformation;
+
+class AMDInfoImpl extends CPUIDCPUInfo implements AMDCPUInfo
+{
+    protected static boolean isK6Compatible = false;
+    protected static boolean isK6_2_Compatible = false;
+    protected static boolean isK6_3_Compatible = false;
+    protected static boolean isGeodeCompatible = false;
+    protected static boolean isAthlonCompatible = false;
+    protected static boolean isAthlon64Compatible = false;
+    protected static boolean isBobcatCompatible = false;
+
+    // If modelString != null, the cpu is considered correctly identified.
+    protected static String modelString = null;
+
+    @Override
+    public boolean IsK6Compatible(){ return isK6Compatible; }
+    @Override
+    public boolean IsK6_2_Compatible(){ return isK6_2_Compatible; }
+    @Override
+    public boolean IsK6_3_Compatible(){ return isK6_3_Compatible; }
+    @Override 
+    public boolean IsGeodeCompatible(){ return isGeodeCompatible; }
+    @Override
+    public boolean IsAthlonCompatible(){ return isAthlonCompatible; }
+    @Override
+    public boolean IsAthlon64Compatible(){ return isAthlon64Compatible; }
+    @Override
+    public boolean IsBobcatCompatible(){ return isBobcatCompatible; }
+
+	static
+	{
+		identifyCPU();
+	}	
+
+	@Override
+    public String getCPUModelString() throws UnknownCPUException
+    {
+        if (modelString != null)
+            return modelString;
+        throw new UnknownCPUException("Unknown AMD CPU; Family="+(CPUID.getCPUFamily() + CPUID.getCPUExtendedFamily())+", Model="+(CPUID.getCPUModel() + CPUID.getCPUExtendedModel()));
+    }
+    
+
+    private synchronized static void identifyCPU()
+    {
+    //AMD-family = getCPUFamily()+getCPUExtendedFamily()
+    //AMD-model = getCPUModel()+getCPUExtendedModel()
+    //i486 class (Am486, 5x86) 
+        if(CPUID.getCPUFamily() + CPUID.getCPUExtendedFamily() == 4){
+            switch(CPUID.getCPUModel() + CPUID.getCPUExtendedModel()){
+                case 3:
+                    modelString = "486 DX/2";
+                    break;
+                case 7:
+                    modelString = "486 DX/2-WB";
+                    break;
+                case 8:
+                    modelString = "486 DX/4";
+                    break;
+                case 9:
+                    modelString = "486 DX/4-WB";
+                    break;
+                case 14:
+                    modelString = "Am5x86-WT";
+                    break;
+                case 15:
+                    modelString = "Am5x86-WB";
+                    break;
+            }
+        }
+        //i586 class (K5/K6/K6-2/K6-III) 
+        if(CPUID.getCPUFamily() + CPUID.getCPUExtendedFamily() == 5){
+            isK6Compatible = true;
+            switch(CPUID.getCPUModel() + CPUID.getCPUExtendedModel()){
+                case 0:
+                    modelString = "K5/SSA5";
+                    break;
+                case 1:
+                    modelString = "K5";
+                    break;
+                case 2:
+                    modelString = "K5";
+                    break;
+                case 3:
+                    modelString = "K5";
+                    break;
+                case 4:
+                	isK6Compatible = false;
+                	isGeodeCompatible = true;
+                	modelString = "Geode GX1/GXLV/GXm";
+                	break;
+                case 5:
+                	isK6Compatible = false;
+                	isGeodeCompatible = true;
+                	modelString = "Geode GX2/LX";
+                	break;
+                case 6:
+                    modelString = "K6";
+                    break;
+                case 7:
+                    modelString = "K6";
+                    break;
+                case 8:
+                    isK6_2_Compatible = true;
+                    modelString = "K6-2";
+                    break;
+                case 9:
+                    isK6_2_Compatible = true;
+                    isK6_3_Compatible = true;
+                    modelString = "K6-3";
+                    break;
+                case 13:
+                    isK6_2_Compatible = true;
+                    modelString = "K6-2+ or K6-III+";
+                    break;
+            }
+        }
+        //i686 class (Athlon/Athlon XP/Duron/K7 Sempron) 
+        if(CPUID.getCPUFamily() + CPUID.getCPUExtendedFamily() == 6){
+            isK6Compatible = true;
+            isK6_2_Compatible = true;
+            isK6_3_Compatible = true;
+            isAthlonCompatible = true;
+            switch(CPUID.getCPUModel() + CPUID.getCPUExtendedModel()){
+                case 0:
+                    modelString = "Athlon (250 nm)";
+                    break;
+                case 1:
+                    modelString = "Athlon (250 nm)";
+                    break;
+                case 2:
+                    modelString = "Athlon (180 nm)";
+                    break;
+                case 3:
+                    modelString = "Duron";
+                    break;
+                case 4:
+                    modelString = "Athlon (Thunderbird)";
+                    break;
+                case 6:
+                    modelString = "Athlon (Palamino)";
+                    break;
+                case 7:
+                    modelString = "Duron (Morgan)";
+                    break;
+                case 8:
+                    modelString = "Athlon (Thoroughbred)";
+                    break;
+                case 10:
+                    modelString = "Athlon (Barton)";
+                    break;
+            }
+        }
+        //AMD64 class (A64/Opteron/A64 X2/K8 Sempron/Turion/Second-Generation Opteron/Athlon Neo) 
+       if(CPUID.getCPUFamily() + CPUID.getCPUExtendedFamily() == 15){
+            isK6Compatible = true;
+            isK6_2_Compatible = true;
+            isK6_3_Compatible = true;
+            isAthlonCompatible = true;
+            isAthlon64Compatible = true;
+            isX64 = true;
+            switch(CPUID.getCPUModel() + CPUID.getCPUExtendedModel()){
+                case 4:
+                    modelString = "Athlon 64/Mobile XP-M";
+                case 5:
+                    modelString = "Athlon 64 FX Opteron";
+                    break;
+                case 7:
+                    modelString = "Athlon 64 FX (Sledgehammer S939, 130 nm)";
+                    break;
+                case 8:
+                    modelString = "Mobile A64/Sempron/XP-M";
+                    break;
+                case 11:
+                    modelString = "Athlon 64 (Clawhammer S939, 130 nm)";
+                    break;
+                case 12:
+                    modelString = "Athlon 64/Sempron (Newcastle S754, 130 nm)";
+                    break;
+                case 14:
+                    modelString = "Athlon 64/Sempron (Newcastle S754, 130 nm)";
+                    break;
+                case 15:
+                    modelString = "Athlon 64/Sempron (Clawhammer S939, 130 nm)";
+                    break;                    
+                case 18:
+                    modelString = "Sempron (Palermo, 90 nm)";
+                    break;
+                case 20:
+                    modelString = "Athlon 64 (Winchester S754, 90 nm)";
+                    break;
+                case 23:
+                    modelString = "Athlon 64 (Winchester S939, 90 nm)";
+                    break;
+                case 24:
+                    modelString = "Mobile A64/Sempron/XP-M (Winchester S754, 90 nm)";
+                    break;
+                case 26:
+                    modelString = "Athlon 64 (Winchester S939, 90 nm)";
+                    break;
+                case 27:
+                    modelString = "Athlon 64/Sempron (Winchester/Palermo 90 nm)";
+                    break;
+                case 28:
+                    modelString = "Sempron (Palermo, 90 nm)";
+                    break;
+                case 31:
+                    modelString = "Athlon 64/Sempron (Winchester/Palermo, 90 nm)";
+                    break;
+                case 33:
+                    modelString = "Dual-Core Opteron (Italy-Egypt S940, 90 nm)";
+                    break;
+                case 35:
+                    modelString = "Athlon 64 X2/A64 FX/Opteron (Toledo/Denmark S939, 90 nm)";
+                    break;
+                case 36:
+                    modelString = "Mobile A64/Turion (Lancaster/Richmond/Newark, 90 nm)";
+                    break;
+                case 37:
+                    modelString = "Opteron (Troy/Athens S940, 90 nm)";
+                    break;
+                case 39:
+                    modelString = "Athlon 64 (San Diego, 90 nm)";
+                    break;
+                case 43:
+                    modelString = "Athlon 64 X2 (Manchester, 90 nm)";
+                    break;
+                case 44:
+                    modelString = "Sempron/mobile Sempron (Palermo/Albany/Roma S754, 90 nm)";
+                    break;
+                case 47:
+                    modelString = "Athlon 64/Sempron (Venice/Palermo S939, 90 nm)";
+                    break;
+                case 65:
+                    modelString = "Second-Generaton Opteron (Santa Rosa S1207, 90 nm)";
+                    break;
+                case 67:
+                    modelString = "Athlon 64 X2/2nd-gen Opteron (Windsor/Santa Rosa, 90 nm)";
+                    break;
+                case 72:
+                    modelString = "Athlon 64 X2/Turion 64 X2 (Windsor/Taylor/Trinidad, 90 nm)";
+                    break;
+                case 75:
+                    modelString = "Athlon 64 X2 (Windsor, 90 nm)";
+                    break;
+                case 76:
+                    modelString = "Mobile A64/mobile Sempron/Turion (Keene/Trinidad/Taylor, 90 nm)";
+                    break;
+                case 79:
+                    modelString = "Athlon 64/Sempron (Orleans/Manila AM2, 90 nm)";
+                    break;
+                case 93:
+                    modelString = "Opteron Gen 2 (Santa Rosa, 90 nm)";
+                    break;
+                case 95:
+                    modelString = "A64/Sempron/mobile Sempron (Orleans/Manila/Keene, 90 nm)";
+                    break;
+                case 104:
+                    modelString = "Turion 64 X2 (Tyler S1, 65 nm)";
+                    break;
+                case 107:
+                    modelString = "Athlon 64 X2/Sempron X2/Athlon Neo X2 (Brisbane/Huron, 65 nm)";
+                    break;
+                case 108:
+                    modelString = "A64/Athlon Neo/Sempron/Mobile Sempron (Lima/Huron/Sparta/Sherman, 65 nm)";
+                    break;
+                case 111:
+                    modelString = "Neo/Sempron/mobile Sempron (Huron/Sparta/Sherman, 65 nm)";
+                    break;
+                case 124:
+                    modelString = "Athlon/Sempron/mobile Sempron (Lima/Sparta/Sherman, 65 nm)";
+                    break;
+                case 127:
+                    modelString = "A64/Athlon Neo/Sempron/mobile Sempron (Lima/Huron/Sparta/Sherman, 65 nm)";
+                    break;
+                case 193:
+                    modelString = "Athlon 64 FX (Windsor S1207 90 nm)";
+                    break;
+                default: // is this safe?
+                    modelString = "Athlon 64 (unknown)";
+                    break;
+            }
+        }
+        //Stars (Phenom II/Athlon II/Third-Generation Opteron/Opteron 4100 & 6100/Sempron 1xx) 
+        if(CPUID.getCPUFamily() + CPUID.getCPUExtendedFamily() == 16){
+            isK6Compatible = true;
+            isK6_2_Compatible = true;
+            isK6_3_Compatible = true;
+            isAthlonCompatible = true;
+            isAthlon64Compatible = true;
+            isX64 = true;
+            switch(CPUID.getCPUModel() + CPUID.getCPUExtendedModel()){
+                case 2:
+                    modelString = "Phenom / Athlon / Opteron Gen 3 (Barcelona/Agena/Toliman/Kuma, 65 nm)";
+                    break;
+                case 4:
+                    modelString = "Phenom II / Opteron Gen 3 (Shanghai/Deneb/Heka/Callisto, 45 nm)";
+                    break;
+                case 5:
+                    modelString = "Athlon II X2/X3/X4 (Regor/Rana/Propus AM3, 45 nm)";
+                    break;
+                case 6:
+                    modelString = "Mobile Athlon II/Turion II/Phenom II/Sempron/V-series (Regor/Caspian/Champlain, 45 nm)";
+                    break;
+                case 8:
+                    modelString = "Six-Core Opteron/Opteron 4100 series (Istanbul/Lisbon, 45 nm)";
+                    break;
+                case 9:
+                    modelString = "Opteron 6100 series (Magny-Cours G34, 45 nm)";
+                    break;
+                case 10:
+                    modelString = "Phenom II X4/X6 (Zosma/Thuban AM3, 45 nm)";
+                    break;
+            }
+        }
+        //K8 mobile+HT3 (Turion X2/Athlon X2/Sempron) 
+        if(CPUID.getCPUFamily() + CPUID.getCPUExtendedFamily() == 17){
+            isK6Compatible = true;
+            isK6_2_Compatible = true;
+            isK6_3_Compatible = true;
+            isAthlonCompatible = true;
+            isAthlon64Compatible = true;
+            isX64 = true;
+            switch(CPUID.getCPUModel() + CPUID.getCPUExtendedModel()){
+                case 3:
+                    modelString = "AMD Turion X2/Athlon X2/Sempron (Lion/Sable, 65 nm)";
+                    break;
+            }
+        }
+        //Bobcat
+        if(CPUID.getCPUFamily() + CPUID.getCPUExtendedFamily() == 20){
+            isK6Compatible = true;
+            isK6_2_Compatible = true;
+            isK6_3_Compatible = true;
+            isAthlonCompatible = true;
+            isAthlon64Compatible = true;
+            isBobcatCompatible = true;
+            isX64 = true;
+            switch(CPUID.getCPUModel() + CPUID.getCPUExtendedModel()){
+                case 1:                    
+                    modelString = "Bobcat APU";
+                    break;
+                // Case 3 is uncertain but most likely a Bobcat APU
+                case 3:
+                    modelString = "Bobcat APU";
+                    break;
+            }
+        }
+    }
+	@Override
+	public boolean hasX64()
+	{
+		return isX64;
+	}
+
+}
diff --git a/core/java/src/freenet/support/CPUInformation/CPUID.java b/core/java/src/freenet/support/CPUInformation/CPUID.java
index ae4a8846756b9468470a601c383b030ecb60cbf6..c747abd7706decf93eb9d78d23da932f9989939c 100644
--- a/core/java/src/freenet/support/CPUInformation/CPUID.java
+++ b/core/java/src/freenet/support/CPUInformation/CPUID.java
@@ -9,10 +9,12 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.HashMap;
 
 import net.i2p.I2PAppContext;
 import net.i2p.util.FileUtil;
 
+
 /**
  * @author Iakin
  * A class for retrieveing details about the CPU using the CPUID assembly instruction.
@@ -53,7 +55,8 @@ public class CPUID {
     private static final boolean isLinux = System.getProperty("os.name").toLowerCase().contains("linux");
     private static final boolean isFreebsd = System.getProperty("os.name").toLowerCase().contains("freebsd");
     private static final boolean isSunos = System.getProperty("os.name").toLowerCase().contains("sunos");
-    
+
+
     /**
      * This isn't always correct.
      * http://stackoverflow.com/questions/807263/how-do-i-detect-which-kind-of-jre-is-installed-32bit-vs-64bit
@@ -70,12 +73,9 @@ public class CPUID {
     static
     {
         loadNative();
-    }
-    
-    /**
-     * A class that can (amongst other things I assume) represent the state of the
-     * different CPU registers after a call to the CPUID assembly method
-     */
+    }    
+    //A class that can (amongst other things I assume) represent the state of the
+    //different CPU registers after a call to the CPUID assembly method
     protected static class CPUIDResult {
         final int EAX;
         final int EBX;
@@ -97,7 +97,8 @@ public class CPUID {
      */
     private static native CPUIDResult doCPUID(int iFunction);
 
-    private static String getCPUVendorID()
+
+    public static String getCPUVendorID()
     {
         CPUIDResult c = doCPUID(0);
         StringBuilder sb= new StringBuilder(13);
@@ -118,71 +119,74 @@ public class CPUID {
     
         return sb.toString();
     }
-    private static int getCPUFamily()
+    public static int getCPUFamily()
     {
         CPUIDResult c = doCPUID(1);
         return (c.EAX >> 8) & 0xf;
     }
-    private static int getCPUModel()
+    public static int getCPUModel()
     {
         CPUIDResult c = doCPUID(1);
         return (c.EAX >> 4) & 0xf;
     }
-    private static int getCPUExtendedModel()
+    public static int getCPUExtendedModel()
     {
         CPUIDResult c = doCPUID(1);
         return (c.EAX >> 16) & 0xf;
     }
-    private static int getCPUType()
+    public static int getCPUType()
     {
         CPUIDResult c = doCPUID(1);
         return (c.EAX >> 12) & 0xf;
     }
-    private static int getCPUExtendedFamily()
+    public static int getCPUExtendedFamily()
     {
         CPUIDResult c = doCPUID(1);
         return (c.EAX >> 20) & 0xff;
     }
-    private static int getCPUStepping()
+    public static int getCPUStepping()
     {
         CPUIDResult c = doCPUID(1);
         return c.EAX & 0xf;
     }
-    private static int getEDXCPUFlags()
+    public static int getEDXCPUFlags()
     {
         CPUIDResult c = doCPUID(1);
         return c.EDX;
     }
-    private static int getECXCPUFlags()
+    public static int getECXCPUFlags()
     {
         CPUIDResult c = doCPUID(1);
         return c.ECX;
     }
-    private static int getExtendedEDXCPUFlags()
+    public static int getExtendedEBXCPUFlags()
     {
         CPUIDResult c = doCPUID(0x80000001);
-        return c.EDX;
+        return c.EBX;    
     }
-    private static int getExtendedECXCPUFlags()
+    public static int getExtendedECXCPUFlags()
     {
         CPUIDResult c = doCPUID(0x80000001);
         return c.ECX;
     }
+    public static int getExtendedEDXCPUFlags()
+    {
+        CPUIDResult c = doCPUID(0x80000001);
+        return c.EDX;
+    }
     
-    /**
-     * Returns a CPUInfo item for the current type of CPU
-     * If I could I would declare this method in a interface named
-     * CPUInfoProvider and implement that interface in this class.
-     * This would make it easier for other people to understand that there
-     * is nothing preventing them from coding up new providers, probably using
-     * other detection methods than the x86-only CPUID instruction
-     */
+    //Returns a CPUInfo item for the current type of CPU
+    //If I could I would declare this method in a interface named
+    //CPUInfoProvider and implement that interface in this class.
+    //This would make it easier for other people to understand that there
+    //is nothing preventing them from coding up new providers, probably using
+    //other detection methods than the x86-only CPUID instruction
     public static CPUInfo getInfo() throws UnknownCPUException
     {
         if(!_nativeOk)
             throw new UnknownCPUException("Failed to read CPU information from the system. Please verify the existence of the jcpuid dll/so.");
         if(getCPUVendorID().equals("CentaurHauls"))
-            return new VIAC3Impl();
+            return new VIAInfoImpl();
         if(!isX86)
             throw new UnknownCPUException("Failed to read CPU information from the system. The CPUID instruction exists on x86 CPU's only");
         if(getCPUVendorID().equals("AuthenticAMD"))
@@ -192,303 +196,6 @@ public class CPUID {
         throw new UnknownCPUException("Unknown CPU type: '"+getCPUVendorID()+"'");
     }
     
-    protected abstract static class CPUIDCPUInfo
-    {
-        public String getVendor()
-        {
-            return getCPUVendorID();
-        }
-        public boolean hasMMX(){
-            return (getEDXCPUFlags() & 0x800000) >0; //EDX Bit 23
-        }
-        public boolean hasSSE(){
-            return (getEDXCPUFlags() & 0x2000000) >0; //EDX Bit 25
-        }
-        public boolean hasSSE2(){
-            return (getEDXCPUFlags() & 0x4000000) >0; //EDX Bit 26
-        }
-        public boolean hasSSE3(){
-            return (getEDXCPUFlags() & 0x1) >0; //ECX Bit 0
-        }
-        public boolean hasSSE41(){
-            return (getEDXCPUFlags() & 0x80000) >0; //ECX Bit 19
-        }
-        public boolean hasSSE42(){
-            return (getEDXCPUFlags() & 0x100000) >0; //ECX Bit 20
-        }
-        public boolean hasSSE4A(){
-            return (getExtendedECXCPUFlags() & 0x40) >0; //Extended ECX Bit 6
-        }
-        public boolean IsC3Compatible() { return false; }
-    }
-    protected static class VIAC3Impl extends CPUIDCPUInfo implements CPUInfo {
-        @Override
-        public boolean IsC3Compatible() { return true; }
-        public String getCPUModelString() { return "VIA C3"; }
-    }
-    protected static class AMDInfoImpl extends CPUIDCPUInfo implements AMDCPUInfo
-    {
-        public boolean IsK6Compatible()
-        {
-            return getCPUFamily() >= 5 && getCPUModel() >= 6;
-        }
-        public boolean IsK6_2_Compatible()
-        {
-            return getCPUFamily() >= 5 && getCPUModel() >= 8;
-        }
-        public boolean IsK6_3_Compatible()
-        {
-            return getCPUFamily() >= 5 && getCPUModel() >= 9;
-        }
-        public boolean IsAthlonCompatible()
-        {
-            return getCPUFamily() >= 6;
-        }
-        public boolean IsAthlon64Compatible()
-        {
-            return getCPUFamily() == 15 && getCPUExtendedFamily() == 0;
-        }
-
-        public String getCPUModelString() throws UnknownCPUException
-        {
-            if(getCPUFamily() == 4){
-                switch(getCPUModel()){
-                    case 3:
-                        return "486 DX/2";
-                    case 7:
-                        return "486 DX/2-WB";
-                    case 8:
-                        return "486 DX/4";
-                    case 9:
-                        return "486 DX/4-WB";
-                    case 14:
-                        return "Am5x86-WT";
-                    case 15:
-                        return "Am5x86-WB";
-                }
-            }
-            if(getCPUFamily() == 5){
-                switch(getCPUModel()){
-                    case 0:
-                        return "K5/SSA5";
-                    case 1:
-                        return "K5";
-                    case 2:
-                        return "K5";
-                    case 3:
-                        return "K5";
-                    case 6:
-                        return "K6";
-                    case 7:
-                        return "K6";
-                    case 8:
-                        return "K6-2";
-                    case 9:
-                        return "K6-3";
-                    case 13:
-                        return "K6-2+ or K6-III+";
-                }
-            }
-            if(getCPUFamily() == 6){
-                switch(getCPUModel()){
-                    case 0:
-                        return "Athlon (250 nm)";
-                    case 1:
-                        return "Athlon (250 nm)";
-                    case 2:
-                        return "Athlon (180 nm)";
-                    case 3:
-                        return "Duron";
-                    case 4:
-                        return "Athlon (Thunderbird)";
-                    case 6:
-                        return "Athlon (Palamino)";
-                    case 7:
-                        return "Duron (Morgan)";
-                    case 8:
-                        return "Athlon (Thoroughbred)";
-                    case 10:
-                        return "Athlon (Barton)";
-                }
-            }
-            if(getCPUFamily() == 15){
-                if(getCPUExtendedFamily() == 0){
-                    switch(getCPUModel()){
-                        case 4:
-                            return "Athlon 64";
-                        case 5:
-                            return "Athlon 64 FX Opteron";
-                        case 12:
-                            return "Athlon 64";
-                        default: // is this safe?
-                            return "Athlon 64 (unknown)";
-                    }
-                }
-            }
-            throw new UnknownCPUException("Unknown AMD CPU; Family="+getCPUFamily()+", Model="+getCPUModel());
-        }
-    }
-
-    protected static class IntelInfoImpl extends CPUIDCPUInfo implements IntelCPUInfo
-    {
-        public boolean IsPentiumCompatible()
-        {
-            return getCPUFamily() >= 5;
-        }
-        public boolean IsPentiumMMXCompatible()
-        {
-            return IsPentium2Compatible() || (getCPUFamily() == 5 && (getCPUModel() ==4 || getCPUModel() == 8));
-        }
-        public boolean IsPentium2Compatible()
-        {
-            return getCPUFamily() > 6 || (getCPUFamily() == 6 && getCPUModel() >=3);
-        }
-        public boolean IsPentium3Compatible()
-        {	
-		// Atom
-		if (getCPUExtendedModel() == 1 && (getCPUFamily() == 6 && (getCPUModel() == 12))){
-			return true;
-		// ??
-		} else if (getCPUExtendedModel() == 0 && (getCPUFamily() > 6 || (getCPUFamily() == 6 && getCPUModel() >=7))){
-			return true;
-		} else {
-			return false;
-		}
-        }
-        public boolean IsPentium4Compatible()
-        {	
-		// P4
-        	if (getCPUFamily() >= 15){
-        		return true;
-		// Xeon MP (45nm) or Core i7
-        	} else if (getCPUExtendedModel() == 1 && (getCPUFamily() == 6 && (getCPUModel() == 10 || getCPUModel() == 13))){
-        		return true;
-		// Core 2 Duo
-        	} else if (getCPUExtendedModel() == 0 && getCPUFamily() == 6 && getCPUModel() == 15){
-        		return true;
-        	} else {
-        		return false;
-        	}
-        }
-        public String getCPUModelString() throws UnknownCPUException {
-        	if (getCPUExtendedModel() == 0){
-	            if(getCPUFamily() == 4){
-	                switch(getCPUModel()){
-	                    case 0:
-	                        return "486 DX-25/33";
-	                    case 1:
-	                        return "486 DX-50";
-	                    case 2:
-	                        return "486 SX";
-	                    case 3:
-	                        return "486 DX/2";
-	                    case 4:
-	                        return "486 SL";
-	                    case 5:
-	                        return "486 SX/2";
-	                    case 7:
-	                        return "486 DX/2-WB";
-	                    case 8:
-	                        return "486 DX/4";
-	                    case 9:
-	                        return "486 DX/4-WB";
-	                }
-	            }
-        	}
-            if (getCPUExtendedModel() == 0){
-	            if(getCPUFamily() == 5){
-	                switch(getCPUModel()){
-	                    case 0:
-	                        return "Pentium 60/66 A-step";
-	                    case 1:
-	                        return "Pentium 60/66";
-	                    case 2:
-	                        return "Pentium 75 - 200";
-	                    case 3:
-	                        return "OverDrive PODP5V83";
-	                    case 4:
-	                        return "Pentium MMX";
-	                    case 7:
-	                        return "Mobile Pentium 75 - 200";
-	                    case 8:
-	                        return "Mobile Pentium MMX";
-	                }
-	            }
-            }
-            if(getCPUFamily() == 6){
-            	if (getCPUExtendedModel() == 0){
-	                switch(getCPUModel()){
-	                    case 0:
-	                        return "Pentium Pro A-step";
-	                    case 1:
-	                        return "Pentium Pro";
-	                    case 3:
-	                        return "Pentium II (Klamath)";
-	                    case 5:
-	                        return "Pentium II (Deschutes), Celeron (Covington), Mobile Pentium II (Dixon)";
-	                    case 6:
-	                        return "Mobile Pentium II, Celeron (Mendocino)";
-	                    case 7:
-	                        return "Pentium III (Katmai)";
-	                    case 8:
-	                        return "Pentium III (Coppermine), Celeron w/SSE";
-	                    case 9:
-	                        return "Mobile Pentium III (Banias)";
-	                    case 10:
-	                        return "Pentium III Xeon (Cascades)";
-	                    case 11:
-	                        return "Pentium III (130 nm)";
-	                    case 13:
-	                        return "Mobile Pentium III (Dothan)";
-	                    case 14:
-	                        return "Mobile Core (Yonah)";
-	                    case 15:
-	                        return "Core 2 (Conroe)";
-	                }
-            	} else {
-		    	if (getCPUExtendedModel() == 1){
-		    		 switch(getCPUModel()){
-		    		 	case 10:
-		    		 		return "Core i7";
-		    		 	case 12:
-		    		 		return "Atom";
-		    		 	case 13:
-		    		 		return "Xeon MP";
-		    		 }
-		    	}
-		}
-            }
-            if(getCPUFamily() == 7){
-                switch(getCPUModel()){
-                    //Itanium.. TODO
-                }
-            }
-            if(getCPUFamily() == 15){
-                if(getCPUExtendedFamily() == 0){
-                    switch(getCPUModel()){
-                        case 0:
-                            return "Pentium IV (180 nm)";
-                        case 1:
-                            return "Pentium IV (180 nm)";
-                        case 2:
-                            return "Pentium IV (130 nm)";
-                        case 3:
-                            return "Pentium IV (90 nm)";
-                        case 4:
-                            return "Pentium IV (90 nm)";
-                        case 6:
-                            return "Pentium IV (65 nm)";
-                    }
-                }
-                if(getCPUExtendedFamily() == 1){
-                    switch(getCPUModel()){
-                        //    Itanium 2.. TODO
-                    }    
-                }
-            }
-            throw new UnknownCPUException("Unknown Intel CPU; Family="+getCPUFamily()+", Model="+getCPUModel());
-        }
-    }
 
     public static void main(String args[])
     {
@@ -518,6 +225,9 @@ public class CPUID {
             System.out.println("  Is pII-compatible: "+((IntelCPUInfo)c).IsPentium2Compatible());
             System.out.println("  Is pIII-compatible: "+((IntelCPUInfo)c).IsPentium3Compatible());
             System.out.println("  Is pIV-compatible: "+((IntelCPUInfo)c).IsPentium4Compatible());
+            System.out.println("  Is atom-compatible: "+((IntelCPUInfo)c).IsAtomCompatible());
+            System.out.println("  Is core2-compatible: "+((IntelCPUInfo)c).IsCore2Compatible());
+            System.out.println("  Is corei-compatible: "+((IntelCPUInfo)c).IsCoreiCompatible());
         }
         if(c instanceof AMDCPUInfo){
             System.out.println("  **AMD-info**");
@@ -720,8 +430,8 @@ public class CPUID {
              return "jcpuid-x86-windows"; // The convention on Windows
         if(isFreebsd)
             return "jcpuid-x86-freebsd"; // The convention on freebsd...
-	if(isSunos)
-	    return "jcpuid-x86-solaris"; // The convention on SunOS
+        if(isSunos)
+            return "jcpuid-x86-solaris"; // The convention on SunOS
         //throw new RuntimeException("Dont know jcpuid library name for os type '"+System.getProperty("os.name")+"'");
         // use linux as the default, don't throw exception
         return "jcpuid-x86-linux";
@@ -733,8 +443,8 @@ public class CPUID {
              return "jcpuid-x86_64-windows";
         if(isFreebsd)
             return "jcpuid-x86_64-freebsd";
-	if(isSunos)
-	    return "jcpuid-x86_64-solaris";
+        if(isSunos)
+            return "jcpuid-x86_64-solaris";
         // use linux as the default, don't throw exception
         return "jcpuid-x86_64-linux";
     }
diff --git a/core/java/src/freenet/support/CPUInformation/CPUIDCPUInfo.java b/core/java/src/freenet/support/CPUInformation/CPUIDCPUInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..90ce047e0787f82ba458c878773ccbd6bf3e9346
--- /dev/null
+++ b/core/java/src/freenet/support/CPUInformation/CPUIDCPUInfo.java
@@ -0,0 +1,40 @@
+package freenet.support.CPUInformation;
+
+abstract class CPUIDCPUInfo
+{
+    protected static boolean isX64 = false;        
+            
+    public String getVendor()
+    {
+        return CPUID.getCPUVendorID();
+    }
+    public boolean hasMMX()
+    {
+        return (CPUID.getEDXCPUFlags() & 0x800000) >0; //EDX Bit 23
+    }
+    public boolean hasSSE(){
+        return (CPUID.getEDXCPUFlags() & 0x2000000) >0; //EDX Bit 25
+    }
+    public boolean hasSSE2()
+    {
+        return (CPUID.getEDXCPUFlags() & 0x4000000) >0; //EDX Bit 26
+    }
+    public boolean hasSSE3()
+    {
+        return (CPUID.getEDXCPUFlags() & 0x1) >0; //ECX Bit 0
+    }
+    public boolean hasSSE41()
+    {
+        return (CPUID.getEDXCPUFlags() & 0x80000) >0; //ECX Bit 19
+    }
+    public boolean hasSSE42()
+    {
+        return (CPUID.getEDXCPUFlags() & 0x100000) >0; //ECX Bit 20
+    }
+    public boolean hasSSE4A()
+    {
+        return (CPUID.getExtendedECXCPUFlags() & 0x40) >0; //Extended ECX Bit 6
+    }
+    
+    public abstract boolean hasX64();
+}
diff --git a/core/java/src/freenet/support/CPUInformation/CPUInfo.java b/core/java/src/freenet/support/CPUInformation/CPUInfo.java
index 43dfcd8d0faea14c78f57c2583c246af10f2046b..3dbd2a69a2613eb6bf0f89032ce189c4a26d62ff 100644
--- a/core/java/src/freenet/support/CPUInformation/CPUInfo.java
+++ b/core/java/src/freenet/support/CPUInformation/CPUInfo.java
@@ -61,6 +61,4 @@ public interface CPUInfo
      * @return true iff the CPU support the SSE4A instruction set.
      */
     public boolean hasSSE4A();
-
-    public boolean IsC3Compatible();
 }
diff --git a/core/java/src/freenet/support/CPUInformation/IntelCPUInfo.java b/core/java/src/freenet/support/CPUInformation/IntelCPUInfo.java
index 20f8aaf77e689e9c267218c30f4a17bccbcb2a4d..06f57d0407195c61abb15efb14563257e980477a 100644
--- a/core/java/src/freenet/support/CPUInformation/IntelCPUInfo.java
+++ b/core/java/src/freenet/support/CPUInformation/IntelCPUInfo.java
@@ -16,25 +16,41 @@ package freenet.support.CPUInformation;
  */
 public interface IntelCPUInfo extends CPUInfo {
     /**
-     * @return true iff the CPU is at least a Pentium CPU.
+     * @return true if the CPU is at least a Pentium CPU.
      */
     public boolean IsPentiumCompatible();
     /**
-     * @return true iff the CPU is at least a Pentium which implements the MMX instruction/feature set.
+     * @return true if the CPU is at least a Pentium which implements the MMX instruction/feature set.
      */
     public boolean IsPentiumMMXCompatible();
     /**
-     * @return true iff the CPU implements at least the p6 instruction set (Pentium II or better).
+     * @return true if the CPU implements at least the p6 instruction set (Pentium II or better).
      * Please note that an PentimPro CPU causes/should cause this method to return false (due to that CPU using a
      * very early implementation of the p6 instruction set. No MMX etc.)
      */
     public boolean IsPentium2Compatible();
     /**
-     * @return true iff the CPU implements at least a Pentium III level of the p6 instruction/feature set.
+     * @return true if the CPU implements at least a Pentium III level of the p6 instruction/feature set.
      */
     public boolean IsPentium3Compatible();
     /**
-     * @return true iff the CPU implements at least a Pentium IV level instruction/feature set.
+     * @return true if the CPU implements at least a Pentium IV level instruction/feature set.
      */
     public boolean IsPentium4Compatible();
+    /**
+     * @return true if the CPU implements at least a Pentium M level instruction/feature set.
+     */
+    public boolean IsPentiumMCompatible();	
+    /**
+     * @return true if the CPU implements at least a Atom level instruction/feature set.
+     */
+    public boolean IsAtomCompatible();
+    /**
+     * @return true if the CPU implements at least a Core2 level instruction/feature set.
+     */
+    public boolean IsCore2Compatible();
+    /**
+     * @return true if the CPU implements at least a Corei level instruction/feature set.
+     */
+    public boolean IsCoreiCompatible();
 }
diff --git a/core/java/src/freenet/support/CPUInformation/IntelInfoImpl.java b/core/java/src/freenet/support/CPUInformation/IntelInfoImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b6e6df321a4e729930f3691120b9ec0295ab76b
--- /dev/null
+++ b/core/java/src/freenet/support/CPUInformation/IntelInfoImpl.java
@@ -0,0 +1,297 @@
+package freenet.support.CPUInformation;
+
+class IntelInfoImpl extends CPUIDCPUInfo implements IntelCPUInfo
+{
+    protected static boolean isPentiumCompatible = false;
+    protected static boolean isPentiumMMXCompatible = false;
+    protected static boolean isPentium2Compatible = false;
+    protected static boolean isPentium3Compatible = false;
+    protected static boolean isPentium4Compatible = false;
+    protected static boolean isPentiumMCompatible = false;
+    protected static boolean isAtomCompatible = false;
+    protected static boolean isCore2Compatible = false;
+    protected static boolean isCoreiCompatible = false;
+    
+    // If modelString != null, the cpu is considered correctly identified.
+    protected static String modelString = null;
+    
+    @Override
+    public boolean IsPentiumCompatible(){ return isPentiumCompatible; }
+    @Override
+    public boolean IsPentiumMMXCompatible(){ return isPentiumMMXCompatible; }
+    @Override
+    public boolean IsPentium2Compatible(){ return isPentium2Compatible; }
+    @Override
+    public boolean IsPentium3Compatible(){ return isPentium3Compatible; }
+    @Override
+    public boolean IsPentium4Compatible(){ return isPentium4Compatible; }
+    @Override
+    public boolean IsPentiumMCompatible(){ return isPentiumMCompatible; }
+    @Override
+    public boolean IsAtomCompatible(){ return isAtomCompatible; }
+    @Override
+    public boolean IsCore2Compatible(){ return isCore2Compatible; }
+    @Override
+    public boolean IsCoreiCompatible(){ return isCoreiCompatible; }    
+	
+	static
+	{
+		identifyCPU();
+	}
+
+    public String getCPUModelString() throws UnknownCPUException
+    {
+        if (modelString != null)
+            return modelString;
+        throw new UnknownCPUException("Unknown Intel CPU; Family="+CPUID.getCPUFamily()+", Model="+CPUID.getCPUModel());
+    }
+    
+    private synchronized static void identifyCPU()
+    {
+        if (CPUID.getCPUExtendedModel() == 0){
+            if(CPUID.getCPUFamily() == 4){
+                switch(CPUID.getCPUModel()){
+                    case 0:
+                        modelString = "486 DX-25/33";
+                        break;
+                    case 1:
+                        modelString = "486 DX-50";
+                        break;
+                    case 2:
+                        modelString = "486 SX";
+                        break;
+                    case 3:
+                        modelString = "486 DX/2";
+                        break;
+                    case 4:
+                        modelString = "486 SL";
+                        break;
+                    case 5:
+                        modelString = "486 SX/2";
+                        break;
+                    case 7:
+                        modelString = "486 DX/2-WB";
+                        break;
+                    case 8:
+                        modelString = "486 DX/4";
+                        break;
+                    case 9:
+                        modelString = "486 DX/4-WB";
+                        break;
+                }
+            }
+        }
+        if (CPUID.getCPUExtendedModel() == 0){
+            if(CPUID.getCPUFamily() == 5){
+                isPentiumCompatible = true;
+                switch(CPUID.getCPUModel()){
+                    case 0:
+                        modelString = "Pentium 60/66 A-step";
+                        break;
+                    case 1:
+                        modelString = "Pentium 60/66";
+                        break;
+                    case 2:
+                        modelString = "Pentium 75 - 200";
+                        break;
+                    case 3:
+                        modelString = "OverDrive PODP5V83";
+                        break;
+                    case 4:
+                        isPentiumMMXCompatible = true;
+                        modelString = "Pentium MMX";
+                        break;
+                    case 7:
+                        modelString = "Mobile Pentium 75 - 200";
+                        break;
+                    case 8:
+                        isPentiumMMXCompatible = true;
+                        modelString = "Mobile Pentium MMX";
+                        break;
+                }
+            }
+        }
+        if(CPUID.getCPUFamily() == 6){
+            if (CPUID.getCPUExtendedModel() == 0){
+                isPentiumCompatible = true;
+                isPentiumMMXCompatible = true;
+                switch(CPUID.getCPUModel()){
+                    case 0:
+                        modelString = "Pentium Pro A-step";
+                        break;
+                    case 1:
+                        modelString = "Pentium Pro";
+                        break;
+                    case 3:
+                        isPentium2Compatible = true;
+                        modelString = "Pentium II (Klamath)";
+                        break;
+                    case 5:
+                        isPentium2Compatible = true;
+                        modelString = "Pentium II (Deschutes), Celeron (Covington), Mobile Pentium II (Dixon)";
+                        break;
+                    case 6:
+                        isPentium2Compatible = true;
+                        modelString = "Mobile Pentium II, Celeron (Mendocino)";
+                        break;
+                    case 7:
+                        isPentium2Compatible = true;
+                        isPentium3Compatible = true;
+                        modelString = "Pentium III (Katmai)";
+                        break;
+                    case 8:
+                        isPentium2Compatible = true;
+                        isPentium3Compatible = true;
+                        modelString = "Pentium III (Coppermine), Celeron w/SSE";
+                        break;
+                    case 9:
+                        isPentium2Compatible = true;
+                        isPentium3Compatible = true;
+						isPentiumMCompatible = true;
+                        isX64 = true;
+                        modelString = "Pentium M (Banias)";
+                        break;
+                    case 10:
+                        isPentium2Compatible = true;
+                        isPentium3Compatible = true;
+                        modelString = "Pentium III Xeon (Cascades)";
+                        break;
+                    case 11:
+                        isPentium2Compatible = true;
+                        isPentium3Compatible = true;
+						isPentiumMCompatible = true;
+                        modelString = "Pentium III (130 nm)";
+                        break;
+                    case 13:
+                        isPentium2Compatible = true;
+                        isPentium3Compatible = true;
+						isPentiumMCompatible = true;
+                        isX64 = true;
+                        modelString = "Core (Yonah)";
+                        break;
+                    case 14:
+                        isPentium2Compatible = true;
+                        isPentium3Compatible = true;
+						isPentiumMCompatible = true;
+                        isCore2Compatible = true;
+                        isX64 = true;
+                        modelString = "Core 2 (Conroe)";
+                        break;
+                    case 15:
+                        isPentium2Compatible = true;
+                        isPentium3Compatible = true;
+						isPentiumMCompatible = true;
+                        isCore2Compatible = true;
+                        isX64 = true;
+                        modelString = "Core 2 (Conroe)";
+                        break;
+                }
+            } else if (CPUID.getCPUExtendedModel() == 1){
+                isPentiumCompatible = true;
+                isPentiumMMXCompatible = true;
+                isPentium2Compatible = true;
+                isPentium3Compatible = true;
+                isPentium4Compatible = true;
+				isPentiumMCompatible = true;
+                isCore2Compatible = true;
+                isX64 = true;
+                switch(CPUID.getCPUModel()){
+                    case 6:
+                        modelString = "Celeron";
+                        break;
+                     case 10:
+                        isCoreiCompatible = true;
+                         modelString = "Core i7 (45nm)";
+                        break;
+                     case 12:
+                        isAtomCompatible = true;
+                        isCore2Compatible = false;
+                        isPentium4Compatible = false;
+                        isX64 = true;
+                        modelString = "Atom";
+                        break;
+                     case 13:
+                        isCoreiCompatible = true;
+                        modelString = "Xeon MP (45nm)";
+                        break;
+                    case 14:
+                        isCoreiCompatible = true;
+                        modelString = "Core i5/i7 (45nm)";
+                        break;
+                }
+            } else if (CPUID.getCPUExtendedModel() == 2){
+                isPentiumCompatible = true;
+                isPentiumMMXCompatible = true;
+                isPentium2Compatible = true;
+                isPentium3Compatible = true;
+                isPentium4Compatible = true;
+				isPentiumMCompatible = true;
+                isCore2Compatible = true;
+                isCoreiCompatible = true;
+                isX64 = true;
+                switch(CPUID.getCPUModel()){
+                    case 5:
+                        modelString = "Core i3 or i5/i7 mobile (32nm)";
+                        break;
+                    case 10:
+                        modelString = "Core i7/i5 (32nm)";
+                        break;
+                    case 12:
+                        modelString = "Core i7 (32nm)";
+                        break;
+                    case 14:
+                        modelString = "Xeon MP (45nm)";
+                        break;
+                    case 15:
+                        modelString = "Xeon MP (32nm)";
+                        break;
+                }                
+            }
+        }
+        if(CPUID.getCPUFamily() == 7){
+            switch(CPUID.getCPUModel()){
+                //Itanium..  TODO
+            }
+        }
+        if(CPUID.getCPUFamily() == 15){
+            if(CPUID.getCPUExtendedFamily() == 0){
+                isPentiumCompatible = true;
+                isPentiumMMXCompatible = true;
+                isPentium2Compatible = true;
+                isPentium3Compatible = true;
+                isPentium4Compatible = true;
+                switch(CPUID.getCPUModel()){
+                    case 0:
+                        modelString = "Pentium IV (180 nm)";
+                        break;
+                    case 1:
+                        modelString = "Pentium IV (180 nm)";
+                        break;
+                    case 2:
+                        modelString = "Pentium IV (130 nm)";
+                        break;
+                    case 3:
+                        modelString = "Pentium IV (90 nm)";
+                        break;
+                    case 4:
+                        isX64 = true;
+                        modelString = "Pentium IV (90 nm)";
+                        break;
+                    case 6:
+                        isX64 = true;
+                        modelString = "Pentium IV (65 nm)";
+                        break;
+                }
+            }
+            if(CPUID.getCPUExtendedFamily() == 1){
+                switch(CPUID.getCPUModel()){
+                    //    Itanium 2.. TODO
+                }    
+            }
+        }
+    }
+	@Override
+	public boolean hasX64() {
+		return isX64;
+	}
+}
diff --git a/core/java/src/freenet/support/CPUInformation/UnknownCPUException.java b/core/java/src/freenet/support/CPUInformation/UnknownCPUException.java
index f493980b258404a8f6dc03282a216f19dc6d1bc9..9f7599812bc4075d07c743be42984443db735d09 100644
--- a/core/java/src/freenet/support/CPUInformation/UnknownCPUException.java
+++ b/core/java/src/freenet/support/CPUInformation/UnknownCPUException.java
@@ -8,7 +8,12 @@ package freenet.support.CPUInformation;
  *
  */
 public class UnknownCPUException extends RuntimeException {
-    public UnknownCPUException() {
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 5166144274582583742L;
+
+	public UnknownCPUException() {
         super();
     }
 
diff --git a/core/java/src/freenet/support/CPUInformation/VIACPUInfo.java b/core/java/src/freenet/support/CPUInformation/VIACPUInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..f09131b522dccfa5f9cf7155c5320b7fe6d9e402
--- /dev/null
+++ b/core/java/src/freenet/support/CPUInformation/VIACPUInfo.java
@@ -0,0 +1,16 @@
+package freenet.support.CPUInformation;
+
+public interface VIACPUInfo extends CPUInfo{
+
+    /**
+     * @return true if the CPU present in the machine is at least an 'c3' CPU
+     */
+	public boolean IsC3Compatible();
+    /**
+     * @return true if the CPU present in the machine is at least an 'nano' CPU
+     */
+	public boolean IsNanoCompatible();
+	
+	
+
+}
\ No newline at end of file
diff --git a/core/java/src/freenet/support/CPUInformation/VIAInfoImpl.java b/core/java/src/freenet/support/CPUInformation/VIAInfoImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a112455f47b2296486d3edd17a045b85d6ea3a8
--- /dev/null
+++ b/core/java/src/freenet/support/CPUInformation/VIAInfoImpl.java
@@ -0,0 +1,68 @@
+package freenet.support.CPUInformation;
+
+class VIAInfoImpl extends CPUIDCPUInfo implements VIACPUInfo {
+	
+    protected static boolean isC3Compatible = false;
+    protected static boolean isNanoCompatible = false;
+
+    // If modelString != null, the cpu is considered correctly identified.
+    protected static String modelString = null;
+
+    
+	@Override
+    public boolean IsC3Compatible(){ return isC3Compatible; }
+	@Override
+	public boolean IsNanoCompatible(){ return isNanoCompatible; }
+	
+	static
+	{
+		identifyCPU();
+	}
+	
+    @Override
+    public String getCPUModelString()
+    {
+        if (modelString != null)
+            return modelString;
+        throw new UnknownCPUException("Unknown VIA CPU; Family="+(CPUID.getCPUFamily() + CPUID.getCPUExtendedFamily())+", Model="+(CPUID.getCPUModel() + CPUID.getCPUExtendedModel()));
+    }
+
+
+	@Override
+	public boolean hasX64()
+	{
+		return false;
+	}
+	
+
+	private synchronized static void identifyCPU()
+	{
+        if(CPUID.getCPUFamily() == 6){
+        	isC3Compatible = true; // Possibly not optimal
+            switch(CPUID.getCPUModel()){
+            	case 5:
+            		modelString = "Cyrix M2";
+            		break;
+            	case 6:
+            		modelString = "C5 A/B";
+            		break;
+            	case 7:
+            		modelString = "C5 C";
+            		break;
+            	case 8:
+            		modelString = "C5 N";
+            		break;
+            	case 9:
+            		modelString = "C5 XL/P";
+            		break;
+            	case 10:
+            		modelString = "C5 J";
+            		break;
+            	case 15:
+            		isNanoCompatible = true;
+            		modelString = "Nano";
+            		break;
+            }
+        }
+	}
+}
diff --git a/core/java/src/net/i2p/util/NativeBigInteger.java b/core/java/src/net/i2p/util/NativeBigInteger.java
index 2859488c018e7620278960b67139430fd122b47b..a542bfbe3db1502c97d4c4b47737aaa193157a40 100644
--- a/core/java/src/net/i2p/util/NativeBigInteger.java
+++ b/core/java/src/net/i2p/util/NativeBigInteger.java
@@ -24,6 +24,7 @@ import freenet.support.CPUInformation.AMDCPUInfo;
 import freenet.support.CPUInformation.CPUID;
 import freenet.support.CPUInformation.CPUInfo;
 import freenet.support.CPUInformation.IntelCPUInfo;
+import freenet.support.CPUInformation.VIACPUInfo;
 import freenet.support.CPUInformation.UnknownCPUException;
 
 import net.i2p.I2PAppContext;
@@ -124,13 +125,19 @@ public class NativeBigInteger extends BigInteger {
     private final static String JBIGI_OPTIMIZATION_PENTIUM3   = "pentium3";
     private final static String JBIGI_OPTIMIZATION_PENTIUM4   = "pentium4";
     private final static String JBIGI_OPTIMIZATION_VIAC3      = "viac3";
-    /** below here @since 0.8.7 */
+    /**
+     * The 7 optimizations below here are since 0.8.7. Each of the 32-bit processors below
+     * needs an explicit fallback in getResourceList() or getMiddleName2().
+     * 64-bit processors will fallback to athlon64 and athlon in getResourceList().
+     * @since 0.8.7
+     */
     private final static String JBIGI_OPTIMIZATION_ATOM       = "atom";
     private final static String JBIGI_OPTIMIZATION_CORE2      = "core2";
     private final static String JBIGI_OPTIMIZATION_COREI      = "corei";
     private final static String JBIGI_OPTIMIZATION_GEODE      = "geode";
     private final static String JBIGI_OPTIMIZATION_NANO       = "nano";
     private final static String JBIGI_OPTIMIZATION_PENTIUMM   = "pentiumm";
+    /** all libjbibi builds are identical to pentium3, case handled in getMiddleName2() */
     private final static String JBIGI_OPTIMIZATION_VIAC32     = "viac32";
 
     private static final boolean _isWin = System.getProperty("os.name").startsWith("Win");
@@ -188,14 +195,23 @@ public class NativeBigInteger extends BigInteger {
             try {
                 _cpuModel = c.getCPUModelString();
             } catch (UnknownCPUException e) {}
-            if (c.IsC3Compatible())
-                return JBIGI_OPTIMIZATION_VIAC3;
-            if (c instanceof AMDCPUInfo) {
+            if (c instanceof VIACPUInfo){
+            	VIACPUInfo viacpu = (VIACPUInfo) c;
+            	if (viacpu.IsNanoCompatible())
+            	    return JBIGI_OPTIMIZATION_NANO;
+            	return JBIGI_OPTIMIZATION_VIAC3;
+            } else if(c instanceof AMDCPUInfo) {
                 AMDCPUInfo amdcpu = (AMDCPUInfo) c;
+                // Supported in CPUID, no GMP support
+                //if (amdcpu.IsBobcatCompatible())
+                //    return JBIGI_OPTIMIZATION_BOBCAT;
                 if (amdcpu.IsAthlon64Compatible())
                     return JBIGI_OPTIMIZATION_ATHLON64;
                 if (amdcpu.IsAthlonCompatible())
                     return JBIGI_OPTIMIZATION_ATHLON;
+                // FIXME lots of geodes, but GMP configures like a K6-3
+                if (amdcpu.IsGeodeCompatible())
+                    return JBIGI_OPTIMIZATION_GEODE;
                 if (amdcpu.IsK6_3_Compatible())
                     return JBIGI_OPTIMIZATION_K6_3;
                 if (amdcpu.IsK6_2_Compatible())
@@ -204,8 +220,16 @@ public class NativeBigInteger extends BigInteger {
                     return JBIGI_OPTIMIZATION_K6;
             } else if (c instanceof IntelCPUInfo) {
                 IntelCPUInfo intelcpu = (IntelCPUInfo) c;
+                if (intelcpu.IsCoreiCompatible())
+                    return JBIGI_OPTIMIZATION_COREI;
+                if (intelcpu.IsCore2Compatible())
+                    return JBIGI_OPTIMIZATION_CORE2;
                 if (intelcpu.IsPentium4Compatible())
                     return JBIGI_OPTIMIZATION_PENTIUM4;
+                if (intelcpu.IsAtomCompatible())
+                    return JBIGI_OPTIMIZATION_ATOM;
+                if (intelcpu.IsPentiumMCompatible())
+                    return JBIGI_OPTIMIZATION_PENTIUMM;
                 if (intelcpu.IsPentium3Compatible())
                     return JBIGI_OPTIMIZATION_PENTIUM3;
                 if (intelcpu.IsPentium2Compatible())
@@ -600,12 +624,18 @@ public class NativeBigInteger extends BigInteger {
             }
             // the preferred selection
             rv.add(_libPrefix + getMiddleName1() + primary + _libSuffix);
+
             // athlon64 is always a fallback for 64 bit
             if (_is64 && !primary.equals(JBIGI_OPTIMIZATION_ATHLON64))
                 rv.add(_libPrefix + getMiddleName1() + JBIGI_OPTIMIZATION_ATHLON64 + _libSuffix);
+
             // Add fallbacks for any 32-bit that were added 0.8.7 or later here
-            if (primary.equals(JBIGI_OPTIMIZATION_ATOM))
+            // FIXME lots of geodes, but GMP configures like a K6-3, so pentium3 is probably a good backup
+            if (primary.equals(JBIGI_OPTIMIZATION_ATOM) ||
+                primary.equals(JBIGI_OPTIMIZATION_PENTIUMM) ||
+                primary.equals(JBIGI_OPTIMIZATION_GEODE))
                 rv.add(_libPrefix + getMiddleName1() + JBIGI_OPTIMIZATION_PENTIUM3 + _libSuffix);
+
             // athlon is always a fallback for 64 bit, we have it for all architectures
             // and it should be much better than "none"
             if (_is64)
diff --git a/installer/lib/jbigi/libjbigi-linux-atom.so b/installer/lib/jbigi/libjbigi-linux-atom.so
new file mode 100644
index 0000000000000000000000000000000000000000..8de95258a4a406895f749ee8ec4ea874c7bac109
Binary files /dev/null and b/installer/lib/jbigi/libjbigi-linux-atom.so differ
diff --git a/installer/lib/jbigi/libjbigi-linux-atom_64.so b/installer/lib/jbigi/libjbigi-linux-atom_64.so
new file mode 100644
index 0000000000000000000000000000000000000000..069aeb855304fbf0dbf7e73762859759defab12e
Binary files /dev/null and b/installer/lib/jbigi/libjbigi-linux-atom_64.so differ
diff --git a/installer/lib/jbigi/libjbigi-linux-core2.so b/installer/lib/jbigi/libjbigi-linux-core2.so
new file mode 100644
index 0000000000000000000000000000000000000000..ce34a65ce43173b31771210284034bf7a2f266d6
Binary files /dev/null and b/installer/lib/jbigi/libjbigi-linux-core2.so differ
diff --git a/installer/lib/jbigi/libjbigi-linux-core2_64.so b/installer/lib/jbigi/libjbigi-linux-core2_64.so
new file mode 100644
index 0000000000000000000000000000000000000000..eab1ff757ca9ae63afb5e532cec7e6b0684a8995
Binary files /dev/null and b/installer/lib/jbigi/libjbigi-linux-core2_64.so differ
diff --git a/installer/lib/jbigi/libjbigi-linux-corei.so b/installer/lib/jbigi/libjbigi-linux-corei.so
new file mode 100644
index 0000000000000000000000000000000000000000..ce34a65ce43173b31771210284034bf7a2f266d6
Binary files /dev/null and b/installer/lib/jbigi/libjbigi-linux-corei.so differ
diff --git a/installer/lib/jbigi/libjbigi-linux-corei_64.so b/installer/lib/jbigi/libjbigi-linux-corei_64.so
new file mode 100644
index 0000000000000000000000000000000000000000..e72a3aaaa4e1f2430b3a6d8390448af6ca14bbff
Binary files /dev/null and b/installer/lib/jbigi/libjbigi-linux-corei_64.so differ
diff --git a/installer/lib/jbigi/libjbigi-linux-geode.so b/installer/lib/jbigi/libjbigi-linux-geode.so
new file mode 100644
index 0000000000000000000000000000000000000000..8865e6dcde5423beb2bd3e4fa840fd6aa93bd655
Binary files /dev/null and b/installer/lib/jbigi/libjbigi-linux-geode.so differ
diff --git a/installer/lib/jbigi/libjbigi-linux-nano.so b/installer/lib/jbigi/libjbigi-linux-nano.so
new file mode 100644
index 0000000000000000000000000000000000000000..16873d80c85fd7447e27d8ab65a8b4e97814fb86
Binary files /dev/null and b/installer/lib/jbigi/libjbigi-linux-nano.so differ
diff --git a/installer/lib/jbigi/libjbigi-linux-nano_64.so b/installer/lib/jbigi/libjbigi-linux-nano_64.so
new file mode 100644
index 0000000000000000000000000000000000000000..855e7d56307565ac1823d17ccb8a2a65289c3595
Binary files /dev/null and b/installer/lib/jbigi/libjbigi-linux-nano_64.so differ
diff --git a/installer/lib/jbigi/libjbigi-linux-pentiumm.so b/installer/lib/jbigi/libjbigi-linux-pentiumm.so
new file mode 100644
index 0000000000000000000000000000000000000000..336d5d12060aa6171f3037e26c3934148e47c067
Binary files /dev/null and b/installer/lib/jbigi/libjbigi-linux-pentiumm.so differ