// Path: situation-model/src/main/java/br/ufes/inf/lprm/situation/model/Situation.java
// public interface Situation {
// 
//     public long getUID();
//     public SituationEvent getActivation();
//     public SituationEvent getDeactivation();
//     public void setDeactivation(SituationEvent deactivation);
//     public boolean isActive();
//     public List<? extends Participation> getParticipations();
//     public SituationType getType();
// }


import br.ufes.inf.lprm.situation.model.Situation;
import org.drools.core.base.ValueType;
import org.drools.core.base.evaluators.StartsEvaluatorDefinition;
import org.drools.core.common.DefaultFactHandle;
import org.drools.core.common.EventFactHandle;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.rule.VariableRestriction;
import org.drools.core.rule.VariableRestriction.VariableContextEntry;
import org.drools.core.rule.VariableRestriction.ObjectVariableContextEntry;
import org.drools.core.spi.FieldValue;
import org.drools.core.spi.InternalReadAccessor;
import java.lang.reflect.Field;

    private void extractParams() {
        try {
            Field startDev   = this.getClass().getSuperclass().getDeclaredField("startDev");
            startDev.setAccessible(true);
            this.startDev = startDev.getLong(this);
        } catch (Exception e) {
            throw new RuntimeException( e.getMessage() );
        }
    }

    @Override
    public boolean evaluate(InternalWorkingMemory workingMemory, InternalReadAccessor extractor, InternalFactHandle factHandle, FieldValue value) {
        throw new RuntimeException( "The 'starts' operator can only be used to compare one event to another, and never to compare to literal constraints." );
    }

    @Override
    public boolean evaluateCachedRight(InternalWorkingMemory workingMemory, VariableContextEntry context, InternalFactHandle left) {

        if ( context.rightNull ||
                context.declaration.getExtractor().isNullValue( workingMemory, left.getObject() )) {
            return false;
        }

        long leftStartTS, leftEndTS, rightStartTS, rightEndTS;

        rightStartTS = ((VariableRestriction.TemporalVariableContextEntry) context).startTS;
        rightEndTS = ((VariableRestriction.TemporalVariableContextEntry) context).endTS;

        if (left.getObject() instanceof Situation) {
// Path: situation-model/src/main/java/br/ufes/inf/lprm/situation/model/Situation.java
// public interface Situation {
// 
//     public long getUID();
//     public SituationEvent getActivation();
//     public SituationEvent getDeactivation();
//     public void setDeactivation(SituationEvent deactivation);
//     public boolean isActive();
//     public List<? extends Participation> getParticipations();
//     public SituationType getType();
// }


// Path: scene-core/src/main/java/br/ufes/inf/lprm/scene/base/evaluators/implementation/StartsEvaluator.java
import br.ufes.inf.lprm.situation.model.Situation;
import org.drools.core.base.ValueType;
import org.drools.core.base.evaluators.StartsEvaluatorDefinition;
import org.drools.core.common.DefaultFactHandle;
import org.drools.core.common.EventFactHandle;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.rule.VariableRestriction;
import org.drools.core.rule.VariableRestriction.VariableContextEntry;
import org.drools.core.rule.VariableRestriction.ObjectVariableContextEntry;
import org.drools.core.spi.FieldValue;
import org.drools.core.spi.InternalReadAccessor;
import java.lang.reflect.Field;


    private void extractParams() {
        try {
            Field startDev   = this.getClass().getSuperclass().getDeclaredField("startDev");
            startDev.setAccessible(true);
            this.startDev = startDev.getLong(this);
        } catch (Exception e) {
            throw new RuntimeException( e.getMessage() );
        }
    }

    @Override
    public boolean evaluate(InternalWorkingMemory workingMemory, InternalReadAccessor extractor, InternalFactHandle factHandle, FieldValue value) {
        throw new RuntimeException( "The 'starts' operator can only be used to compare one event to another, and never to compare to literal constraints." );
    }

    @Override
    public boolean evaluateCachedRight(InternalWorkingMemory workingMemory, VariableContextEntry context, InternalFactHandle left) {

        if ( context.rightNull ||
                context.declaration.getExtractor().isNullValue( workingMemory, left.getObject() )) {
            return false;
        }

        long leftStartTS, leftEndTS, rightStartTS, rightEndTS;

        rightStartTS = ((VariableRestriction.TemporalVariableContextEntry) context).startTS;
        rightEndTS = ((VariableRestriction.TemporalVariableContextEntry) context).endTS;

        if (left.getObject() instanceof Situation) {
            Situation sit = (Situation) left.getObject();