diff --git a/src/passbook.c b/src/passbook.c
index d42c1e6d67e6e8913f8f5017933ba2b6434faea5..6c2224be00a5ecc5470fd3470bff7ad94a7af81c 100644
--- a/src/passbook.c
+++ b/src/passbook.c
@@ -5,11 +5,6 @@
 
 #include "debug.h"
 
-/**
-  The idea is to eventually implement state dumping by writing a series
-  of commands to a file <file> that we can then reload next time by doing
-  cat <file> - | ./passbook
-**/
 
 const char INSTRUCTION_PUT[] = "put";
 
@@ -19,6 +14,8 @@ const char INSTRUCTION_GET[] = "get";
 
 const char INSTRUCTION_SAVE[] = "save";
 
+const char INSTRUCTION_LIST[] = "list";
+
 typedef struct {
   char * username;
   char * password;
@@ -196,35 +193,55 @@ node_t * map = NULL;
    is used to implement stacks/queues of nodes so we can implement various
    tree traversal algorithms without using recursion (to avoid stack overflow
    for very large trees). */
-typedef struct nodeptr_list {
+typedef struct nodeptr_list_elem {
   const node_t *p;
-  struct nodeptr_list *next;
-  struct nodeptr_list *prev;
+  struct nodeptr_list_elem *next;
+  struct nodeptr_list_elem *prev;
+} nodeptr_list_elem_t;
+
+typedef struct nodeptr_list {
+  nodeptr_list_elem_t *head;
+  nodeptr_list_elem_t *last;
 } nodeptr_list_t;
 
 
-nodeptr_list_t * list_push(nodeptr_list_t *lst, const node_t *p){
-  nodeptr_list_t *n = malloc(sizeof(nodeptr_list_t));
+nodeptr_list_t list_push(nodeptr_list_t lst, const node_t *p){
+  nodeptr_list_elem_t *n = malloc(sizeof(nodeptr_list_elem_t));
   assert(n != NULL && "push: malloc failed");
   n->p = p;
-  n->next = lst;
-  if (lst != NULL){
-    lst->prev = n;
+  n->next = lst.head;
+  n->prev = NULL;  
+  if (lst.head != NULL){
+    assert(lst.last != NULL);
+    lst.head->prev = n;
+  }else{
+    assert(lst.last == NULL);
+    lst.last = n;
   }
-  n->prev = NULL;
-  return n;
+  lst.head = n;
+  
+  return lst;
 }
 
 /* when out is non-NULL we place a pointer to the first node into it */
-nodeptr_list_t * list_pop(nodeptr_list_t *lst, const node_t **out){
-  if (lst != NULL){
+nodeptr_list_t list_pop(nodeptr_list_t lst, const node_t **out){
+  if (lst.head != NULL){
+    assert(lst.last != NULL);
     if (out != NULL){
-      *out = lst->p;
+      *out = lst.head->p;
+    }
+    if (lst.last == lst.head){
+      free(lst.head);
+      lst.head = NULL;
+      lst.last = NULL;
+    }else{
+      nodeptr_list_elem_t *ret = lst.head->next;
+      free(lst.head);
+      lst.head = ret;
     }
-    nodeptr_list_t *ret = lst->next;
-    free(lst);
-    return ret;
+    return lst;
   }else{
+    assert(lst.last == NULL);
     if (out != NULL){
       *out = (const node_t *)NULL;
     }
@@ -232,15 +249,43 @@ nodeptr_list_t * list_pop(nodeptr_list_t *lst, const node_t **out){
   }
 }
 
-void list_destroy(nodeptr_list_t *lst){
-  while (lst != NULL){
+nodeptr_list_t list_dequeue(nodeptr_list_t lst, const node_t **out){
+  if (lst.last != NULL){
+    assert(lst.head != NULL);
+    if (out != NULL){
+      *out = lst.last->p;
+    }
+
+    if (lst.last == lst.head){
+      free(lst.head);
+      lst.head = NULL;
+      lst.last = NULL;
+    }else{
+      nodeptr_list_elem_t *ret = lst.last->prev;
+      free(lst.last);
+      lst.last = ret;
+    }
+    return lst;
+  }else{
+    assert(lst.head == NULL);
+    if (out != NULL){
+      *out = (const node_t *)NULL;
+    }
+    return lst;
+  }
+}
+
+
+nodeptr_list_t list_destroy(nodeptr_list_t lst){
+  while (lst.head != NULL){
     lst = list_pop(lst,NULL);
   }
+  return lst;
 }
 
-void list_print(nodeptr_list_t *lst){
+void list_print(nodeptr_list_t lst){
   printf("\nBegin list print:\n");
-  while (lst != NULL){
+  while (lst.head != NULL){
     const node_t *p;
     lst = list_pop(lst,&p);
     node_print(p);
@@ -248,13 +293,24 @@ void list_print(nodeptr_list_t *lst){
   printf("End list print.\n\n");
 }
 
+void list_print_rev(nodeptr_list_t lst){
+  printf("\nBegin list reverse print:\n");
+  while (lst.last != NULL){
+    const node_t *p;
+    lst = list_dequeue(lst,&p);
+    node_print(p);
+  }
+  printf("End list reverse print.\n\n");
+}
+
 
-void print_all(const node_t *p){
-  nodeptr_list_t *lst = NULL;
+/* in order traversal to print out nodes in sorted order */
+void print_inorder(const node_t *p){
+  nodeptr_list_t lst = {.head = NULL, .last = NULL};
   if (p != NULL){
     lst = list_push(lst,p);
 
-    while(lst != NULL){
+    while(lst.head != NULL){
       // keep recursing left until we can go no further
       while (p->left != NULL){
         lst = list_push(lst,p->left);
@@ -277,6 +333,46 @@ void print_all(const node_t *p){
   }
 }
 
+void node_save(const node_t *p, FILE *f){
+  fprintf(f,"%s",INSTRUCTION_PUT);
+  fprintf(f," ");
+  fprintf(f,"%s",p->url);
+  fprintf(f," ");  
+  fprintf(f,"%s",p->cred.username);  
+  fprintf(f," ");  
+  fprintf(f,"%s",p->cred.password);
+  fprintf(f,"\n");
+}
+  
+/* level order (i.e. breadth-first) traversal to print nodes out in the
+   order that they would need to be put back in to an empty tree to ensure
+   that the resulting tree has the same structure as the original one that
+   was printed out. Returns 0 on success; nonzero on failure */
+int save_levelorder(const node_t *p, const char * filename){
+  FILE *f = fopen(filename,"w");
+  if (f == NULL){
+    debug_printf("Couldn't open file %s for writing.\n",filename);
+    return -1;
+  }
+  nodeptr_list_t lst = {.head = NULL, .last = NULL};
+  if (p != NULL){
+    lst = list_push(lst,p);
+
+    while(lst.last != NULL){
+      lst = list_dequeue(lst,&p);
+      node_save(p,f);
+      if (p->left != NULL){
+        lst = list_push(lst,p->left);
+      }
+      if (p->right != NULL){
+        lst = list_push(lst,p->right);
+      }
+    }
+  }
+  fclose(f);
+  return 0;
+}
+
 /* returns 0 on successful execution of the instruction in inst */
 static int execute(void){
   char * toks[4]; /* these are pointers to start of different tokens */
@@ -288,10 +384,6 @@ static int execute(void){
     return 0;
   }
     
-  if (numToks < 2){
-    return -1;
-  }
-
   if (strcmp(toks[0],INSTRUCTION_GET) == 0){
     if (numToks != 2){
       return -1;
@@ -325,8 +417,17 @@ static int execute(void){
       return -1;
     }
     debug_printf("Saving to: %s\n",toks[1]);
-    print_all(map);
-    
+    if (save_levelorder(map,toks[1]) != 0){
+      return -1;
+    }
+    debug_printf("---\n");
+
+  } else if (strcmp(toks[0],INSTRUCTION_LIST) == 0){
+    if (numToks != 1){
+      return -1;
+    }
+    print_inorder(map);
+
   }else{
     debug_printf("Unrecognised instruction\n");
     return -1;