Merge "Add internal API for note iteration"
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java
index 2085676..5d35355 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java
@@ -46,9 +46,12 @@
 import static org.eclipse.jgit.lib.FileMode.TREE;
 
 import java.io.IOException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.MutableObjectId;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.ObjectReader;
@@ -108,6 +111,54 @@ ObjectId get(AnyObjectId objId, ObjectReader or) throws IOException {
 	}
 
 	@Override
+	Iterator<Note> iterator(AnyObjectId objId, final ObjectReader reader)
+			throws IOException {
+		final MutableObjectId id = new MutableObjectId();
+		id.fromObjectId(objId);
+
+		return new Iterator<Note>() {
+			private int cell;
+
+			private Iterator<Note> itr;
+
+			public boolean hasNext() {
+				if (itr != null && itr.hasNext())
+					return true;
+
+				for (; cell < table.length; cell++) {
+					NoteBucket b = table[cell];
+					if (b == null)
+						continue;
+
+					try {
+						id.setByte(prefixLen >> 1, cell);
+						itr = b.iterator(id, reader);
+					} catch (IOException err) {
+						throw new RuntimeException(err);
+					}
+
+					if (itr.hasNext()) {
+						cell++;
+						return true;
+					}
+				}
+				return false;
+			}
+
+			public Note next() {
+				if (hasNext())
+					return itr.next();
+				else
+					throw new NoSuchElementException();
+			}
+
+			public void remove() {
+				throw new UnsupportedOperationException();
+			}
+		};
+	}
+
+	@Override
 	InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
 			ObjectReader or) throws IOException {
 		int cell = cell(noteOn);
@@ -194,6 +245,12 @@ ObjectId get(AnyObjectId objId, ObjectReader or) throws IOException {
 		}
 
 		@Override
+		Iterator<Note> iterator(AnyObjectId objId, ObjectReader reader)
+				throws IOException {
+			return load(objId, reader).iterator(objId, reader);
+		}
+
+		@Override
 		InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
 				ObjectReader or) throws IOException {
 			return load(noteOn, or).set(noteOn, noteData, or);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java
index 40be45f..67bb3c8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java
@@ -47,6 +47,8 @@
 import static org.eclipse.jgit.lib.FileMode.REGULAR_FILE;
 
 import java.io.IOException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.ObjectId;
@@ -103,6 +105,28 @@ ObjectId get(AnyObjectId objId, ObjectReader or) {
 		return 0 <= idx ? notes[idx].getData() : null;
 	}
 
+	@Override
+	Iterator<Note> iterator(AnyObjectId objId, ObjectReader reader) {
+		return new Iterator<Note>() {
+			private int idx;
+
+			public boolean hasNext() {
+				return idx < cnt;
+			}
+
+			public Note next() {
+				if (hasNext())
+					return notes[idx++];
+				else
+					throw new NoSuchElementException();
+			}
+
+			public void remove() {
+				throw new UnsupportedOperationException();
+			}
+		};
+	}
+
 	InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
 			ObjectReader or) throws IOException {
 		int p = search(noteOn);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteBucket.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteBucket.java
index f546514..e13067c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteBucket.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteBucket.java
@@ -44,6 +44,7 @@
 package org.eclipse.jgit.notes;
 
 import java.io.IOException;
+import java.util.Iterator;
 
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.ObjectId;
@@ -60,6 +61,9 @@ abstract class NoteBucket {
 	abstract ObjectId get(AnyObjectId objId, ObjectReader reader)
 			throws IOException;
 
+	abstract Iterator<Note> iterator(AnyObjectId objId, ObjectReader reader)
+			throws IOException;
+
 	abstract InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
 			ObjectReader reader) throws IOException;