diff --git a/src/emap/hashtable.c b/src/emap/hashtable.c
index 6645a0dbd4ff88c5d16768cff3474d5073355101..1fead602d523d4936794f35183da36d505f29d20 100644
--- a/src/emap/hashtable.c
+++ b/src/emap/hashtable.c
@@ -134,6 +134,32 @@ bool htreg_iterator_exists(int64 id)
     return i64db_exists(htreg->iterators, id);
 }
 
+const char* htreg_iterator_firstkey(int64 id)
+{
+    struct DBIterator *it = i64db_get(htreg->iterators, id);
+    if (it)
+    {
+        union DBKey key;
+        it->first(it, &key);
+        if (dbi_exists(it))
+            return key.str;
+    }
+    return NULL;
+}
+
+const char* htreg_iterator_lastkey(int64 id)
+{
+    struct DBIterator *it = i64db_get(htreg->iterators, id);
+    if (it)
+    {
+        union DBKey key;
+        it->last(it, &key);
+        if (dbi_exists(it))
+            return key.str;
+    }
+    return NULL;
+}
+
 const char* htreg_iterator_nextkey(int64 id)
 {
     struct DBIterator *it = i64db_get(htreg->iterators, id);
@@ -147,6 +173,19 @@ const char* htreg_iterator_nextkey(int64 id)
     return NULL;
 }
 
+const char* htreg_iterator_prevkey(int64 id)
+{
+    struct DBIterator *it = i64db_get(htreg->iterators, id);
+    if (it)
+    {
+        union DBKey key;
+        it->prev(it, &key);
+        if (dbi_exists(it))
+            return key.str;
+    }
+    return NULL;
+}
+
 /**
  * Initializer.
  */
@@ -212,5 +251,8 @@ void htreg_defaults(void)
     htreg->destroy_iterator = htreg_destroy_iterator;
     htreg->iterator_check = htreg_iterator_check;
     htreg->iterator_exists = htreg_iterator_exists;
+    htreg->iterator_firstkey = htreg_iterator_firstkey;
+    htreg->iterator_lastkey = htreg_iterator_lastkey;
     htreg->iterator_nextkey = htreg_iterator_nextkey;
+    htreg->iterator_prevkey = htreg_iterator_prevkey;
 }
diff --git a/src/emap/hashtable.h b/src/emap/hashtable.h
index 44712cdbe35ccf749cd68ddbaf34a8f8442de108..403304eca046e9fd4ec7c036e8fc5022a17b06a4 100644
--- a/src/emap/hashtable.h
+++ b/src/emap/hashtable.h
@@ -31,7 +31,10 @@ struct htreg_interface
     bool (*destroy_iterator) (int64 id);
     bool (*iterator_check) (int64 id);
     bool (*iterator_exists) (int64 id);
+    const char* (*iterator_firstkey) (int64 id);
+    const char* (*iterator_lastkey) (int64 id);
     const char* (*iterator_nextkey) (int64 id);
+    const char* (*iterator_prevkey) (int64 id);
 };
 
 void htreg_defaults(void);
diff --git a/src/emap/init.c b/src/emap/init.c
index fefbc6cd01c6431b35466cc934fc92403ae369fc..9063735a89f7b70eb213f55e9d75a33bab7cc58b 100644
--- a/src/emap/init.c
+++ b/src/emap/init.c
@@ -183,7 +183,10 @@ HPExport void plugin_init (void)
     addScriptCommand("htsize", "i", htSize);
     addScriptCommand("htexists", "i", htExists);
     addScriptCommand("htiterator", "i", htIterator);
+    addScriptCommand("htifirstkey", "i", htiFirstKey);
+    addScriptCommand("htilastkey", "i", htiLastKey);
     addScriptCommand("htinextkey", "i", htiNextKey);
+    addScriptCommand("htiprevkey", "i", htiPrevKey);
     addScriptCommand("hticheck", "i", htiCheck);
     addScriptCommand("htidelete", "i", htiDelete);
     addScriptCommand("setfakecells", "iii??", setFakeCells);
diff --git a/src/emap/script_buildins.c b/src/emap/script_buildins.c
index 703307abad37dd75e5600d91f339cd6d1207a747..78fb940482031c372d4255b3f5507db3d3830dc1 100644
--- a/src/emap/script_buildins.c
+++ b/src/emap/script_buildins.c
@@ -1991,6 +1991,32 @@ BUILDIN(htIterator)
         return false; \
     }
 
+BUILDIN(htiFirstKey)
+{
+    int64 id = script_getnum(st, 2);
+    checkHtIteratorExists(id);
+
+    const char * key = htreg->iterator_firstkey(id);
+    if (key)
+        script_pushstrcopy(st, key);
+    else
+        script_pushstrcopy(st, "");
+    return true;
+}
+
+BUILDIN(htiLastKey)
+{
+    int64 id = script_getnum(st, 2);
+    checkHtIteratorExists(id);
+
+    const char * key = htreg->iterator_lastkey(id);
+    if (key)
+        script_pushstrcopy(st, key);
+    else
+        script_pushstrcopy(st, "");
+    return true;
+}
+
 BUILDIN(htiNextKey)
 {
     int64 id = script_getnum(st, 2);
@@ -2004,6 +2030,19 @@ BUILDIN(htiNextKey)
     return true;
 }
 
+BUILDIN(htiPrevKey)
+{
+    int64 id = script_getnum(st, 2);
+    checkHtIteratorExists(id);
+
+    const char * key = htreg->iterator_prevkey(id);
+    if (key)
+        script_pushstrcopy(st, key);
+    else
+        script_pushstrcopy(st, "");
+    return true;
+}
+
 BUILDIN(htiCheck)
 {
     int64 id = script_getnum(st, 2);
diff --git a/src/emap/script_buildins.h b/src/emap/script_buildins.h
index 2066432fe802b92fecde8d6720a9acf83e08b658..a72a035fec7a09ae900d9054a4ac56f1b02f2aed 100644
--- a/src/emap/script_buildins.h
+++ b/src/emap/script_buildins.h
@@ -82,7 +82,10 @@ BUILDIN(htDelete);
 BUILDIN(htSize);
 BUILDIN(htExists);
 BUILDIN(htIterator);
+BUILDIN(htiFirstKey);
+BUILDIN(htiLastKey);
 BUILDIN(htiNextKey);
+BUILDIN(htiPrevKey);
 BUILDIN(htiCheck);
 BUILDIN(htiDelete);
 BUILDIN(setFakeCells);