/**
   * Test add 0 obligations with no time based trigger on an existing Pii The Obligation Handler
   * should call 0 times persistObject on ObligationTriggerDao, no interaction on Time Based
   * Triggers Handler
   */
  @Test
  public void testAddObligationsEmptyObligationSet() {
    final ObligationsSet obligationSet = new ObligationsSet();
    obligationSet.setObligation(new ArrayList<Obligation>());

    obligationHandler.addObligations(obligationSet, pii);

    verifyZeroInteractions(otDao);
    verifyZeroInteractions(timeBasedTriggerHandler);
  }
  /**
   * Test add n obligations with no time based trigger on an existing Pii The Obligation Handler
   * should call n times persistObject on ObligationTriggerDao, no interaction on Time Based
   * Triggers Handler
   */
  @Test
  public void testAddObligationsNoTimeBasedTriggers() {
    final ObligationsSet obligationSet = new ObligationsSet();
    obligationSet.setObligation(new ArrayList<Obligation>());
    obligationSet.getObligation().add(createSimpleObligationWithSimpleTrigger());
    obligationSet.getObligation().add(createSimpleObligationWithSimpleTrigger());
    obligationSet.getObligation().add(createSimpleObligationWithSimpleTrigger());

    obligationHandler.addObligations(obligationSet, pii);

    verify(otDao, times(3)).persistObject(argThat(new IsSameObligationTrigger(obligationSet)));
    verifyZeroInteractions(timeBasedTriggerHandler);
  }
  /**
   * Test add n obligations with m time based trigger on an existing Pii The Obligation Handler
   * should call n times persistObject on ObligationTriggerDao, no interaction on Time Based
   * Triggers Handler
   */
  @Test
  public void testAddObligationsTimeBasedTriggers() {
    final ObligationsSet obligationSet = new ObligationsSet();
    obligationSet.setObligation(new ArrayList<Obligation>());
    obligationSet.getObligation().add(createSimpleObligationWithSimpleTrigger());
    obligationSet.getObligation().add(createSimpleObligationWithSimpleTrigger());
    obligationSet.getObligation().add(createSimpleObligationWithSimpleTrigger());

    final Obligation obligationWithTriggerAtTime = createSimpleObligationWithTriggerAtTime();
    final Obligation obligationWithTriggerPeriodic = createSimpleObligationWithTriggerPeriodic();

    obligationSet.getObligation().add(obligationWithTriggerAtTime);
    obligationSet.getObligation().add(obligationWithTriggerPeriodic);

    class TimeBasedTriggerMatcher extends ArgumentMatcher<Trigger> {
      public boolean matches(Object obj) {
        Trigger trigger = (Trigger) obj;

        return trigger.equals(
                obligationWithTriggerAtTime.getTriggersSet().getTrigger().get(0).getValue())
            || trigger.equals(
                obligationWithTriggerPeriodic.getTriggersSet().getTrigger().get(0).getValue());
      }
    }

    class ActionTimeBasedTriggerMatcher extends ArgumentMatcher<Action> {
      public boolean matches(Object obj) {
        Action action = (Action) obj;

        return action.equals(obligationWithTriggerAtTime.getActionValue())
            || action.equals(obligationWithTriggerPeriodic.getActionValue());
      }
    }

    obligationHandler.addObligations(obligationSet, pii);

    verify(otDao, times(5)).persistObject(argThat(new IsSameObligationTrigger(obligationSet)));
    verify(timeBasedTriggerHandler, times(2))
        .handle(
            argThat(new TimeBasedTriggerMatcher()),
            argThat(new ActionTimeBasedTriggerMatcher()),
            eq(pii));
  }
    public boolean matches(Object obj) {
      ObligationTrigger ot = (ObligationTrigger) obj;

      for (Obligation ob : obligationSet.getObligation()) {
        String actualTriggerName = ot.getTriggerName();
        String expectedTriggerName = ob.getTriggersSet().getTrigger().get(0).getName().toString();

        Trigger actualTrigger = ot.getTrigger();
        Trigger expectedTrigger = ob.getTriggersSet().getTrigger().get(0).getValue();

        if (ot.getAction().equals(ob.getActionValue())
            && actualTriggerName.equals(expectedTriggerName)
            && actualTrigger.equals(expectedTrigger)) {
          return true;
        }
      }

      return false;
    }