KviKvsObject * KviKvsObjectClass::allocateInstance(KviKvsObject * pParent,const QString &szName,KviKvsRunTimeContext * pContext,KviKvsVariantList * pParams)
{
	if(!m_allocProc)
		return 0;

	KviKvsObject * pObject = m_allocProc(this,pParent,szName);
	if(!pObject)
		return 0;

	if(!pObject->init(pContext,pParams))
	{
		// internal init failure : abort
		pObject->dieNow();
		return 0;
	}

	// copy params
	KviKvsVariantList copy;
	copy.setAutoDelete(false);

	KviKvsVariant * v = pParams->first();

	while(v)
	{
		copy.append(v);
		v = pParams->next();
	}
	KviKvsVariant ret;

	if(!pObject->callFunction(pObject,"constructor",QString(),pContext,&ret,&copy))
	{
		// ops...constructor failed (script error!)
		pObject->dieNow();
		return 0;
	}
	
	if(!ret.isEmpty())
		pContext->warning(__tr2qs_ctx("It's not allowed to return values in the constructor","kvs"));

	return pObject;
}
bool KviKvsTreeNodeSpecialCommandForeach::execute(KviKvsRunTimeContext * c)
{
    KviKvsVariantList l;
    l.setAutoDelete(true);
    if(!m_pIterationData->evaluate(c,&l))
        return false;

    KviKvsSwitchList swl;
    if(m_pSwitches)
    {
        if(!(m_pSwitches->evaluate(c,&swl)))
            return false;
    }

    bool bIncludeEmptyScalars = swl.find('a',"all") != 0;

    for(KviKvsVariant * pArg = l.first(); pArg; pArg = l.next())
    {
        switch(pArg->type())
        {
        case KviKvsVariantData::Array:
        {
            unsigned int uCnt = pArg->array()->size();
            unsigned int idx = 0;
            while(idx < uCnt)
            {
                // we evaluate this each time (as it may actually be killed at each iteration)
                // FIXME: maybe some kind of reference counting or a observer pattern might be a bit more efficient here
                //        (but might be far less efficient everywhere else...)
                KviKvsRWEvaluationResult * v = m_pIterationVariable->evaluateReadWrite(c);
                if(!v)
                    return false;
                KviKvsVariant * pOne = pArg->array()->at(idx);
                if(pOne)
                {
                    if(bIncludeEmptyScalars || (!pOne->isEmpty()))
                    {
                        v->result()->copyFrom(*pOne);
                    } else {
                        delete v; // we're done with it for this iteration
                        idx++;
                        continue;
                    }
                } else {
                    if(bIncludeEmptyScalars)
                    {
                        v->result()->setNothing();
                    } else {
                        delete v; // we're done with it for this iteration
                        idx++;
                        continue;
                    }

                }
                delete v; // we're done with it for this iteration

                if(!m_pLoop->execute(c))
                {
                    if(c->error())
                        return false;

                    // break allowed!
                    if(c->breakPending())
                    {
                        c->handleBreak();
                        return true;
                    }

                    if(c->continuePending())
                    {
                        c->handleContinue();
                        idx++;
                        continue;
                    }

                    return false; // propagate the false return value
                }

                idx++;
            }
        }
        break;
        case KviKvsVariantData::Hash:
        {
            KviKvsHashIterator it(*(pArg->hash()->dict()));
            while(KviKvsVariant * pOne = it.current())
            {
                // we evaluate this each time (as it may actually be killed at each iteration)
                // FIXME: maybe some kind of reference counting or a observer pattern might be a bit more efficient here
                //        (but might be far less efficient everywhere else...)
                KviKvsRWEvaluationResult * v = m_pIterationVariable->evaluateReadWrite(c);
                if(!v)
                    return false;

                if(bIncludeEmptyScalars || (!pOne->isEmpty()))
                {
                    v->result()->copyFrom(*pOne);
                } else {
                    delete v; // we're done with it for this iteration
                    ++it;
                    continue;
                }
                delete v; // we're done with it for this iteration

                if(!m_pLoop->execute(c))
                {
                    if(c->error())
                        return false;

                    // break allowed!
                    if(c->breakPending())
                    {
                        c->handleBreak();
                        return true;
                    }

                    if(c->continuePending())
                    {
                        c->handleContinue();
                        ++it;
                        continue;
                    }

                    return false; // propagate the false return value
                }

                ++it;
            }
        }
        break;
        default:
            if(bIncludeEmptyScalars || (!pArg->isEqualToNothing()))
            {
                // we evaluate this each time (as it may actually be killed at each iteration)
                // FIXME: maybe some kind of reference counting or a observer pattern might be a bit more efficient here
                //        (but might be far less efficient everywhere else...)
                KviKvsRWEvaluationResult * v = m_pIterationVariable->evaluateReadWrite(c);
                if(!v)
                    return false;
                v->result()->copyFrom(*pArg);
                delete v; // we're done with it for this iteration

                if(!m_pLoop->execute(c))
                {
                    if(c->error())
                        return false;

                    // break allowed!
                    if(c->breakPending())
                    {
                        c->handleBreak();
                        return true;
                    }

                    if(c->continuePending())
                    {
                        c->handleContinue();
                        continue;
                    }

                    return false; // propagate the false return value
                }
            }
            break;
        }
    }

    return true;
}