bool PolicyCompiler_pf::addLoopbackForRedirect::processNext()
{
    PolicyRule *rule = getNext(); if (rule==NULL) return false;
    PolicyCompiler_pf *pf_comp = dynamic_cast<PolicyCompiler_pf*>(compiler);

    RuleElementDst *dst = rule->getDst();
    RuleElementSrv *srv = rule->getSrv();

    if (pf_comp->redirect_rules_info==NULL)
        compiler->abort(
            rule, 
            "addLoopbackForRedirect needs a valid pointer to "
            "the list<NATCompiler_pf::redirectRuleInfo> object");

    tmp_queue.push_back(rule);

    if (pf_comp->redirect_rules_info->empty()) return true;

    for (FWObject::iterator i=srv->begin(); i!=srv->end(); i++) 
    {
	FWObject *o1 = FWReference::getObject(*i);
	Service *s = Service::cast( o1 );
	assert(s);

        for (FWObject::iterator j=dst->begin(); j!=dst->end(); j++) 
        {
            FWObject *o2 = FWReference::getObject(*j);
            if (o2->getName() == "self" && DNSName::isA(o2)) continue;

            Address *a = Address::cast( o2 );
            assert(a);

            list<NATCompiler_pf::redirectRuleInfo>::const_iterator k;
            for (k=pf_comp->redirect_rules_info->begin();
                 k!=pf_comp->redirect_rules_info->end(); ++k)
            {
                Address *old_tdst_obj = Address::cast(
                    compiler->dbcopy->findInIndex(k->old_tdst));
                Service *tsrv_obj = Service::cast(
                    compiler->dbcopy->findInIndex(k->tsrv));

                if ( *a == *(old_tdst_obj) &&  *s == *(tsrv_obj) )
                {
// insert address used for redirection in the NAT rule.
                    FWObject *new_tdst_obj = compiler->dbcopy->findInIndex(k->new_tdst);
                    dst->addRef(new_tdst_obj);
                    return true;
                }
            }
        }
    }

    return true;
}
bool PolicyCompiler_pf::splitIfFirewallInDst::processNext()
{
    PolicyRule *rule = getNext(); if (rule==NULL) return false;

    PolicyRule *r;
    RuleElementDst *dst = rule->getDst();    assert(dst);

    if (dst->size()==1 || dst->getNeg())
    {
	tmp_queue.push_back(rule);
	return true;
    }

    FWObject *fw_in_dst = NULL;
    vector<FWObject*> cl;
    for (FWObject::iterator i1=dst->begin(); i1!=dst->end(); ++i1)
    {
	FWObject *obj = FWReference::getObject(*i1);
	if (obj==NULL)
            compiler->abort(rule, "Broken Dst");

	if (obj->getId()==compiler->getFwId())
        {
	    fw_in_dst = obj;

	    RuleElementDst *ndst;

	    r = compiler->dbcopy->createPolicyRule();
	    compiler->temp_ruleset->add(r);
	    r->duplicate(rule);
	    ndst = r->getDst();
	    ndst->clearChildren();
	    ndst->setAnyElement();
	    ndst->addRef( compiler->fw );
	    tmp_queue.push_back(r);
	}
    }
    if (fw_in_dst!=NULL) dst->removeRef( fw_in_dst );

    tmp_queue.push_back(rule);
    return true;
}
void PolicyCompiler_pix::replaceTranslatedAddresses::action(
    PolicyRule* policy_rule,
    NATRule* nat_rule, Address *src, Address*, Service *srv)
{

//    FWObject *rule_iface = compiler->dbcopy->findInIndex(
//        policy_rule->getInterfaceId());

    RuleElementItf *intf_re = policy_rule->getItf();
    FWObject *rule_iface = FWObjectReference::getObject(intf_re->front());

    RuleElement *re = nat_rule->getOSrc();

    FWObject *o = FWReference::getObject(re->front());
#ifndef NDEBUG
    Address  *osrc = Address::cast(o); assert(osrc);
#endif

    re = nat_rule->getODst();
    o = FWReference::getObject(re->front());
    Address  *odst = Address::cast(o); assert(odst);

    re = nat_rule->getOSrv();
    o = FWReference::getObject(re->front());
    Service  *osrv = Service::cast(o); assert(osrv);

#ifndef NDEBUG
    re = nat_rule->getTSrc();
    o = FWReference::getObject(re->front());
    Address  *tsrc = Address::cast(o); assert(tsrc);

    re = nat_rule->getTDst();
    o = FWReference::getObject(re->front());
    Address  *tdst = Address::cast(o); assert(tdst);

    re = nat_rule->getTSrv();
    o = FWReference::getObject(re->front());
    Service  *tsrv = Service::cast(o); assert(tsrv);
#endif

    FWObject *p = odst->getParent();

    if (odst->getId() == rule_iface->getId() ||
        p->getId() == rule_iface->getId())
    {

        PolicyRule  *r = compiler->dbcopy->createPolicyRule();
        compiler->temp_ruleset->add(r);
        r->duplicate(policy_rule);

        RuleElementSrc *nsrc = r->getSrc();
        nsrc->clearChildren();
        nsrc->addRef( src );

        RuleElementDst *ndst = r->getDst();
        ndst->clearChildren();
        ndst->addRef( odst );

        RuleElementSrv *nsrv = r->getSrv();
        nsrv->clearChildren();

        if (osrv->isAny())
            nsrv->addRef( srv );
        else
            nsrv->addRef( osrv );

        transformed_rules.push_back(r);
    }

}