### Question:
AuthenticationContext implements Contextual<AuthenticationContext> { public AuthenticationContext withSsl(MatchRule rule, SecurityFactory<SSLContext> sslContext) { if (sslContext == null || rule == null) return this; return new AuthenticationContext(authRules, with(sslRules, rule, sslContext)); } private  AuthenticationContext();   AuthenticationContext(final RuleNode<AuthenticationConfiguration> authRules, final RuleNode<SecurityFactory<SSLContext>> sslRules); static AuthenticationContext empty(); static AuthenticationContext captureCurrent(); AuthenticationContext with(MatchRule rule, AuthenticationConfiguration configuration); AuthenticationContext withSsl(MatchRule rule, SecurityFactory<SSLContext> sslContext); AuthenticationContext with(AuthenticationContext other); AuthenticationContext with(int idx, MatchRule rule, AuthenticationConfiguration configuration); AuthenticationContext withSsl(int idx, MatchRule rule, SecurityFactory<SSLContext> sslContext); AuthenticationContext replacing(int idx, MatchRule rule, AuthenticationConfiguration configuration); AuthenticationContext replacingSslContext(int idx, MatchRule rule, SecurityFactory<SSLContext> sslContext); AuthenticationContext without(int idx); AuthenticationContext withoutSsl(int idx); T run(PrivilegedAction<T> action); T run(PrivilegedExceptionAction<T> action); T run(P parameter, ParametricPrivilegedAction<T, P> action); T run(P parameter, ParametricPrivilegedExceptionAction<T, P> action); void runAsObjIntConsumer(ObjIntConsumer<T> action, T parameter1, int parameter2); T runAsSupplier(Supplier<T> action); void runAsObjIntConsumerEx(ExceptionObjIntConsumer<T, E> action, T parameter1, int parameter2); T runAsSupplierEx(ExceptionSupplier<T, E> action); ContextManager<AuthenticationContext> getInstanceContextManager(); static ContextManager<AuthenticationContext> getContextManager();  }### Answer:
@Test public void addRuleSslAtTheEnd() { RuleNode<SecurityFactory<SSLContext>> initialRule = new RuleNode<>(null, MatchRule.ALL.matchPort(1234), ssl1); AuthenticationContext ctx = new AuthenticationContext(null, initialRule) .withSsl(MatchRule.ALL.matchHost("someHost"), ssl2); assertExpectedRuleNode(ctx.sslRules, ssl1, MatchRule.ALL.matchPort(1234)); RuleNode<SecurityFactory<SSLContext>> second = ctx.sslRules.getNext(); assertExpectedRuleNode(second, ssl2, MatchRule.ALL.matchHost("someHost")); assertNull(second.getNext()); }
@Test public void addRuleSslAtTheStart() { RuleNode<SecurityFactory<SSLContext>> initialRule = new RuleNode<>(null, MatchRule.ALL.matchPort(1234), ssl1); AuthenticationContext ctx = new AuthenticationContext(null, initialRule) .withSsl(0, MatchRule.ALL.matchHost("someHost"), ssl2); assertExpectedRuleNode(ctx.sslRules, ssl2, MatchRule.ALL.matchHost("someHost")); RuleNode<SecurityFactory<SSLContext>> second = ctx.sslRules.getNext(); assertExpectedRuleNode(second, ssl1, MatchRule.ALL.matchPort(1234)); assertNull(second.getNext()); }
@Test public void addRuleSslInTheMiddle() { RuleNode<SecurityFactory<SSLContext>> initialRule = new RuleNode<>( new RuleNode<>(null, MatchRule.ALL.matchPort(2345), ssl2), MatchRule.ALL.matchPort(1234), ssl1); AuthenticationContext ctx = new AuthenticationContext(null, initialRule) .withSsl(1, MatchRule.ALL.matchHost("someHost"), ssl3); assertExpectedRuleNode(ctx.sslRules, ssl1, MatchRule.ALL.matchPort(1234)); RuleNode<SecurityFactory<SSLContext>> second = ctx.sslRules.getNext(); assertExpectedRuleNode(second, ssl3, MatchRule.ALL.matchHost("someHost")); RuleNode<SecurityFactory<SSLContext>> third = second.getNext(); assertExpectedRuleNode(third, ssl2, MatchRule.ALL.matchPort(2345)); assertNull(third.getNext()); }