Index: /trunk/psLib/src/types/psMetadata.c
===================================================================
--- /trunk/psLib/src/types/psMetadata.c	(revision 7917)
+++ /trunk/psLib/src/types/psMetadata.c	(revision 7918)
@@ -12,6 +12,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.117 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-07-15 02:57:12 $
+ *  @version $Revision: 1.118 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-07-17 22:41:38 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -919,8 +919,4 @@
 
     psMetadataIterator* newIter = psAlloc(sizeof(psMetadataIterator));
-    newIter->regex = NULL;
-    newIter->iter = NULL;
-
-    // Set deallocator
     psMemSetDeallocator(newIter, (psFreeFunc) metadataIteratorFree);
 
@@ -929,9 +925,8 @@
     if (regex) {
         newIter->regex = psAlloc(sizeof(regex_t));
-        int regRtn = regcomp(newIter->regex,regex,0);
+        int regRtn = regcomp(newIter->regex, regex, 0);
         if (regRtn != 0) {
             char errMsg[256];
             regerror(regRtn, newIter->regex, errMsg, 256);
-            regfree(newIter->regex);
             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                     PS_ERRORTEXT_psMetadata_REGEX_INVALID,
@@ -940,4 +935,11 @@
             return NULL;
         }
+        if (!psMetadataIteratorSet(newIter, location)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to set location=%d for metadata iterator.\n", location);
+            psFree(newIter);
+            return NULL;
+        }
+    } else {
+        newIter->regex = NULL;
     }
 
@@ -948,25 +950,25 @@
                            long location)
 {
-    int match;
-    psMetadataItem* cursor;
-
-    PS_ASSERT_PTR_NON_NULL(iterator,NULL);
-
-    psListIterator* iter = iterator->iter;
-    PS_ASSERT_PTR_NON_NULL(iterator->iter,NULL);
-
-    regex_t* regex = iterator->regex;
+    PS_ASSERT_PTR_NON_NULL(iterator, NULL);
+    psListIterator *listIter = iterator->iter;
+    PS_ASSERT_PTR_NON_NULL(listIter, NULL);
+
+    regex_t *regex = iterator->regex;
 
     // handle trivial case where no regex subsetting is required.
     if (regex == NULL) {
-        return psListIteratorSet(iter,location);
-    }
-
+        return psListIteratorSet(listIter, location);
+    }
+
+    // If there's a regex, then we need to count into the list.
+    // We count ONLY those entries that match the regex
+
+    // Here we count in from the tail
     if (location < 0) {
-        // match from the tail
-        match = 0;
-        psListIteratorSet(iter,PS_LIST_TAIL);
-        while ( (cursor=(psMetadataItem*)iter->cursor) != NULL) {
-            if (regexec(regex, cursor->name, 0, NULL, 0) == 0) {
+        psListIteratorSet(listIter, PS_LIST_TAIL);
+        psMetadataItem *item;           // Item from iteration
+        int match = 0;                  // Match number
+        while (listIter->cursor && (item = listIter->cursor->data)) {
+            if (regexec(regex, item->name, 0, NULL, 0) == 0) {
                 // this key is a match
                 match--;
@@ -975,14 +977,15 @@
                 }
             }
-            (void)psListGetAndDecrement(iter);
+            (void)psListGetAndDecrement(listIter);
         }
         return (match == location);
     }
 
-    // find the n-th match from the head
-    match = -1;
-    psListIteratorSet(iter,PS_LIST_HEAD);
-    while ( (cursor=(psMetadataItem*)iter->cursor) != NULL) {
-        if (regexec(regex, cursor->name, 0, NULL, 0) == 0) {
+    // Here we count in from the head
+    psListIteratorSet(listIter, PS_LIST_HEAD);
+    psMetadataItem *item;               // Item from iteration
+    int match = -1;                     // Match number
+    while (listIter->cursor && (item = listIter->cursor->data)) {
+        if (regexec(regex, item->name, 0, NULL, 0) == 0) {
             // this key is a match
             match++;
@@ -991,5 +994,5 @@
             }
         }
-        (void)psListGetAndIncrement(iter);
+        (void)psListGetAndIncrement(listIter);
     }
     return (match == location);
@@ -998,10 +1001,7 @@
 psMetadataItem* psMetadataGetAndIncrement(psMetadataIterator* iterator)
 {
-    psMetadataItem* oldValue;
-
     PS_ASSERT_PTR_NON_NULL(iterator,NULL);
-
-    psListIterator* iter = iterator->iter;
-    PS_ASSERT_PTR_NON_NULL(iterator->iter,NULL);
+    psListIterator* listIter = iterator->iter;
+    PS_ASSERT_PTR_NON_NULL(listIter,NULL);
 
     regex_t* regex = iterator->regex;
@@ -1009,27 +1009,23 @@
     // handle trivial case where no regex subsetting is required.
     if (regex == NULL) {
-        return (psMetadataItem*)psListGetAndIncrement(iter);
-    }
-
-    oldValue = (psMetadataItem*)iter->cursor;
-
-    while (psListGetAndIncrement(iter) != NULL) {
-        if (iter->cursor != NULL &&
-                regexec(regex, ((psMetadataItem*)iter->cursor->data)->name, 0, NULL, 0) == 0) {
+        return (psMetadataItem*)psListGetAndIncrement(listIter);
+    }
+
+    // Iterate until we find something matching the regex
+    psMetadataItem *newItem;            // New MD item from iteration
+    while ((newItem = psListGetAndIncrement(listIter))) {
+        if (regexec(regex, newItem->name, 0, NULL, 0) == 0) {
             // this key is a match
             break;
         }
     }
-    return oldValue;
+    return newItem;
 }
 
 psMetadataItem* psMetadataGetAndDecrement(psMetadataIterator* iterator)
 {
-    psMetadataItem* oldValue;
-
-    PS_ASSERT_PTR_NON_NULL(iterator,NULL);
-
-    psListIterator* iter = iterator->iter;
-    PS_ASSERT_PTR_NON_NULL(iterator->iter,NULL);
+    PS_ASSERT_PTR_NON_NULL(iterator, NULL);
+    psListIterator* listIter = iterator->iter;
+    PS_ASSERT_PTR_NON_NULL(listIter, NULL);
 
     regex_t* regex = iterator->regex;
@@ -1037,17 +1033,16 @@
     // handle trivial case where no regex subsetting is required.
     if (regex == NULL) {
-        return (psMetadataItem*)psListGetAndDecrement(iter);
-    }
-
-    oldValue = (psMetadataItem*)iter->cursor;
-
-    while (psListGetAndDecrement(iter) != NULL) {
-        if (iter->cursor != NULL &&
-                regexec(regex, ((psMetadataItem*)iter->cursor)->name, 0, NULL, 0) == 0) {
+        return (psMetadataItem*)psListGetAndDecrement(listIter);
+    }
+
+    // Iterate until we find something matching the regex
+    psMetadataItem *newItem;            // New MD item from iteration
+    while ((newItem = psListGetAndDecrement(listIter))) {
+        if (regexec(regex, newItem->name, 0, NULL, 0) == 0) {
             // this key is a match
             break;
         }
     }
-    return oldValue;
+    return newItem;
 }
 
Index: /trunk/psLib/test/types/.cvsignore
===================================================================
--- /trunk/psLib/test/types/.cvsignore	(revision 7917)
+++ /trunk/psLib/test/types/.cvsignore	(revision 7918)
@@ -43,2 +43,4 @@
 mdcfgwrt.verified
 
+tap_psListIterator
+tap_psMetadataIterator
Index: /trunk/psLib/test/types/Makefile.am
===================================================================
--- /trunk/psLib/test/types/Makefile.am	(revision 7917)
+++ /trunk/psLib/test/types/Makefile.am	(revision 7918)
@@ -27,5 +27,6 @@
 	tst_psPixels \
 	tst_psArguments \
-	tap_psMetadataIterator
+	tap_psMetadataIterator \
+	tap_psListIterator
 
 
@@ -53,4 +54,7 @@
 tap_psMetadataIterator_CPPFLAGS   = $(AM_CPPFLAGS) -I$(top_srcdir)/test/tap/src
 tap_psMetadataIterator_LDFLAGS    = $(AM_LDFLAGS) $(top_builddir)/test/tap/src/libtap.la
+
+tap_psListIterator_CPPFLAGS   = $(AM_CPPFLAGS) -I$(top_srcdir)/test/tap/src
+tap_psListIterator_LDFLAGS    = $(AM_LDFLAGS) $(top_builddir)/test/tap/src/libtap.la
 
 check_DATA = \
Index: /trunk/psLib/test/types/tap_psListIterator.c
===================================================================
--- /trunk/psLib/test/types/tap_psListIterator.c	(revision 7918)
+++ /trunk/psLib/test/types/tap_psListIterator.c	(revision 7918)
@@ -0,0 +1,186 @@
+#include <stdio.h>
+#include <pslib.h>
+#include "tap.h"
+
+#define STRING1 "This is string #1"
+#define STRING2 "String number 2"
+#define STRING3 "3 number string"
+#define STRING4 "four number string"
+#define STRING5 "number five string"
+#define STRING6 "#6 string"
+#define STRING7 "#7 $7r!Ng"
+
+
+// Generate a dummy list
+static psList *listGenerate(void)
+{
+    psList *list = psListAlloc(NULL);
+
+    // Generate the strings
+    psString string1 = psStringCopy(STRING1);
+    psString string2 = psStringCopy(STRING2);
+    psString string3 = psStringCopy(STRING3);
+    psString string4 = psStringCopy(STRING4);
+    psString string5 = psStringCopy(STRING5);
+    psString string6 = psStringCopy(STRING6);
+    psString string7 = psStringCopy(STRING7);
+
+    // Add the strings to the list
+    psListAdd(list, PS_LIST_TAIL, string1);
+    psListAdd(list, PS_LIST_TAIL, string2);
+    psListAdd(list, PS_LIST_TAIL, string3);
+    psListAdd(list, PS_LIST_TAIL, string4);
+    psListAdd(list, PS_LIST_TAIL, string5);
+    psListAdd(list, PS_LIST_TAIL, string6);
+    psListAdd(list, PS_LIST_TAIL, string7);
+
+    // Drop references
+    psFree(string1);
+    psFree(string2);
+    psFree(string3);
+    psFree(string4);
+    psFree(string5);
+    psFree(string6);
+    psFree(string7);
+
+    return list;
+}
+
+// Function to perform iteration
+typedef psString (*iterFunc)(psListIterator *iter);
+
+
+// Test the iteration by iterating once and checking the name, comment, and data
+static void testIteration(iterFunc function, // Function to use to iterate
+                          psListIterator *iterator, // The iterator
+                          const char *string // Expected string
+                         )
+{
+    psString output = function(iterator);
+    ok(output, "output = %x", output);
+    skip_start(!output, 1, "Skipping test because iteration failed");
+    ok(strcmp(output, string) == 0, "output = %s", output);
+    skip_end();
+
+    return;
+}
+
+
+int main (void)
+{
+    //plan_tests(158);
+
+    diag("psListIterator tests");
+
+    {
+        diag("Forwards");
+        psList *list = listGenerate();
+        psListIterator *iter = psListIteratorAlloc(list, PS_LIST_HEAD, false);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 14, "Skipping 14 tests because psMetadataIteratorAlloc failed");
+
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING1);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING2);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING3);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING4);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING5);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING6);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING7);
+
+        skip_end();
+        psFree(iter);
+        psFree(list);
+    }
+
+    {
+        diag("Backwards");
+        psList *list = listGenerate();
+        psListIterator *iter = psListIteratorAlloc(list, PS_LIST_TAIL, NULL);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 14, "Skipping 14 tests because psListIteratorAlloc failed");
+
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING7);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING6);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING5);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING4);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING3);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING2);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING1);
+
+        skip_end();
+        psFree(iter);
+        psFree(list);
+    }
+
+    {
+        diag("Jumping in halfway through (using allocator), forwards");
+        psList *list = listGenerate();
+        psListIterator *iter = psListIteratorAlloc(list, 3, NULL);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 8, "Skipping 8 tests because psListIteratorAlloc failed");
+
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING4);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING5);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING6);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING7);
+
+        skip_end();
+        psFree(iter);
+        psFree(list);
+    }
+
+    {
+        diag("Jumping in halfway through (using allocator), backwards");
+        psList *list = listGenerate();
+        psListIterator *iter = psListIteratorAlloc(list, -4, NULL);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 8, "Skipping 8 tests because psListIteratorAlloc failed");
+
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING4);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING3);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING2);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING1);
+
+        skip_end();
+        psFree(iter);
+        psFree(list);
+    }
+
+    {
+        diag("Jumping in halfway through (using set), forwards");
+        psList *list = listGenerate();
+        psListIterator *iter = psListIteratorAlloc(list, PS_LIST_HEAD, NULL);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 8, "Skipping 8 tests because psListIteratorAlloc failed");
+        psListIteratorSet(iter, 3);
+
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING4);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING5);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING6);
+        testIteration((iterFunc)psListGetAndIncrement, iter, STRING7);
+
+        skip_end();
+        psFree(iter);
+        psFree(list);
+    }
+
+    {
+        diag("Jumping in halfway through (using set), backwards");
+        psList *list = listGenerate();
+        psListIterator *iter = psListIteratorAlloc(list, PS_LIST_HEAD, NULL);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 8, "Skipping 8 tests because psListIteratorAlloc failed");
+        psListIteratorSet(iter, -4);
+
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING4);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING3);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING2);
+        testIteration((iterFunc)psListGetAndDecrement, iter, STRING1);
+
+        skip_end();
+        psFree(iter);
+        psFree(list);
+    }
+
+    return exit_status();
+}
Index: /trunk/psLib/test/types/tap_psMetadataIterator.c
===================================================================
--- /trunk/psLib/test/types/tap_psMetadataIterator.c	(revision 7917)
+++ /trunk/psLib/test/types/tap_psMetadataIterator.c	(revision 7918)
@@ -12,15 +12,15 @@
 #define COMMENT2 "This is a    "
 #define FLAG2 PS_META_DUPLICATE_OK
-#define VALUE2 ""
+#define VALUE2 "   comment."
 
 #define NAME3 "FILENAME"
 #define COMMENT3 "File name"
 #define FLAG3 0
-#define VALUE3 "abcdefg123456.fits"
+#define VALUE3 "abcdef123456.fits"
 
 #define NAME4 "COMMENT"
-#define COMMENT4 "   comment   "
+#define COMMENT4 "   this IS a   "
 #define FLAG4 PS_META_DUPLICATE_OK
-#define VALUE4 ""
+#define VALUE4 "comment    too!"
 
 #define NAME5 "DATE-OBS"
@@ -30,12 +30,12 @@
 
 #define NAME6 "COMMENT"
-#define COMMENT6 "    block"
+#define COMMENT6 "    another"
 #define FLAG6 PS_META_DUPLICATE_OK
-#define VALUE6 ""
+#define VALUE6 "comment     "
 
 #define NAME7 "COMMENT"
 #define COMMENT7 "This is another comment"
 #define FLAG7 PS_META_DUPLICATE_OK
-#define VALUE7 ""
+#define VALUE7 "Hello world"
 
 #define MULTI_NAME "COMMENT"
@@ -48,6 +48,11 @@
 #define MULTI_COMMENT3 COMMENT6
 #define MULTI_COMMENT4 COMMENT7
-
-psMetadata *mdGenerate(void)
+#define MULTI_VALUE1 VALUE2
+#define MULTI_VALUE2 VALUE4
+#define MULTI_VALUE3 VALUE6
+#define MULTI_VALUE4 VALUE7
+
+// Generate a dummy metadata
+static psMetadata *mdGenerate(void)
 {
     psMetadata *md = psMetadataAlloc();
@@ -65,58 +70,243 @@
 }
 
-#define TEST_ITERATION(NAME, COMMENT, VALUE) \
-item = psMetadataGetAndIncrement(iter); \
-ok(item, "item = %x", item); \
-skip_start(!item, 3, "Skipping 3 tests because psMetadataGetAndIncrement failed"); \
-ok(strcmp(item->name, NAME) == 0, "item->name = %s", item->name); \
-ok(strcmp(item->comment, COMMENT) == 0, "item->comment = %s", item->comment); \
-ok(strcmp(item->data.V, VALUE) == 0, "item->data.V = %s", item->data.V); \
-skip_end();
+// Function to perform iteration
+typedef psMetadataItem *(*iterFunc)(psMetadataIterator *iter);
+
+
+// Test the iteration by iterating once and checking the name, comment, and data
+static void testIteration(iterFunc function, // Function to use to iterate
+                          psMetadataIterator *iterator, // The iterator
+                          const char *name, // Name of the item
+                          const char *comment, // Comment for the item
+                          const char *value // Value for the item
+                         )
+{
+    psMetadataItem *item = function(iterator);
+    ok(item, "item = %x", item);
+    skip_start(!item, 4, "Skipping 4 tests because iteration failed");
+    ok(strcmp(item->name, name) == 0, "item->name = %s", item->name);
+    ok(strcmp(item->comment, comment) == 0, "item->comment = %s", item->comment);
+    ok(item->type == PS_DATA_STRING, "item->type = %x", item->type);
+    skip_start(item->type != PS_DATA_STRING, 1, "Skipping 1 test because the item has incorrect type");
+    ok(strcmp(item->data.V, value) == 0, "item->data.V = %s", item->data.V);
+    skip_end();
+    skip_end();
+
+    return;
+}
 
 
 int main (void)
 {
-    plan_tests(42);
+    plan_tests(242);
 
     diag("psMetadataIterator tests");
 
-    // No regular expressions
-    {
+    {
+        diag("No regular expressions, forwards");
         psMetadata *md = mdGenerate();
         psMetadataIterator *iter = psMetadataIteratorAlloc(md, PS_LIST_HEAD, NULL);
         ok(iter, "iter = %x", iter);
-        skip_start(!iter, 28, "Skipping 28 tests because psMetadataIteratorAlloc failed");
-        psMetadataItem *item;
-
-        TEST_ITERATION(NAME1, COMMENT1, VALUE1);
-        TEST_ITERATION(NAME2, COMMENT2, VALUE2);
-        TEST_ITERATION(NAME3, COMMENT3, VALUE3);
-        TEST_ITERATION(NAME4, COMMENT4, VALUE4);
-        TEST_ITERATION(NAME5, COMMENT5, VALUE5);
-        TEST_ITERATION(NAME6, COMMENT6, VALUE6);
-        TEST_ITERATION(NAME7, COMMENT7, VALUE7);
-
-        skip_end();
-        psFree(iter);
-        psFree(md);
-    }
-
-    // With regular expressions
-    {
+        skip_start(!iter, 35, "Skipping 35 tests because psMetadataIteratorAlloc failed");
+
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME1, COMMENT1, VALUE1);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME2, COMMENT2, VALUE2);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME3, COMMENT3, VALUE3);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME4, COMMENT4, VALUE4);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME5, COMMENT5, VALUE5);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME6, COMMENT6, VALUE6);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME7, COMMENT7, VALUE7);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("No regular expressions, backwards");
+        psMetadata *md = mdGenerate();
+        psMetadataIterator *iter = psMetadataIteratorAlloc(md, PS_LIST_TAIL, NULL);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 35, "Skipping 35 tests because psMetadataIteratorAlloc failed");
+
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME7, COMMENT7, VALUE7);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME6, COMMENT6, VALUE6);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME5, COMMENT5, VALUE5);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME4, COMMENT4, VALUE4);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME3, COMMENT3, VALUE3);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME2, COMMENT2, VALUE2);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME1, COMMENT1, VALUE1);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("No regular expressions, jumping in halfway through (using allocator), forwards");
+        psMetadata *md = mdGenerate();
+        psMetadataIterator *iter = psMetadataIteratorAlloc(md, 3, NULL);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 20, "Skipping 20 tests because psMetadataIteratorAlloc failed");
+
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME4, COMMENT4, VALUE4);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME5, COMMENT5, VALUE5);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME6, COMMENT6, VALUE6);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME7, COMMENT7, VALUE7);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("No regular expressions, jumping in halfway through (using allocator), backwards");
+        psMetadata *md = mdGenerate();
+        psMetadataIterator *iter = psMetadataIteratorAlloc(md, -4, NULL);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 15, "Skipping 20 tests because psMetadataIteratorAlloc failed");
+
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME4, COMMENT4, VALUE4);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME3, COMMENT3, VALUE3);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME2, COMMENT2, VALUE2);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME1, COMMENT1, VALUE1);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("No regular expressions, jumping in halfway through (using set), forwards");
+        psMetadata *md = mdGenerate();
+        psMetadataIterator *iter = psMetadataIteratorAlloc(md, PS_LIST_HEAD, NULL);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 20, "Skipping 20 tests because psMetadataIteratorAlloc failed");
+        psMetadataIteratorSet(iter, 3);
+
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME4, COMMENT4, VALUE4);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME5, COMMENT5, VALUE5);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME6, COMMENT6, VALUE6);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, NAME7, COMMENT7, VALUE7);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("No regular expressions, jumping in halfway through (using set), backwards");
+        psMetadata *md = mdGenerate();
+        psMetadataIterator *iter = psMetadataIteratorAlloc(md, PS_LIST_HEAD, NULL);
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 15, "Skipping 20 tests because psMetadataIteratorAlloc failed");
+        psMetadataIteratorSet(iter, -4);
+
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME4, COMMENT4, VALUE4);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME3, COMMENT3, VALUE3);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME2, COMMENT2, VALUE2);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, NAME1, COMMENT1, VALUE1);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("With regular expressions, forwards");
         psMetadata *md = mdGenerate();
         psMetadataIterator *iter = psMetadataIteratorAlloc(md, PS_LIST_HEAD, "^" MULTI_NAME "$");
         ok(iter, "iter = %x", iter);
-        skip_start(!iter, 12, "Skipping 12 tests because psMetadataIteratorAlloc failed");
-        psMetadataItem *item;
-
-        TEST_ITERATION(MULTI_NAME1, MULTI_COMMENT1, "");
-        TEST_ITERATION(MULTI_NAME2, MULTI_COMMENT2, "");
-        TEST_ITERATION(MULTI_NAME3, MULTI_COMMENT3, "");
-        TEST_ITERATION(MULTI_NAME4, MULTI_COMMENT4, "");
-
-        skip_end();
-        psFree(iter);
-        psFree(md);
-    }
+        skip_start(!iter, 20, "Skipping 20 tests because psMetadataIteratorAlloc failed");
+
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, MULTI_NAME1, MULTI_COMMENT1, MULTI_VALUE1);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, MULTI_NAME2, MULTI_COMMENT2, MULTI_VALUE2);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, MULTI_NAME3, MULTI_COMMENT3, MULTI_VALUE3);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, MULTI_NAME4, MULTI_COMMENT4, MULTI_VALUE4);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("With regular expressions, backwards");
+        psMetadata *md = mdGenerate();
+        psMetadataIterator *iter = psMetadataIteratorAlloc(md, PS_LIST_TAIL, "^" MULTI_NAME "$");
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 20, "Skipping 20 tests because psMetadataIteratorAlloc failed");
+
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, MULTI_NAME4, MULTI_COMMENT4, MULTI_VALUE4);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, MULTI_NAME3, MULTI_COMMENT3, MULTI_VALUE3);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, MULTI_NAME2, MULTI_COMMENT2, MULTI_VALUE2);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, MULTI_NAME1, MULTI_COMMENT1, MULTI_VALUE1);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("With regular expressions, jumping in halfway through (using allocator), forwards");
+        psMetadata *md = mdGenerate();
+        psMetadataIterator *iter = psMetadataIteratorAlloc(md, 2, "^" MULTI_NAME "$");
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 20, "Skipping 20 tests because psMetadataIteratorAlloc failed");
+
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, MULTI_NAME3, MULTI_COMMENT3, MULTI_VALUE3);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, MULTI_NAME4, MULTI_COMMENT4, MULTI_VALUE4);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("With regular expressions, jumping in halfway through (using allocator), backwards");
+        psMetadata *md = mdGenerate();
+        psMetadataIterator *iter = psMetadataIteratorAlloc(md, -3, "^" MULTI_NAME "$");
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 20, "Skipping 20 tests because psMetadataIteratorAlloc failed");
+
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, MULTI_NAME2, MULTI_COMMENT2, MULTI_VALUE2);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, MULTI_NAME1, MULTI_COMMENT1, MULTI_VALUE1);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("With regular expressions, jumping in halfway through (using set), forwards");
+        psMetadata *md = mdGenerate();
+        psMetadataIterator *iter = psMetadataIteratorAlloc(md, PS_LIST_HEAD, "^" MULTI_NAME "$");
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 20, "Skipping 20 tests because psMetadataIteratorAlloc failed");
+        psMetadataIteratorSet(iter, 2);
+
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, MULTI_NAME3, MULTI_COMMENT3, MULTI_VALUE3);
+        testIteration((iterFunc)psMetadataGetAndIncrement, iter, MULTI_NAME4, MULTI_COMMENT4, MULTI_VALUE4);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
+    {
+        diag("With regular expressions, jumping in halfway through (using set), backwards");
+        psMetadata *md = mdGenerate();
+        psMetadataIterator *iter = psMetadataIteratorAlloc(md, PS_LIST_HEAD, "^" MULTI_NAME "$");
+        ok(iter, "iter = %x", iter);
+        skip_start(!iter, 20, "Skipping 20 tests because psMetadataIteratorAlloc failed");
+        psMetadataIteratorSet(iter, -3);
+
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, MULTI_NAME2, MULTI_COMMENT2, MULTI_VALUE2);
+        testIteration((iterFunc)psMetadataGetAndDecrement, iter, MULTI_NAME1, MULTI_COMMENT1, MULTI_VALUE1);
+
+        skip_end();
+        psFree(iter);
+        psFree(md);
+    }
+
 
     return exit_status();
