// Iterator support - for in, for each
	Atom VectorBaseObject::nextName(int index)
	{
		AvmAssert(index > 0);
		if (((uint32)index) <= m_length)
		{
			AvmCore *core = this->core();
			return core->intToAtom(index-1);
		}
		else
		{
			return nullStringAtom;
		}
	}
	// Iterator support - for in, for each
	Atom ArrayObject::nextName(int index)
	{
		AvmAssert(index > 0);

		int denseLength = (int)getDenseLength();
		if (index <= denseLength)
		{
			AvmCore *core = this->core();
 			return core->intToAtom(index-1);
		}
		else
		{
			return ScriptObject::nextName (index - denseLength);
		}
	}
	Atom ArrayObject::getAtomProperty(Atom name) const
	{
		if (traits()->needsHashtable())
		{
			AvmCore *core = this->core();
			if (hasDense())
			{
				uint32 index;
				if (AvmCore::getIndexFromAtom(name, &index))
				{
					// if we get here, we have a valid integer index.
					if ((index < getDenseLength()))
						return m_denseArr.getAtFast(index);
				}
			}

			if (name == core->klength->atom())
				return core->intToAtom (getLength());
		}

		return ScriptObject::getAtomProperty(name);
	}
    ArrayObject* RegExpObject::_exec(Stringp subject, 
									UTF8String *utf8Subject,
									int startIndex,
									int& matchIndex,
									int& matchLen)
	{
		AvmAssert(subject != NULL);
		AvmAssert(utf8Subject != NULL);
		
		int ovector[OVECTOR_SIZE];
		int results;
		int subjectLength = utf8Subject->length();

		if( startIndex < 0 ||
			startIndex > subjectLength ||
			(results = pcre_exec((pcre*)m_pcreInst,
								NULL,
								utf8Subject->c_str(),
								subjectLength,
								startIndex,
								PCRE_NO_UTF8_CHECK,
								ovector,
								OVECTOR_SIZE)) < 0)
		{
			matchIndex = 0;
			matchLen = 0;
			return NULL;
		}

		AvmCore *core = this->core();
		ArrayObject *a = toplevel()->arrayClass->newArray(results);

		a->setAtomProperty(toplevel()->regexpClass()->kindex,
			   core->intToAtom(Utf8ToUtf16Index(subject, utf8Subject, ovector[0])));
		a->setAtomProperty(toplevel()->regexpClass()->kinput,
			   subject->atom());
		a->setLength(results);

		// set array slots
		for (int i=0; i<results; i++) {
			if (ovector[i*2] > -1) {
				int length = ovector[i*2 + 1] - ovector[i*2];
				Atom match = stringFromUTF8(utf8Subject->c_str()+ovector[i*2], length);
				a->setUintProperty(i, match);
			} else {
				a->setUintProperty(i, undefinedAtom);
			}
		}

		// handle named groups
		if (m_hasNamedGroups)
		{
			int entrySize;
			pcre_fullinfo((pcre*)m_pcreInst, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrySize);
	 
			int nameCount;
			pcre_fullinfo((pcre*)m_pcreInst, NULL, PCRE_INFO_NAMECOUNT, &nameCount);
	 
			// this space is freed when (pcre*)m_pcreInst is freed 
			char *nameTable;
			pcre_fullinfo((pcre*)m_pcreInst, NULL, PCRE_INFO_NAMETABLE, &nameTable);
	 
			/* nameTable is a series of fixed length entries (entrySize) 
			   the first two bytes are the index into the ovector and the result
			   is a null terminated string (the subgroup name) */
			for (int i = 0; i < nameCount; i++)
			{
				int nameIndex, length;
				nameIndex = (nameTable[0] << 8) + nameTable[1];
				length = ovector[nameIndex * 2 + 1] - ovector[ nameIndex * 2 ];

				Atom name = stringFromUTF8((char*)(nameTable+2), (uint32)strlen(nameTable+2));
				name = core->internString(name)->atom();

				Atom value = stringFromUTF8(utf8Subject->c_str()+ovector[nameIndex*2], length);

				a->setAtomProperty(name, value);

				nameTable += entrySize;
			}
		}
		
		matchIndex = ovector[0];
		matchLen = ovector[1]-ovector[0];

		return a;
	}