diff --git a/core/java/src/freenet/support/CPUInformation/CPUID.java b/core/java/src/freenet/support/CPUInformation/CPUID.java
index 83aa333670190594c3d0b5793d4cf965edaba230..d8f8967fba64c55aa83639227854d8ff8b46d310 100644
--- a/core/java/src/freenet/support/CPUInformation/CPUID.java
+++ b/core/java/src/freenet/support/CPUInformation/CPUID.java
@@ -1,5 +1,6 @@
 /*
  * Created on Jul 14, 2004
+ * Updated on Jan 8, 2011
  */
 package freenet.support.CPUInformation;
 
@@ -129,11 +130,26 @@ public class CPUID {
         CPUIDResult c = doCPUID(1);
         return c.EAX & 0xf;
     }
-    private static int getCPUFlags()
+    private static int getEDXCPUFlags()
     {
         CPUIDResult c = doCPUID(1);
         return c.EDX;
     }
+    private static int getECXCPUFlags()
+    {
+        CPUIDResult c = doCPUID(1);
+        return c.ECX;
+    }
+    private static int getExtendedEDXCPUFlags()
+    {
+        CPUIDResult c = doCPUID(0x80000001);
+        return c.EDX;
+    }
+    private static int getExtendedECXCPUFlags()
+    {
+        CPUIDResult c = doCPUID(0x80000001);
+        return c.ECX;
+    }
     
     //Returns a CPUInfo item for the current type of CPU
     //If I could I would declare this method in a interface named
@@ -163,13 +179,25 @@ public class CPUID {
             return getCPUVendorID();
         }
         public boolean hasMMX(){
-            return (getCPUFlags() & 0x800000) >0; //Bit 23
+            return (getEDXCPUFlags() & 0x800000) >0; //EDX Bit 23
         }
         public boolean hasSSE(){
-            return (getCPUFlags() & 0x2000000) >0; //Bit 25
+            return (getEDXCPUFlags() & 0x2000000) >0; //EDX Bit 25
         }
         public boolean hasSSE2(){
-            return (getCPUFlags() & 0x4000000) >0; //Bit 26
+            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; }
     }
@@ -296,77 +324,119 @@ public class CPUID {
             return getCPUFamily() > 6 || (getCPUFamily() == 6 && getCPUModel() >=3);
         }
         public boolean IsPentium3Compatible()
-        {
-            return getCPUFamily() > 6 || (getCPUFamily() == 6 && getCPUModel() >=7);
+        {	
+		// Atom
+		if (getCPUExtendedModel() == 1 && (getCPUFamily() == 6 && (getCPUModel() == 10))){
+			return true;
+		// ??
+		} else if (getCPUFamily() > 6 || (getCPUFamily() == 6 && getCPUModel() >=7)){
+			return true;
+		} else {
+			return false;
+		}
         }
         public boolean IsPentium4Compatible()
-        {
-            return getCPUFamily() >= 15;
+        {	
+			// 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(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(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 (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){
-                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";
-                    case 10:
-                        return "Pentium III Xeon (Cascades)";
-                    case 11:
-                        return "Pentium III (130 nm)";
-                }
+            	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()){
@@ -384,6 +454,10 @@ public class CPUID {
                             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){
@@ -407,7 +481,7 @@ public class CPUID {
         System.out.println("CPU Family: " + getCPUFamily());
         System.out.println("CPU Model: " + getCPUModel());
         System.out.println("CPU Stepping: " + getCPUStepping());
-        System.out.println("CPU Flags: " + getCPUFlags());
+        System.out.println("CPU Flags: " + getEDXCPUFlags());
         
         CPUInfo c = getInfo();
         System.out.println(" **More CPUInfo**");
@@ -415,6 +489,10 @@ public class CPUID {
         System.out.println(" CPU has MMX: " + c.hasMMX());
         System.out.println(" CPU has SSE: " + c.hasSSE());
         System.out.println(" CPU has SSE2: " + c.hasSSE2());
+        System.out.println(" CPU has SSE3: " + c.hasSSE3());
+        System.out.println(" CPU has SSE4.1: " + c.hasSSE41());
+        System.out.println(" CPU has SSE4.2: " + c.hasSSE42());
+        System.out.println(" CPU has SSE4A: " + c.hasSSE4A());
         if(c instanceof IntelCPUInfo){
             System.out.println("  **Intel-info**");
             System.out.println("  Is pII-compatible: "+((IntelCPUInfo)c).IsPentium2Compatible());
diff --git a/core/java/src/freenet/support/CPUInformation/CPUInfo.java b/core/java/src/freenet/support/CPUInformation/CPUInfo.java
index e6b6609278a6f15a9a1ca907ce736e5ff793d324..43dfcd8d0faea14c78f57c2583c246af10f2046b 100644
--- a/core/java/src/freenet/support/CPUInformation/CPUInfo.java
+++ b/core/java/src/freenet/support/CPUInformation/CPUInfo.java
@@ -1,6 +1,6 @@
 /*
- * Created on Jul 16, 2004
- *
+ * Created on Jul 14, 2004
+ * Updated on Jan 8, 2011
  */
 package freenet.support.CPUInformation;
 
@@ -42,5 +42,25 @@ public interface CPUInfo
      */
     public boolean hasSSE2();
 
+    /**
+     * @return true iff the CPU support the SSE3 instruction set.
+     */
+    public boolean hasSSE3();
+    
+    /**
+     * @return true iff the CPU support the SSE4.1 instruction set.
+     */
+    public boolean hasSSE41();
+
+    /**
+     * @return true iff the CPU support the SSE4.2 instruction set.
+     */
+    public boolean hasSSE42();
+
+    /**
+     * @return true iff the CPU support the SSE4A instruction set.
+     */
+    public boolean hasSSE4A();
+
     public boolean IsC3Compatible();
 }
diff --git a/core/java/src/net/i2p/data/PrivateKey.java b/core/java/src/net/i2p/data/PrivateKey.java
index bf415bdc9c522acabcae644858666858c5cfff21..5b0a5e4bbb4512824e82ad355c3ec858e25b448f 100644
--- a/core/java/src/net/i2p/data/PrivateKey.java
+++ b/core/java/src/net/i2p/data/PrivateKey.java
@@ -16,6 +16,9 @@ import net.i2p.crypto.KeyGenerator;
  * A private key is 256byte Integer. The private key represents only the 
  * exponent, not the primes, which are constant and defined in the crypto spec.
  *
+ * Note that we use short exponents, so all but the last 28.25 bytes are zero.
+ * See http://www.i2p2.i2p/how_cryptography for details.
+ *
  * @author jrandom
  */
 public class PrivateKey extends SimpleDataStructure {
@@ -50,4 +53,24 @@ public class PrivateKey extends SimpleDataStructure {
         return KeyGenerator.getPublicKey(this);
     }
 
+    /**
+     * We assume the data has enough randomness in it, so use the last 4 bytes for speed.
+     * Overridden since we use short exponents, so the first 227 bytes are all zero.
+     * Not that we are storing PrivateKeys in any Sets or Maps anywhere.
+     */
+    @Override
+    public int hashCode() {
+        if (_data == null)
+            return 0;
+        int rv = _data[KEYSIZE_BYTES - 4];
+        for (int i = 1; i < 4; i++)
+            rv ^= (_data[i + (KEYSIZE_BYTES - 4)] << (i*8));
+        return rv;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if ((obj == null) || !(obj instanceof PrivateKey)) return false;
+        return DataHelper.eq(_data, ((PrivateKey) obj)._data);
+    }
 }
diff --git a/core/java/src/net/i2p/util/LogManager.java b/core/java/src/net/i2p/util/LogManager.java
index 49eaf291febff73acf522210ae7d186ac07684ad..0ca7ef209c4ffe25a7223846c5cf1cda951bd569 100644
--- a/core/java/src/net/i2p/util/LogManager.java
+++ b/core/java/src/net/i2p/util/LogManager.java
@@ -152,7 +152,9 @@ public class LogManager {
         if (_writer != null)
             return;
         _writer = new LogWriter(this);
-        Thread t = new I2PThread(_writer, "LogWriter", true);
+        // NOT an I2PThread, as it contains logging and we end up with problems
+        Thread t = new Thread(_writer, "LogWriter");
+        t.setDaemon(true);
         t.start();
     }