diff --git a/apps/i2psnark/java/src/org/klomp/snark/Message.java b/apps/i2psnark/java/src/org/klomp/snark/Message.java
index bed8b9541e105725ef202ed6fc206ba61258945e..f70df76d66506a35cbf61e18eec0b984798c2038 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Message.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Message.java
@@ -49,6 +49,9 @@ class Message
   final static byte REJECT       = 16;  // Fast (BEP 6)
   final static byte ALLOWED_FAST = 17;  // Fast (BEP 6)
   final static byte EXTENSION    = 20;  // BEP 10
+  final static byte HASH_REQUEST = 21;  // BEP 52
+  final static byte HASHES       = 22;  // BEP 52
+  final static byte HASH_REJECT  = 23;  // BEP 52
   
   // Not all fields are used for every message.
   // KEEP_ALIVE doesn't have a real wire representation
@@ -278,6 +281,13 @@ class Message
         return "REJECT(" + piece + ',' + begin + ',' + length + ')';
       case ALLOWED_FAST:
         return "ALLOWED_FAST(" + piece + ')';
+      // BEP 52 below here
+      case HASH_REQUEST:
+        return "HASH_REQUEST";
+      case HASHES:
+        return "HASHES";
+      case HASH_REJECT:
+        return "HASH_REJECT";
       default:
         return "UNKNOWN (" + type + ')';
       }
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index 684ea62bfeca1ce8aa481057290adeec06d872e8..416b98a47a6db41eefd51dbc73b52c9fbf62d3fb 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -1088,6 +1088,12 @@ public class I2PSnarkServlet extends BasicServlet {
                     // b32
                     newURL = newURL.toUpperCase(Locale.US);
                     addMagnet(MagnetURI.MAGNET_FULL + newURL, dir);
+                } else if (newURL.length() == 68 && newURL.startsWith("1220") &&
+                           newURL.replaceAll("[a-fA-F0-9]", "").length() == 0) {
+                    // hex v2 multihash
+                    // TODO
+                    _manager.addMessage("Version 2 info hashes are not supported");
+                    //addMagnet(MagnetURI.MAGNET_FULL_V2 + newURL, dir);
                 } else {
                     // try as file path, hopefully we're on the same box
                     if (newURL.startsWith("file://"))
@@ -3282,6 +3288,7 @@ public class I2PSnarkServlet extends BasicServlet {
             else
                 buf.append(_t("Complete")).append("</b>");
             buf.append("</td><td><span>");
+            // TODO adjust for padding files
             buf.append("<b>")
                .append(_t("Size"))
                .append(":</b> ")
@@ -3300,6 +3307,7 @@ public class I2PSnarkServlet extends BasicServlet {
             } else {
                 buf.append('0');
             }
+            // TODO adjust for padding files
             // not including skipped files, but -1 when not running
             long needed = snark.getNeededLength();
             if (needed < 0) {
@@ -3313,6 +3321,7 @@ public class I2PSnarkServlet extends BasicServlet {
                    .append(":</b> ")
                    .append(formatSize(needed));
             }
+            // TODO adjust for padding files
             long skipped = snark.getSkippedLength();
             if (skipped > 0) {
                 buf.append("</span>&nbsp;<span>");
@@ -3321,9 +3330,8 @@ public class I2PSnarkServlet extends BasicServlet {
                    .append(":</b> ")
                    .append(formatSize(skipped));
             }
-            if (meta != null) {
-                List<List<String>> files = meta.getFiles();
-                int fileCount = files != null ? files.size() : 1;
+            if (storage != null) {
+                int fileCount = storage.getFileCount();
                 buf.append("</span>&nbsp;<span>");
                 buf.append("<b>")
                    .append(_t("Files"))
@@ -3455,7 +3463,16 @@ public class I2PSnarkServlet extends BasicServlet {
         long[] remainingArray = (arrays != null) ? arrays[0] : null;
         long[] previewArray = (arrays != null) ? arrays[1] : null;
         for (int i = 0; i < ls.length; i++) {
-            fileList.add(new Sorters.FileAndIndex(ls[i], storage, remainingArray, previewArray));
+            File f = ls[i];
+            if (isTopLevel) {
+                // Hide (assumed) padding directory if it's in the filesystem.
+                // Storage now will not create padding files, but
+                // may have been created by an old version or other client.
+                String n = f.getName();
+                if ((n.equals(".pad") || n.equals("_pad")) && f.isDirectory())
+                    continue;
+            }
+            fileList.add(new Sorters.FileAndIndex(f, storage, remainingArray, previewArray));
         }
 
         boolean showSort = fileList.size() > 1;
@@ -3616,7 +3633,7 @@ public class I2PSnarkServlet extends BasicServlet {
             }
 
             String path = addPaths(decodedBase, item.getName());
-            if (item.isDirectory() && !path.endsWith("/"))
+            if (fai.isDirectory && !path.endsWith("/"))
                 path=addPaths(path,"/");
             path = encodePath(path);
             String icon = toIcon(item);
@@ -3676,14 +3693,14 @@ public class I2PSnarkServlet extends BasicServlet {
             if (preview != null)
                 buf.append(preview);
             buf.append("</td><td align=right class=\"snarkFileSize\">");
-            if (!item.isDirectory())
+            if (!fai.isDirectory)
                 buf.append(formatSize(length));
             buf.append("</td><td class=\"snarkFileStatus\">");
             buf.append(status);
             buf.append("</td>");
             if (showPriority) {
                 buf.append("<td class=\"priority\">");
-                if ((!complete) && (!item.isDirectory())) {
+                if ((!complete) && (!fai.isDirectory)) {
                     if (!inOrder) {
                         buf.append("<label class=\"priorityHigh\" title=\"").append(_t("Download file at high priority")).append("\">" +
                                    "\n<input type=\"radio\" class=\"prihigh\" value=\"5\" name=\"pri.").append(fileIndex).append("\" ");