// Path: src/test/java/at/pollux/thymeleaf/shiro/test/ShiroTest.java
// public abstract class ShiroTest {
// 
//     private static ThreadState subjectThreadState;
// 
//     public ShiroTest() {
//     }
// 
//     /**
//      * Allows subclasses to set the currently executing {@link Subject} instance.
//      *
//      * @param subject the Subject instance
//      */
//     protected void setSubject(Subject subject) {
//         clearSubject();
//         subjectThreadState = createThreadState(subject);
//         subjectThreadState.bind();
//     }
// 
//     protected Subject getSubject() {
//         return SecurityUtils.getSubject();
//     }
// 
//     protected ThreadState createThreadState(Subject subject) {
//         return new SubjectThreadState(subject);
//     }
// 
//     /**
//      * Clears Shiro's thread state, ensuring the thread remains clean for future test execution.
//      */
//     protected void clearSubject() {
//         doClearSubject();
//     }
// 
//     private static void doClearSubject() {
//         if (subjectThreadState != null) {
//             subjectThreadState.clear();
//             subjectThreadState = null;
//         }
//     }
// 
//     protected static void setSecurityManager(SecurityManager securityManager) {
//         SecurityUtils.setSecurityManager(securityManager);
//     }
// 
//     protected static SecurityManager getSecurityManager() {
//         return SecurityUtils.getSecurityManager();
//     }
// 
//     @AfterClass
//     public static void tearDownShiro() {
//         doClearSubject();
//         try {
//             SecurityManager securityManager = getSecurityManager();
//             LifecycleUtils.destroy(securityManager);
//         } catch (UnavailableSecurityManagerException e) {
//             //we don't care about this when cleaning up the test environment
//             //(for example, maybe the subclass is a unit test and it didn't
//             // need a SecurityManager instance because it was using only mock Subject instances)
//         }
//         setSecurityManager(null);
//     }
// }
// 
// Path: src/test/java/at/pollux/thymeleaf/shiro/test/TestIniSecurityManagerFactory.java
// public class TestIniSecurityManagerFactory extends IniSecurityManagerFactory {
// 
//     public TestIniSecurityManagerFactory(Ini config) {
//         super(config);
//     }
// 
//     @Override
//     protected Realm createRealm(Ini ini) {
//         //IniRealm realm = new IniRealm(ini); changed to support SHIRO-322
//         IniRealm realm = new TestIniRealm();
//         realm.setName(INI_REALM_NAME);
//         realm.setIni(ini); //added for SHIRO-322
//         return realm;
//     }
// }


import static org.junit.Assert.*;
import at.pollux.thymeleaf.shiro.test.ShiroTest;
import at.pollux.thymeleaf.shiro.test.TestIniSecurityManagerFactory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.Ini;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
        setSubject(subjectUnderTest);

        Context context = new Context();
        String result;

        // Guest user
        result = templateEngine.process(TEST_TEMPLATE_PATH, context);
        assertFalse(result.contains("shiro:"));
        assertFalse(result.contains("TYPEPRINCIPAL1"));
        assertFalse(result.contains("TYPEPRINCIPAL2"));

        // Logged in user
        subjectUnderTest.login(new UsernamePasswordToken(USER1, PASS1));
        assertEquals(Integer.valueOf(0), SecurityUtils.getSubject().getPrincipals().oneByType(Integer.class)); // sanity
        result = templateEngine.process(TEST_TEMPLATE_PATH, context);
        assertFalse(result.contains("shiro:"));
        assertTrue(result.contains("TYPEPRINCIPAL1<span>0</span>TYPEPRINCIPAL1"));
        assertTrue(result.contains("TYPEPRINCIPAL20TYPEPRINCIPAL2"));
        subjectUnderTest.logout();
    }

    @Test
    public void testPrincipalWithProperty() {
        Subject subjectUnderTest = new Subject.Builder(getSecurityManager()).buildSubject();
        setSubject(subjectUnderTest);

        Context context = new Context();
        String result;

        // Guest user
// Path: src/test/java/at/pollux/thymeleaf/shiro/test/ShiroTest.java
// public abstract class ShiroTest {
// 
//     private static ThreadState subjectThreadState;
// 
//     public ShiroTest() {
//     }
// 
//     /**
//      * Allows subclasses to set the currently executing {@link Subject} instance.
//      *
//      * @param subject the Subject instance
//      */
//     protected void setSubject(Subject subject) {
//         clearSubject();
//         subjectThreadState = createThreadState(subject);
//         subjectThreadState.bind();
//     }
// 
//     protected Subject getSubject() {
//         return SecurityUtils.getSubject();
//     }
// 
//     protected ThreadState createThreadState(Subject subject) {
//         return new SubjectThreadState(subject);
//     }
// 
//     /**
//      * Clears Shiro's thread state, ensuring the thread remains clean for future test execution.
//      */
//     protected void clearSubject() {
//         doClearSubject();
//     }
// 
//     private static void doClearSubject() {
//         if (subjectThreadState != null) {
//             subjectThreadState.clear();
//             subjectThreadState = null;
//         }
//     }
// 
//     protected static void setSecurityManager(SecurityManager securityManager) {
//         SecurityUtils.setSecurityManager(securityManager);
//     }
// 
//     protected static SecurityManager getSecurityManager() {
//         return SecurityUtils.getSecurityManager();
//     }
// 
//     @AfterClass
//     public static void tearDownShiro() {
//         doClearSubject();
//         try {
//             SecurityManager securityManager = getSecurityManager();
//             LifecycleUtils.destroy(securityManager);
//         } catch (UnavailableSecurityManagerException e) {
//             //we don't care about this when cleaning up the test environment
//             //(for example, maybe the subclass is a unit test and it didn't
//             // need a SecurityManager instance because it was using only mock Subject instances)
//         }
//         setSecurityManager(null);
//     }
// }
// 
// Path: src/test/java/at/pollux/thymeleaf/shiro/test/TestIniSecurityManagerFactory.java
// public class TestIniSecurityManagerFactory extends IniSecurityManagerFactory {
// 
//     public TestIniSecurityManagerFactory(Ini config) {
//         super(config);
//     }
// 
//     @Override
//     protected Realm createRealm(Ini ini) {
//         //IniRealm realm = new IniRealm(ini); changed to support SHIRO-322
//         IniRealm realm = new TestIniRealm();
//         realm.setName(INI_REALM_NAME);
//         realm.setIni(ini); //added for SHIRO-322
//         return realm;
//     }
// }


// Path: src/test/java/at/pollux/thymeleaf/shiro/dialect/ShiroDialectTest.java
import static org.junit.Assert.*;
import at.pollux.thymeleaf.shiro.test.ShiroTest;
import at.pollux.thymeleaf.shiro.test.TestIniSecurityManagerFactory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.Ini;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;

        setSubject(subjectUnderTest);

        Context context = new Context();
        String result;

        // Guest user
        result = templateEngine.process(TEST_TEMPLATE_PATH, context);
        assertFalse(result.contains("shiro:"));
        assertFalse(result.contains("TYPEPRINCIPAL1"));
        assertFalse(result.contains("TYPEPRINCIPAL2"));

        // Logged in user
        subjectUnderTest.login(new UsernamePasswordToken(USER1, PASS1));
        assertEquals(Integer.valueOf(0), SecurityUtils.getSubject().getPrincipals().oneByType(Integer.class)); // sanity
        result = templateEngine.process(TEST_TEMPLATE_PATH, context);
        assertFalse(result.contains("shiro:"));
        assertTrue(result.contains("TYPEPRINCIPAL1<span>0</span>TYPEPRINCIPAL1"));
        assertTrue(result.contains("TYPEPRINCIPAL20TYPEPRINCIPAL2"));
        subjectUnderTest.logout();
    }

    @Test
    public void testPrincipalWithProperty() {
        Subject subjectUnderTest = new Subject.Builder(getSecurityManager()).buildSubject();
        setSubject(subjectUnderTest);

        Context context = new Context();
        String result;

        // Guest user
        result = templateEngine.process(TEST_TEMPLATE_PATH, context);