Index: cpp/frams/vm/classes/collectionobj.cpp
===================================================================
--- cpp/frams/vm/classes/collectionobj.cpp	(revision 863)
+++ cpp/frams/vm/classes/collectionobj.cpp	(revision 868)
@@ -50,5 +50,5 @@
 ParamEntry dictionary_paramtab[] =
 {
-	{ "Dictionary", 1, 12, "Dictionary", "Dictionary associates stored values with string keys "
+	{ "Dictionary", 1, 14, "Dictionary", "Dictionary associates stored values with string keys "
 	"(\"key\" is the first argument in get/set/remove functions). Integer key can be "
 	"used to enumerate all elements (note that while iterating, the elements are returned in no particular order).\n"
@@ -65,5 +65,7 @@
 	"\td={ \"name\":\"John\", \"age\":44 };\n"
 	"Iterating:\n"
-	"\tfor(var i=0;i<d.size;i++) Simulator.print(d.getKey(i)+\" is \"+d.get(i));",
+	"\tfor(var v in d) Simulator.print(v); //values\n"
+	"\tfor(var k in d.keys) Simulator.print(k+\" is \"+d[k]); //keys\n"
+	"\tfor(var i=0;i<d.size;i++) Simulator.print(d.getKey(i)+\" is \"+d.get(i)); //by index",
 	},
 	{ "clear", 0, PARAM_NOSTATIC, "Clear data", "p()", PROCEDURE(p_clear), },
@@ -84,4 +86,6 @@
 	{ "clone", 0, PARAM_NOSTATIC, "Create a clone", "p oDictionary()", PROCEDURE(p_clone), "The resulting clone is a shallow copy (contains the same object references as the original). A deep copy can be obtained through serialization: String.deserialize(String.serialize(object));" },
 	{ "assign", 0, PARAM_NOSTATIC, "Assign from another object", "p(x)", PROCEDURE(p_assign), "Replaces current dictionary with dictionary contents from another object." },
+	{ "iterator", 0, PARAM_NOSTATIC | PARAM_READONLY, "Iterator", "o", GETONLY(iterator), },
+	{ "keys", 0, PARAM_NOSTATIC | PARAM_READONLY, "Keys", "o", GETONLY(keys), "Iterate over this object to get all keys: for(k in dict.keys) ..." },
 
 	{ 0, 0, 0, },
@@ -539,4 +543,14 @@
 }
 
+void DictionaryObject::get_iterator(ExtValue* ret)
+{
+	ret->setObject(DictionaryIterator::makeFrom(this));
+}
+
+void DictionaryObject::get_keys(ExtValue* ret)
+{
+	ret->setObject(DictionaryIterator::makeFrom(this));
+}
+
 ////////////////
 
@@ -584,4 +598,74 @@
 }
 
+/////////////////
+
+#define FIELDSTRUCT DictionaryIterator
+ParamEntry dictionaryiterator_paramtab[] =
+{
+	{ "DictionaryIterator", 1, 3, "DictionaryIterator", "DictionaryIterator" },
+	{ "next", 0, PARAM_READONLY | PARAM_NOSTATIC, "next", "d 0 1", GETONLY(next), },
+	{ "value", 0, PARAM_READONLY | PARAM_NOSTATIC, "value", "x", GETONLY(value), },
+	{ "iterator", 0, PARAM_READONLY | PARAM_NOSTATIC, "keys iterator", "x", GETONLY(iterator), },
+	{ 0, 0, 0, },
+};
+#undef FIELDSTRUCT
+
+DictionaryIterator::DictionaryIterator(DictionaryObject* d, bool _keys)
+	:it(d->hash)
+{
+	dic = d;
+	dic->incref();
+	initial = true;
+	keys = _keys;
+}
+
+ExtObject DictionaryIterator::makeFrom(DictionaryObject *d, bool _keys)
+{
+	static Param par(dictionaryiterator_paramtab);
+	return ExtObject(&par, new DictionaryIterator(d, _keys));
+}
+
+DictionaryIterator::~DictionaryIterator()
+{
+	dic->decref();
+}
+
+void DictionaryIterator::get_next(ExtValue* ret)
+{
+	if (initial)
+		initial = false;
+	else
+		it++;
+	ret->setInt(it.isValid());
+}
+
+void DictionaryIterator::get_value(ExtValue* ret)
+{
+	if ((!initial) && it.isValid())
+	{
+		if (keys)
+		{
+			ret->setString(it->key);
+		}
+		else
+		{
+			ExtValue *v = (ExtValue*)it->value;
+			if (v == NULL)
+				ret->setEmpty();
+			else
+				*ret = *v;
+		}
+	}
+	else
+		ret->setEmpty();
+}
+
+void DictionaryIterator::get_iterator(ExtValue* ret)
+{
+	ret->setObject(makeFrom(dic, true));
+}
+
+//////////////
+
 // not actually needed for deserialization (vector and dict are special cases) but findDeserializableClass can be also used in other contexts
 REGISTER_DESERIALIZABLE(VectorObject)
Index: cpp/frams/vm/classes/collectionobj.h
===================================================================
--- cpp/frams/vm/classes/collectionobj.h	(revision 863)
+++ cpp/frams/vm/classes/collectionobj.h	(revision 868)
@@ -79,4 +79,6 @@
 	PARAMPROCDEF(p_clone);
 	PARAMPROCDEF(p_assign);
+	PARAMGETDEF(iterator);
+	PARAMGETDEF(keys);
 #undef STATRICKCLASS
 	ExtValue get(SString key);
@@ -107,3 +109,19 @@
 };
 
+class DictionaryIterator : public DestrBase
+{
+public:
+	DictionaryObject *dic;
+	HashEntryIterator it;
+	bool initial, keys;
+	DictionaryIterator(DictionaryObject* d, bool _keys);
+	~DictionaryIterator();
+#define STATRICKCLASS DictionaryIterator
+	PARAMGETDEF(next);
+	PARAMGETDEF(value);
+	PARAMGETDEF(iterator);
+#undef STATRICKCLASS
+	static ExtObject makeFrom(DictionaryObject *v, bool _keys = false);
+};
+
 #endif
