@Test
public void combinedScenarios() {

    List<FullTrigger> activeTriggers = new ArrayList<>();
    // Marketing
    Trigger trigger = new Trigger(TEST_TENANT, "marketing-scenario","Marketing Scenario");
    String expression = "event:groupBy(tags.accountId):window(time,10s):having(count > 2)";
    ExternalCondition condition = new ExternalCondition(trigger.getId(), FIRING, DATA_ID, ALERTER_ID, expression);
    activeTriggers.add(new FullTrigger(trigger, null, Arrays.asList(condition)));
    // Fraud
    trigger = new Trigger(TEST_TENANT, "fraud-scenario", "Fraud Scenario");
    expression = "event:groupBy(tags.accountId):window(time,10s):having(count > 1, count.tags.location > 1)";
    condition = new ExternalCondition(trigger.getId(), FIRING, DATA_ID, ALERTER_ID, expression);
    activeTriggers.add(new FullTrigger(trigger, null, Arrays.asList(condition)));
    // Customer retention
    trigger = new Trigger(TEST_TENANT, "customer-retention-scenario", "Customer Retention Scenario");
    expression = "event:groupBy(tags.traceId):" +
            "filter((category == \"Credit Check\" && text == \"Exceptionally Good\") || " +
            "(category == \"Stock Check\" && text == \"Out of Stock\")):" +
            "having(count > 1, count.tags.accountId == 1)";
    condition = new ExternalCondition(trigger.getId(), FIRING, DATA_ID, ALERTER_ID, expression);
    activeTriggers.add(new FullTrigger(trigger, null, Arrays.asList(condition)));
    Expression exp = new Expression(activeTriggers);
    String drl = exp.getDrl();
    // System.out.println(drl);
    startSession(drl);
    // Init t0
    clock.setStartupTime(1);
    long now = clock.getCurrentTime();
    // User1 buys 5 times in < 10 seconds
    Event a1 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "A1 - Buy Book");
    a1.addContext("duration", "1000");
    a1.addContext("accountId", "user1");
    // User2 buys 3 times > 10 seconds
    Event a6 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "A6 - Buy Book");
    a6.addContext("duration", "1000");
    a6.addContext("accountId", "user2");
    // User1 buys 5 times in < 10 seconds from different locations
    Event b1 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B1 - Buy Book");
    b1.addTag("duration", "1000");
    b1.addTag("accountId", "user1");
    b1.addTag("location", "ip1");
    // User2 buys 3 times > 10 seconds from single location
    Event b6 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B6 - Buy Book");
    b6.addTag("duration", "1000");
    b6.addTag("accountId", "user2");
    b6.addTag("location", "ip3");
    // User3 buys 5 times in < 10 seconds from single location
    Event b11 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B11 - Buy Book");
    b11.addTag("duration", "1000");
    b11.addTag("accountId", "user3");
    b11.addTag("location", "ip10");
    // User1 buys 5 times in < 10 seconds from different locations
    Event e1 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E1 - Buy Book");
    e1.addTag("duration", "1000");
    e1.addTag("accountId", "user1");
    e1.addTag("location", "ip1");
    // User2 buys 3 times > 10 seconds from single location
    Event e6 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E6 - Buy Book");
    e6.addTag("duration", "1000");
    e6.addTag("accountId", "user2");
    e6.addTag("location", "ip3");
    // User3 buys 5 times in < 10 seconds from single location
    Event e11 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E11 - Buy Book");
    e11.addTag("duration", "1000");
    e11.addTag("accountId", "user3");
    e11.addTag("location", "ip10");
    insert(a1, a6, b1, b6, b11, e1, e6, e11);
    // t0 + 1000
    now = clock.advanceTime(1000, TimeUnit.MILLISECONDS);
    Event a2 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "A2 - Buy Music");
    a2.addContext("duration", "2000");
    a2.addContext("accountId", "user1");
    Event b2 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B2 - Buy Music");
    b2.addTag("duration", "2000");
    b2.addTag("accountId", "user1");
    b2.addTag("location", "ip1");
    Event b12 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B12 - Buy Music");
    b12.addTag("duration", "2000");
    b12.addTag("accountId", "user3");
    b12.addTag("location", "ip10");
    Event e2 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E2 - Buy Music");
    e2.addTag("duration", "2000");
    e2.addTag("accountId", "user1");
    e2.addTag("location", "ip1");
    Event e12 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E12 - Buy Music");
    e12.addTag("duration", "2000");
    e12.addTag("accountId", "user3");
    e12.addTag("location", "ip10");
    insert(a2, b2, b12, e2, e12);
    // t0 + 2000
    now = clock.advanceTime(1000, TimeUnit.MILLISECONDS);
    Event a3 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "A3 - Buy Groceries");
    a3.addContext("duration", "1500");
    a3.addContext("accountId", "user1");
    Event b3 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B3 - Buy Groceries");
    b3.addTag("duration", "1500");
    b3.addTag("accountId", "user1");
    b3.addTag("location", "ip1");
    Event b13 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B13 - Buy Groceries");
    b13.addTag("duration", "1500");
    b13.addTag("accountId", "user3");
    b13.addTag("location", "ip10");
    Event e3 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E3 - Buy Groceries");
    e3.addTag("duration", "1500");
    e3.addTag("accountId", "user1");
    e3.addTag("location", "ip1");
    Event e13 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E13 - Buy Groceries");
    e13.addTag("duration", "1500");
    e13.addTag("accountId", "user3");
    e13.addTag("location", "ip10");
    insert(a3, b3, b13, e3, e13);
    // t0 + 3000
    now = clock.advanceTime(1000, TimeUnit.MILLISECONDS);
    Event a4 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "A4 - Buy VideoGames");
    a4.addContext("duration", "3000");
    a4.addContext("accountId", "user1");
    Event b4 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B4 - Buy VideoGames");
    b4.addTag("duration", "3000");
    b4.addTag("accountId", "user1");
    b4.addTag("location", "ip2");
    Event b14 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B14 - Buy VideoGames");
    b14.addTag("duration", "3000");
    b14.addTag("accountId", "user3");
    b14.addTag("location", "ip10");
    Event e4 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E4 - Buy VideoGames");
    e4.addTag("duration", "3000");
    e4.addTag("accountId", "user1");
    e4.addTag("location", "ip2");
    Event e14 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E14 - Buy VideoGames");
    e14.addTag("duration", "3000");
    e14.addTag("accountId", "user3");
    e14.addTag("location", "ip10");
    insert(a4, b4, b14, e4, e14);
    // t0 + 4000
    now = clock.advanceTime(1000, TimeUnit.MILLISECONDS);
    Event a5 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "A5 - Buy VideoGames");
    a5.addContext("duration", "3000");
    a5.addContext("accountId", "user1");
    Event b5 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B5 - Buy VideoGames");
    b5.addTag("duration", "3000");
    b5.addTag("accountId", "user1");
    b5.addTag("location", "ip1");
    Event b15 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B15 - Buy VideoGames");
    b15.addTag("duration", "3000");
    b15.addTag("accountId", "user3");
    b15.addTag("location", "ip10");
    Event e5 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E5 - Buy VideoGames");
    e5.addTag("duration", "3000");
    e5.addTag("accountId", "user1");
    e5.addTag("location", "ip1");
    Event e15 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E15 - Buy VideoGames");
    e15.addTag("duration", "3000");
    e15.addTag("accountId", "user3");
    e15.addTag("location", "ip10");
    insert(a5, b5, b15, e5, e15);
    // t0 + 5000
    now = clock.advanceTime(1000, TimeUnit.MILLISECONDS);
    Event a7 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "A7 - Buy Music");
    a7.addContext("duration", "2000");
    a7.addContext("accountId", "user2");
    insert(a7);
    // t0 + 11000
    now = clock.advanceTime(6000, TimeUnit.MILLISECONDS);
    Event a8 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "A8 - Buy Groceries");
    a8.addContext("duration", "1500");
    a8.addContext("accountId", "user2");
    insert(a8);
    // t0 + 15000
    now = clock.advanceTime(4000, TimeUnit.MILLISECONDS);
    Event b7 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B7 - Buy Music");
    b7.addTag("duration", "2000");
    b7.addTag("accountId", "user2");
    b7.addTag("location", "ip4");
    Event e7 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E7 - Buy Music");
    e7.addTag("duration", "2000");
    e7.addTag("accountId", "user2");
    e7.addTag("location", "ip4");
    insert(b7, e7);
    // t0 + 20000
    now = clock.advanceTime(5000, TimeUnit.MILLISECONDS);
    Event b8 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "B8 - Buy Groceries");
    b8.addTag("duration", "1500");
    b8.addTag("accountId", "user2");
    b8.addTag("location", "ip5");
    Event e8 = new Event(TEST_TENANT, uuid(), now, DATA_ID, "TraceCompletion", "E8 - Buy Groceries");
    e8.addTag("duration", "1500");
    e8.addTag("accountId", "user2");
    e8.addTag("location", "ip5");
    insert(b8, e8);
    stopSession();
    Assert.assertEquals(15, results.size());
    results.stream().forEach(e -> {
        /*
            System.out.println("Event: ");
            System.out.println(e);
            System.out.println("Source events:");
            extractEvents(e).stream().forEach(extracted -> {
                System.out.println(extracted);
            });
            System.out.println("\n");
        */
    });
}