bool PolicyCompiler_junosacl::mirrorRule::processNext()
{
    //PolicyCompiler_iosacl *iosacl_comp=dynamic_cast<PolicyCompiler_iosacl*>(compiler);
    PolicyRule *rule = getNext(); if (rule==NULL) return false;
    if (rule->getOptionsObject()->getBool("iosacl_add_mirror_rule"))
    {
        PolicyRule *r= compiler->dbcopy->createPolicyRule();
        compiler->temp_ruleset->add(r);
        r->duplicate(rule);

        r->setAction(rule->getAction());

        switch (rule->getDirection())
        {
        case PolicyRule::Inbound: r->setDirection(PolicyRule::Outbound); break;
        case PolicyRule::Outbound: r->setDirection(PolicyRule::Inbound); break;
        default: r->setDirection(PolicyRule::Both); break;
        }

	RuleElementSrc *osrc = rule->getSrc();
	RuleElementDst *odst = rule->getDst();
	RuleElementSrv *osrv = rule->getSrv();
	RuleElementItf *oitf = rule->getItf();

	RuleElementSrc *nsrc = r->getSrc();
	RuleElementDst *ndst = r->getDst();
	RuleElementSrv *nsrv = r->getSrv();
	RuleElementItf *nitf = r->getItf();

        duplicateRuleElement(osrc, ndst);
        duplicateRuleElement(odst, nsrc);
        duplicateRuleElement(oitf, nitf);

        if (!osrv->isAny())
        {
            ObjectMirror mirror;
            nsrv->clearChildren();
            for (list<FWObject*>::iterator i1=osrv->begin(); i1!=osrv->end(); ++i1) 
            {
                Service *nobj = mirror.getMirroredService(
                    Service::cast(FWReference::getObject(*i1)));
                if (nobj->getParent() == NULL)
                    compiler->persistent_objects->add(nobj, false);
                nsrv->addRef(nobj);
            }
        }

        tmp_queue.push_back(r);
    }
    tmp_queue.push_back(rule);
    return true;
}
/*
 * This rule processor is used to separate TCP service objects that
 * match tcp flags when generated config uses object-group clause
 */
bool PolicyCompiler_junosacl::splitTCPServiceWithFlags::processNext()
{
    PolicyRule *rule=getNext(); if (rule==NULL) return false;
    RuleElementSrv *srv = rule->getSrv();

    if (srv->size() > 1)
    {
        std::list<FWObject*> cl;
        for (list<FWObject*>::iterator i1=srv->begin(); i1!=srv->end(); ++i1) 
        {
            FWObject *o   = *i1;
            FWObject *obj = NULL;
            if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer();
            Service *s=Service::cast(obj);
            assert(s!=NULL);

            TCPService *tcp_srv = TCPService::cast(s);
            if (tcp_srv && (tcp_srv->inspectFlags() || tcp_srv->getEstablished()))
                cl.push_back(s);
        }

        while (!cl.empty()) 
        {
            PolicyRule  *r = compiler->dbcopy->createPolicyRule();
            compiler->temp_ruleset->add(r);
            r->duplicate(rule);

            RuleElementSrv *nsrv = r->getSrv();
            nsrv->clearChildren();
            nsrv->addRef( cl.front() );
            tmp_queue.push_back(r);

            srv->removeRef( cl.front() );
            cl.pop_front();
        }
        if (srv->size()>0) tmp_queue.push_back(rule);

    } else
        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);
    }

}