public boolean evaluate(
        InternalWorkingMemory workingMemory,
        final InternalReadAccessor extractor1,
        final Object object1,
        final InternalReadAccessor extractor2,
        final Object object2) {
      if (extractor1.isNullValue(workingMemory, object1)) {
        return false;
      }

      long obj1StartTS = -1;
      long obj1EndTS = -1;
      long obj2StartTS = -1;
      long obj2EndTS = -1;

      DefaultFactHandle obj1FH = (DefaultFactHandle) object1;

      if (obj1FH instanceof EventFactHandle) {
        obj1StartTS = ((EventFactHandle) obj1FH).getStartTimestamp();
        obj1EndTS = ((EventFactHandle) obj1FH).getEndTimestamp();
      } else {
        Object obj1Fact = workingMemory.getObject(obj1FH);
        if (obj1Fact instanceof SituationType) {
          obj1StartTS = ((SituationType) obj1Fact).getActivation().getTimestamp();
          if (!((SituationType) obj1Fact).isActive()) {
            obj1EndTS = ((SituationType) obj1Fact).getDeactivation().getTimestamp();
          }
        }
      }

      DefaultFactHandle obj2FH = (DefaultFactHandle) object2;

      if (obj2FH instanceof EventFactHandle) {
        obj2StartTS = ((EventFactHandle) obj2FH).getStartTimestamp();
        obj2EndTS = ((EventFactHandle) obj2FH).getEndTimestamp();
      } else {
        Object obj2Fact = workingMemory.getObject(obj2FH);
        if (obj2Fact instanceof SituationType) {
          obj2StartTS = ((SituationType) obj2Fact).getActivation().getTimestamp();
          // includes is not applicable when situationB is not finished
          if (!((SituationType) obj2Fact).isActive()) {
            obj2EndTS = ((SituationType) obj2Fact).getDeactivation().getTimestamp();
          } else return false;
        }
      }

      long distStart = obj2StartTS - obj1StartTS;
      if (obj1EndTS == (-1)) {
        return this.getOperator().isNegated()
            ^ (distStart >= this.startMinDev && distStart <= this.startMaxDev);
      } else {
        long distEnd = obj1EndTS - obj2EndTS;
        return this.getOperator().isNegated()
            ^ (distStart >= this.startMinDev
                && distStart <= this.startMaxDev
                && distEnd >= this.endMinDev
                && distEnd <= this.endMaxDev);
      }
    }
    public boolean evaluate(
        InternalWorkingMemory workingMemory,
        final InternalReadAccessor extractor1,
        final InternalFactHandle handle1,
        final InternalReadAccessor extractor2,
        final InternalFactHandle handle2) {
      if (extractor1.isNullValue(workingMemory, handle1.getObject())
          || extractor2.isNullValue(workingMemory, handle2.getObject())) {
        return false;
      }

      long distStart =
          ((EventFactHandle) handle1).getStartTimestamp()
              - ((EventFactHandle) handle2).getStartTimestamp();
      long distEnd =
          Math.abs(
              ((EventFactHandle) handle2).getEndTimestamp()
                  - ((EventFactHandle) handle1).getEndTimestamp());
      return this.getOperator().isNegated() ^ (distStart > 0 && distEnd <= this.endDev);
    }