diff --git a/.gitignore b/.gitignore
index 8d377bcf35..2115d5fd97 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
 \.settings/
 \.project
 \.classpath
+\target/**/*
+\target/*
diff --git a/src/main/java/se/su/dsv/scipro/ApplicationSettings.java b/src/main/java/se/su/dsv/scipro/ApplicationSettings.java
index c018687bee..39f25b473d 100644
--- a/src/main/java/se/su/dsv/scipro/ApplicationSettings.java
+++ b/src/main/java/se/su/dsv/scipro/ApplicationSettings.java
@@ -11,6 +11,7 @@ public class ApplicationSettings {
 
 	private boolean enableRemoteUserLookup;
 	private String remoteLookupUrl;
+	private boolean acceptExternalAuthentication;
 	
 	public boolean isEnableRemoteUserLookup() {
 		return enableRemoteUserLookup;
@@ -28,4 +29,12 @@ public class ApplicationSettings {
 		return remoteLookupUrl;
 	}
 	
+	public boolean isAcceptExternalAuthentication(){
+		return acceptExternalAuthentication;
+	}
+	
+	public void setAcceptExternalAuthentication(boolean pAcceptExternalAuthentication){
+		acceptExternalAuthentication = pAcceptExternalAuthentication;
+	}
+	
 }
diff --git a/src/main/java/se/su/dsv/scipro/SciProApplication.java b/src/main/java/se/su/dsv/scipro/SciProApplication.java
index d1fd6babce..2b3c943ee1 100644
--- a/src/main/java/se/su/dsv/scipro/SciProApplication.java
+++ b/src/main/java/se/su/dsv/scipro/SciProApplication.java
@@ -28,6 +28,7 @@ import se.su.dsv.scipro.admin.pages.settings.AdminFinalSeminarSettingsPage;
 import se.su.dsv.scipro.admin.pages.settings.AdminFinalSeminarSettingsPerProjectClassPage;
 import se.su.dsv.scipro.admin.pages.settings.AdminGeneralSettingsPage;
 import se.su.dsv.scipro.admin.pages.settings.AdminPeerSettingsPage;
+import se.su.dsv.scipro.admin.pages.settings.AdminServerEnvironmentSettingsPage;
 import se.su.dsv.scipro.basepages.DemoPage;
 import se.su.dsv.scipro.basepages.errorpages.AccessDeniedPage;
 import se.su.dsv.scipro.basepages.errorpages.NotFoundPage;
@@ -104,9 +105,8 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
 
 	/**
 	 * Logger instance.
-	 * @TODO Inject
 	 */
-	private Logger logger = Logger.getLogger(this.getClass());
+	private Logger logger = Logger.getLogger(SciProApplication.class);
 	/**
 	 * Constructor
 	 */
@@ -191,6 +191,7 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
 		mountBookmarkablePage("admin/files", SysAdminFilePage.class);
 		mountBookmarkablePage("admin/allfinalseminars", AdminFinalSeminarPage.class);
 		mountBookmarkablePage("admin/settings", AdminGeneralSettingsPage.class);
+		mountBookmarkablePage("admin/settings/serverenvironment", AdminServerEnvironmentSettingsPage.class);
 		mountBookmarkablePage("admin/settings/finalseminargeneralsettings", AdminFinalSeminarSettingsPage.class);
 		mountBookmarkablePage("admin/settings/finalseminarprojectlevel", AdminFinalSeminarSettingsPerProjectClassPage.class);
 		mountBookmarkablePage("admin/settings/peer", AdminPeerSettingsPage.class);
@@ -310,7 +311,7 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
 	public WebRequest newWebRequest(final HttpServletRequest request){
 		final WebRequest webRequest = super.newWebRequest(request);
 		if(attemptExternalAuthentication(webRequest)){
-			logger.debug("External authentication used");
+			logger.debug("External authentication used successfully");
 		}
 		return webRequest;
 	}
@@ -331,19 +332,19 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
 			if(session != null){
 				if(session.isLoggedIn()){
 					if(!helper.isRemoteUserValid(session.getUser())){//This check may not be needed and may hinder performance, but better safe than sorry for now.
-						logger.warn("User is logged in, but conflicting info is supplied via external authentication protocols.");
+						logger.debug("User is logged in as '"+session.getUser().getEmailAddress()+"', but conflicting info ('"+helper.getExternalAuthRemoteUser()+"') is supplied via external authentication protocols.");
 					}
 				}else{
 					//logger.info("Attempting sign in with external auth data");
 					if(!helper.signIn(session)){
-						logger.error("User passes external authentication but cannot be signed in.");
+						logger.error("User '"+helper.getExternalAuthRemoteUser()+"' passes external authentication but cannot be signed in.");
 					}else{
 						logger.debug("Signed in user '"+helper.getExternalAuthRemoteUser()+"' via external authentication");
 						return true;
 					}
 				}
 			}else{
-				throw new IllegalStateException("External authentication was attempted, but no session was available.");
+				throw new IllegalStateException("External authentication was attempted, but no session was available for sign in.");
 			}
 		}
 		return false;
diff --git a/src/main/java/se/su/dsv/scipro/SciProSession.java b/src/main/java/se/su/dsv/scipro/SciProSession.java
index 2bc15ed2b1..3d9f1245e4 100644
--- a/src/main/java/se/su/dsv/scipro/SciProSession.java
+++ b/src/main/java/se/su/dsv/scipro/SciProSession.java
@@ -207,7 +207,9 @@ public class SciProSession extends WebSession {
 	 * @return true if the switch was successful, else false.
 	 */
 	public boolean switchAuthenticatedUser(final String suUser, final String suRealm){
-		logger.info("Currently logged in user: '"+user.getEmailAddress()+"' attempting switch to '"+suUser+"'");
+		if(!isLoggedIn() || user == null)//Terminate early
+			return false;
+		logger.info("Currently logged in user: '"+user.getEmailAddress()+"' attempting switch to '"+suUser+"@"+suRealm+"'");
 		if(suUser != null && roleDao.isSysadmin(user)){
 			iRoles.clear();
 			return signInAuthenticatedUser(suUser, suRealm);
diff --git a/src/main/java/se/su/dsv/scipro/admin/pages/AbstractAdminSettingsPage.java b/src/main/java/se/su/dsv/scipro/admin/pages/AbstractAdminSettingsPage.java
index 635d34019c..d43bb6968d 100644
--- a/src/main/java/se/su/dsv/scipro/admin/pages/AbstractAdminSettingsPage.java
+++ b/src/main/java/se/su/dsv/scipro/admin/pages/AbstractAdminSettingsPage.java
@@ -10,6 +10,7 @@ import se.su.dsv.scipro.admin.pages.settings.AdminFinalSeminarSettingsPage;
 import se.su.dsv.scipro.admin.pages.settings.AdminFinalSeminarSettingsPerProjectClassPage;
 import se.su.dsv.scipro.admin.pages.settings.AdminGeneralSettingsPage;
 import se.su.dsv.scipro.admin.pages.settings.AdminPeerSettingsPage;
+import se.su.dsv.scipro.admin.pages.settings.AdminServerEnvironmentSettingsPage;
 import se.su.dsv.scipro.components.AbstractMenuPanel;
 import se.su.dsv.scipro.icons.ImageIcon;
 import se.su.dsv.scipro.security.auth.Authorization;
@@ -29,6 +30,7 @@ public abstract class AbstractAdminSettingsPage extends AbstractAdminPage {
 			protected List<MenuItem> getItemList() {
 				final List<MenuItem> items = new ArrayList<MenuItem>();
 				items.add(new MenuItem("General settings", AdminGeneralSettingsPage.class));
+				items.add(new MenuItem("Server Environment", AdminServerEnvironmentSettingsPage.class));
 				items.add(new MenuItem("Final seminar general settings", AdminFinalSeminarSettingsPage.class));
 				items.add(new MenuItem("Final seminar project level settings", AdminFinalSeminarSettingsPerProjectClassPage.class));
 				items.add(new MenuItem("Peer settings", AdminPeerSettingsPage.class /*,ImageIcon.ICON_SETTINGS */));
diff --git a/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminServerEnvironmentSettingsPage.html b/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminServerEnvironmentSettingsPage.html
new file mode 100644
index 0000000000..71a7e5df94
--- /dev/null
+++ b/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminServerEnvironmentSettingsPage.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html
+	xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
+<body>
+<wicket:extend>
+	<h3 class="section">Server/Request environment</h3>
+	<div style="overflow:auto;height:50%;">
+	<ul>
+		<li wicket:id="requestAttributes">
+			<span wicket:id="name">[name]</span>:
+			<span wicket:id="value">[value]</span>
+		</li>
+	</ul>
+	</div>
+</wicket:extend>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminServerEnvironmentSettingsPage.java b/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminServerEnvironmentSettingsPage.java
new file mode 100644
index 0000000000..8ede9d512a
--- /dev/null
+++ b/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminServerEnvironmentSettingsPage.java
@@ -0,0 +1,49 @@
+package se.su.dsv.scipro.admin.pages.settings;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+
+import se.su.dsv.scipro.admin.pages.AbstractAdminSettingsPage;
+import se.su.dsv.scipro.util.KeyValuePair;
+
+public class AdminServerEnvironmentSettingsPage extends AbstractAdminSettingsPage {
+	public AdminServerEnvironmentSettingsPage(final PageParameters pp) {
+		super(pp);
+		add(new ListView<KeyValuePair<String>>("requestAttributes",getRequestAttributes()){
+			private static final long serialVersionUID = 1L;
+			@Override
+			protected void populateItem(ListItem<KeyValuePair<String>> item){
+				KeyValuePair<String> pair = item.getModelObject();
+				item.add(new Label("name",pair.getKey()));
+				item.add(new Label("value","'"+pair.getValue()+"'"));
+			}
+		});
+	}
+	private List<KeyValuePair<String>> getRequestAttributes(){
+		final HttpServletRequest rawRequest = getWebRequestCycle().getWebRequest().getHttpServletRequest();
+		List<KeyValuePair<String>> list = new ArrayList<KeyValuePair<String>>();
+		list.add(new KeyValuePair<String>("[CALL] getRemoteUser",rawRequest.getRemoteUser()));
+		list.add(new KeyValuePair<String>("[CALL] getAuthType",rawRequest.getAuthType()));
+		@SuppressWarnings("rawtypes") Enumeration attributes = rawRequest.getAttributeNames();
+		while(attributes.hasMoreElements()){
+			final String key = (String)attributes.nextElement();
+			final String value = rawRequest.getAttribute(key).toString();
+			list.add(new KeyValuePair<String>("[ATTR] "+key,value));
+		}
+		Map<String,String> envs = System.getenv();
+		for(String key : envs.keySet()){
+			list.add(new KeyValuePair<String>("[ENV] "+key,envs.get(key)));
+		}
+		return list; 
+	}
+}
+
diff --git a/src/main/java/se/su/dsv/scipro/security/auth/ExternalAuthenticationRequestHelper.java b/src/main/java/se/su/dsv/scipro/security/auth/ExternalAuthenticationRequestHelper.java
index b092537ae1..c70c556893 100644
--- a/src/main/java/se/su/dsv/scipro/security/auth/ExternalAuthenticationRequestHelper.java
+++ b/src/main/java/se/su/dsv/scipro/security/auth/ExternalAuthenticationRequestHelper.java
@@ -1,6 +1,5 @@
 package se.su.dsv.scipro.security.auth;
 
-import java.security.Policy.Parameters;
 import java.util.Enumeration;
 import java.util.Map;
 import java.util.Set;
@@ -8,7 +7,10 @@ import java.util.Set;
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.log4j.Logger;
+import org.apache.wicket.injection.web.InjectorHolder;
+import org.apache.wicket.spring.injection.annot.SpringBean;
 
+import se.su.dsv.scipro.ApplicationSettings;
 import se.su.dsv.scipro.SciProSession;
 import se.su.dsv.scipro.data.dataobjects.User;
 import se.su.dsv.scipro.data.dataobjects.Username;
@@ -30,18 +32,24 @@ public final class ExternalAuthenticationRequestHelper{
 	//Wrapped request
 	private final HttpServletRequest req;
 	//remote user attribute
-	private String remoteUser;
+	private String remoteUser=null;
 	//if remote user is on the username@realm form, this attribute holds the username
-	private String remoteUserId;
+	private String remoteUserId=null;
 	//if remote user is on the username@realm form, this attribute holds the realm
-	private String remoteUserRealm;
+	private String remoteUserRealm=null;
 	//logger instance
 	private Logger logger = Logger.getLogger(this.getClass());
+	@SpringBean 
+	private ApplicationSettings appSettings;
 	/**
 	 * Construct a utility wrapper from a servlet request.
+	 * Throws IllegalStateException if the request is null.
 	 * @param request
 	 */
-	public ExternalAuthenticationRequestHelper(final HttpServletRequest request){
+	public ExternalAuthenticationRequestHelper(final HttpServletRequest request) throws IllegalStateException{
+		if(request==null)
+			throw new IllegalStateException("Request is null, this is considered illegal.");
+		InjectorHolder.getInjector().inject(this);
 		req = request;
 		formatUserString();
 	}
@@ -54,7 +62,7 @@ public final class ExternalAuthenticationRequestHelper{
 	}
 	/**
 	 * Exposed query method.
-	 * @return If remote user is on the username@realm form, this attribute holds the userid, else getExternalAuthRemoteUser().
+	 * @return If remote user is on the username@realm form, this attribute holds the username, else getExternalAuthRemoteUser().
 	 */
 	public String getExternalAuthRemoteUserId(){
 		return remoteUserId;
@@ -70,7 +78,7 @@ public final class ExternalAuthenticationRequestHelper{
 	 * Internal query method
 	 */
 	private boolean isExternalAuthInfoOnRequest(){
-		return (req.getRemoteUser()!=null);
+		return (remoteUser!=null);
 	}
 	/**
 	 * Internal query method
@@ -83,12 +91,16 @@ public final class ExternalAuthenticationRequestHelper{
 	 * @return true if the application is configured to accept external authentication and the needed information is available on the request, else false.
 	 */
 	public boolean isExternalAuthSupported(){
-		return (true && isExternalAuthInfoOnRequest());
+		if(appSettings.isAcceptExternalAuthentication() && !isExternalAuthInfoOnRequest())
+			logger.warn("External authentication support is ON, but REMOTE_USER is not populated");
+		if(!appSettings.isAcceptExternalAuthentication() && isExternalAuthInfoOnRequest())
+			logger.warn("External authentication support is OFF, but REMOTE_USER is populated");
+		return (appSettings.isAcceptExternalAuthentication() && isExternalAuthInfoOnRequest());
 	}
 	/**
 	 * Private utility method for dumping headers.
 	 */
-	public void dumpAuthInfo(){
+	private void dumpAuthInfo(){
 		logger.debug("---Standard methods---");
 		logger.debug("Request implementation:" + req.getClass().getName());
 		logger.debug("getAuthType = '" + getExternalAuthType() +"'");
@@ -165,12 +177,12 @@ public final class ExternalAuthenticationRequestHelper{
 		}
 	}
 	/**
-	 * Signs the stored remote user in on the given SciProSession.
-	 * @param session
+	 * Signs the stored remote user in on the supplied SciProSession.
+	 * @param session If null, method fails gracefully by returning false.
 	 * @return true on success, else false.
 	 */
 	public boolean signIn(final SciProSession session){
-		if(session != null){
+		if(session != null && isExternalAuthSupported()){
 			//dumpAuthInfo();
 			return session.signInAuthenticatedUser(getExternalAuthRemoteUserId(), getExternalAuthRemoteUserRealm());
 		}
diff --git a/src/main/java/se/su/dsv/scipro/util/KeyValuePair.java b/src/main/java/se/su/dsv/scipro/util/KeyValuePair.java
new file mode 100644
index 0000000000..0b7958d70e
--- /dev/null
+++ b/src/main/java/se/su/dsv/scipro/util/KeyValuePair.java
@@ -0,0 +1,79 @@
+package se.su.dsv.scipro.util;
+
+import java.io.Serializable;
+
+/**
+ * Small utility class for immutable (yes it's immutable and no it's never going to be otherwise) key/value pairs.
+ * The "value" field is parameterized, but the key is always intended to be a simple String.
+ * The Serializable properties of this depends on those of the parameterized type.
+ * Typical usage: 
+ * <code>
+ * 	KeyValuePair<SomeType> pair = new KeyValuePair<SomeType>("thisIsAKey",someObject);
+ * 	pair.getKey();
+ * 	pair.getValue();
+ * </code>
+ * @param <V>
+ */
+public final class KeyValuePair<V> implements Serializable{
+	private static final long serialVersionUID = 1L;
+	private final String key;
+	private final V value;
+	/**
+	 * Default and only constructor, provide key and value.
+	 * null values are accepted for both key and value, and should be safe to use (yet nonsensical).
+	 * @param key
+	 * @param value
+	 */
+	public KeyValuePair(final String key, final V value){
+		this.key = key;
+		this.value = value;
+	}
+	/**
+	 * Getter for wrapped key String
+	 * @return The key
+	 */
+	public String getKey(){
+		return key;
+	}
+	/**
+	 * Getter for wrapped Value
+	 * @return The value
+	 */
+	public V getValue(){
+		return value;
+	}
+	/**
+	 * Equals override, behaves in a logical fashion (two objects are equal if both key and value matches).
+	 * Null values are accounted for, ie: two objects with null key+value are considered equal.
+	 */
+	@Override
+	public boolean equals(final Object o){
+		if(o==this)
+			return true;
+		if(!(o instanceof KeyValuePair))
+			return false;
+		@SuppressWarnings("unchecked")
+		final KeyValuePair<V> other = (KeyValuePair<V>)o;
+		return ((key==null?other.key==null:key.equals(other.key)) && 
+				(value==null?other.value==null:value.equals(other.value)));
+	}
+	/**
+	 * Hash-code override, uses both components in a standard fashion.
+	 */
+	@Override
+	public int hashCode(){
+		final int w = 31;
+		int result = 17;//Why hello there Mr Bloch, how are we feeling today ?
+		result = w * result + (key==null?0:key.hashCode());
+		result = w * result + (value==null?0:value.hashCode());
+		return result;
+	}
+	/**
+	 * Standard override, return String format not exposed and subject to change.
+	 * Any parsing of this representation is strongly advised against and done at your own risk.  
+	 */
+	@Override
+	public String toString(){
+		return ("{"+key+":"+value+"}");
+	}
+}
\ No newline at end of file
diff --git a/src/main/resources/applicationContext.xml b/src/main/resources/applicationContext.xml
index 5b8bd5f57b..78cb9aa86b 100644
--- a/src/main/resources/applicationContext.xml
+++ b/src/main/resources/applicationContext.xml
@@ -83,6 +83,8 @@
 		<property name="enableRemoteUserLookup" value="true"></property>
 		<!-- This property points to the location of the daisy json search -->
 		<property name="remoteLookupUrl" value="https://thesis.dsv.su.se/match/json" />
+		<!--  External auth support (via J2EE standard mechanism REMOTE_USER), if true: other authentication mechanics will be bypassed.-->
+		<property name="acceptExternalAuthentication" value="true"/>
 	</bean>
 	
 	<!-- Defines the class used for lookup in username against a remote server  NOW AUTOWIRED AND DEPRECATED, NOT MAINTAINED-->
diff --git a/src/test/java/se/su/dsv/scipro/security/auth/TestAuthRoutines.java b/src/test/java/se/su/dsv/scipro/security/auth/TestAuthRoutines.java
new file mode 100644
index 0000000000..8df1815fcb
--- /dev/null
+++ b/src/test/java/se/su/dsv/scipro/security/auth/TestAuthRoutines.java
@@ -0,0 +1,192 @@
+package se.su.dsv.scipro.security.auth;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequestWrapper;
+
+import org.apache.wicket.protocol.http.HttpSessionStore;
+import org.apache.wicket.session.ISessionStore;
+import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
+import org.apache.wicket.spring.test.ApplicationContextMock;
+import org.apache.wicket.util.tester.WicketTester;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.springframework.orm.jpa.LocalEntityManagerFactoryBean;
+
+import se.su.dsv.scipro.ApplicationSettings;
+import se.su.dsv.scipro.SciProApplication;
+import se.su.dsv.scipro.SciProSession;
+import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
+import se.su.dsv.scipro.data.dao.interfaces.RoleDao;
+import se.su.dsv.scipro.data.dao.interfaces.StringResourceDao;
+import se.su.dsv.scipro.data.dao.interfaces.UserDao;
+import se.su.dsv.scipro.data.dao.interfaces.UserSettingsDao;
+import se.su.dsv.scipro.data.dataobjects.Role;
+import se.su.dsv.scipro.data.dataobjects.Student;
+import se.su.dsv.scipro.data.dataobjects.SysAdmin;
+import se.su.dsv.scipro.data.dataobjects.User;
+import se.su.dsv.scipro.data.dataobjects.Username;
+import se.su.dsv.scipro.json.IUserLookup;
+import se.su.dsv.scipro.repository.util.RepositoryManager;
+ 
+public class TestAuthRoutines {
+	private SciProSession session;
+	private WicketTester wt;
+	private User user;
+	private Role sysAdm;
+	private IUserLookup fixedLookup;
+	private ApplicationSettings appSettings;
+	@Before
+	public void init(){
+		final ApplicationContextMock ac = new ApplicationContextMock();
+		//Create mock object in need of config		
+		appSettings = new ApplicationSettings();
+		appSettings.setAcceptExternalAuthentication(true);
+		//Fake a lookup mechanism
+		fixedLookup = new IUserLookup(){
+			@Override
+			public User lookup(String username) throws Exception{
+				if(username.equals("kalle-kula"))
+					return user;
+				else
+					return null;
+			}
+		};
+		//Create mock user and associated data
+		user = new User();
+		user.setDateCreated(new Date());
+		user.setEmailAddress("kalle-kula@dsv.su.se");
+		user.setFirstName("Kalle");
+		user.setLastName("Kula");
+		user.setIdentifier(new Long(666));
+		user.setLastModified(new Date());
+		Set<Role> roles = new HashSet<Role>();
+		//Faked student
+		Role role = new Student();
+		role.setId(new Long(555));
+		role.setUser(user);
+		roles.add(new Student());
+		user.setRoles(roles);
+		//Faked sysadm, added later
+		sysAdm = new SysAdmin();
+		sysAdm.setId(new Long(444));
+		Set<Username> usernames = new HashSet<Username>();
+		Username username = new Username();
+		username.setUserName("kalle-kula");
+		username.setRealm("DSV.SU.SE");
+		usernames.add(username);
+		user.setUserNames(usernames);
+		//Put stuff on bean context
+		ac.putBean("entityManagerFactory",Mockito.mock(LocalEntityManagerFactoryBean.class));
+		ac.putBean("repositoryManager",Mockito.mock(RepositoryManager.class));
+		ac.putBean("applicationSettings",appSettings);
+		ac.putBean("userDao",Mockito.mock(UserDao.class));
+		ac.putBean("stringResourceDao",Mockito.mock(StringResourceDao.class));
+		RoleDao mockedRoleDao = Mockito.mock(RoleDao.class);
+		Mockito.when(mockedRoleDao.isSysadmin(user)).thenAnswer(new Answer<Boolean>() {
+		    @Override
+		    public Boolean answer(InvocationOnMock invocation) throws Throwable {
+		        return user.getRoles().contains(sysAdm);
+		    }
+		});
+		ac.putBean("roleDao",mockedRoleDao);
+		ac.putBean("projectDao",Mockito.mock(ProjectDao.class));
+		ac.putBean("userSettingsDao",Mockito.mock(UserSettingsDao.class));
+		ac.putBean("userFullLookup",fixedLookup);
+		//Create tester
+		wt = new WicketTester(new SciProApplication(){
+		    @Override
+		    protected ISessionStore newSessionStore(){
+		        return new HttpSessionStore(this);
+		    }
+			@Override
+			protected SpringComponentInjector getSpringInjector() {
+				return new SpringComponentInjector(this, ac, true);
+			}
+		});
+		wt.setupRequestAndResponse();
+		session = (SciProSession)wt.getWicketSession();
+	}
+	@Test
+	public void testAuthenticationHelper() throws IllegalStateException {
+		//Try with faulty request
+		ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(wt.getServletRequest());
+		Assert.assertFalse(helper.isExternalAuthSupported());
+		Assert.assertTrue(helper.getExternalAuthRemoteUser()==null);
+		Assert.assertTrue(helper.getExternalAuthRemoteUserId()==null);
+		Assert.assertTrue(helper.getExternalAuthRemoteUserRealm().equals("DSV.SU.SE"));
+		Assert.assertFalse(helper.isRemoteUserValid(user));
+		Assert.assertFalse(helper.signIn(null));
+		//Try with conforming request
+		helper = new ExternalAuthenticationRequestHelper(new HttpServletRequestWrapper(wt.getServletRequest()){
+			@Override
+			public String getRemoteUser(){
+				return "kalle-kula@dsv.su.se";
+			}
+		});
+		Assert.assertTrue(helper.isExternalAuthSupported());
+		Assert.assertTrue(helper.getExternalAuthRemoteUser().equals("kalle-kula@dsv.su.se"));
+		Assert.assertTrue(helper.getExternalAuthRemoteUserId().equals("kalle-kula"));
+		Assert.assertTrue(helper.getExternalAuthRemoteUserRealm().equals("DSV.SU.SE"));
+		Assert.assertTrue(helper.isRemoteUserValid(user));
+	}
+	@Test
+	public void testTurnOffViaSettings(){
+		appSettings.setAcceptExternalAuthentication(false);
+		ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(wt.getServletRequest());
+		Assert.assertFalse(helper.isExternalAuthSupported());
+	}
+	@Test(expected=IllegalStateException.class)
+	public void testNullRequest(){
+		//At this point, an exception should be thrown
+		new ExternalAuthenticationRequestHelper(null);
+	}
+	@Test(expected=NullPointerException.class)
+	public void testSessionSignInAndSu(){
+		ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(new HttpServletRequestWrapper(wt.getServletRequest()){
+			@Override
+			public String getRemoteUser(){
+				return "kalle-kula@dsv.su.se";
+			}
+		});
+		Assert.assertTrue(helper.isExternalAuthSupported());
+		Assert.assertTrue(helper.signIn(session));
+		Assert.assertTrue(helper.isRemoteUserValid(user));
+		Assert.assertTrue(session.isLoggedIn());
+		Assert.assertTrue(session.getUser().getIdentifier().equals(user.getIdentifier()));
+		//User not authorized to switch, this should fail
+		Assert.assertFalse(session.switchAuthenticatedUser("kalle-kula", "dsv.su.se"));
+		//Change his roles and try again
+		Set<Role> roles = user.getRoles();
+		sysAdm.setUser(user);
+		roles.add(sysAdm);
+		user.setRoles(roles);
+		Assert.assertTrue(session.switchAuthenticatedUser("kalle-kula", "dsv.su.se"));
+		Assert.assertTrue(session.getUser().getIdentifier().equals(user.getIdentifier()));
+		//This should fail with an exception, there is no such user
+		session.switchAuthenticatedUser("somebody","somewhere.se");
+	}
+	@Test(expected=NullPointerException.class)
+	public void testFailedAuthenticatedSignIn(){
+		ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(new HttpServletRequestWrapper(wt.getServletRequest()){
+			@Override
+			public String getRemoteUser(){
+				return "some-dude@ki.se";
+			}
+		});
+		//This should throw exceptions, not sure about this interface (throwing exceptions when authentication passes but no user can be located).
+		helper.signIn(session);
+	}
+	@Test
+	public void testFailedSwitchAuthentitedUser(){
+		Assert.assertFalse(session.isLoggedIn());
+		Assert.assertFalse(session.switchAuthenticatedUser("some-dude-who-is-not-real","someplace.se"));
+		Assert.assertFalse(session.switchAuthenticatedUser("some-dude","someplace.se"));
+	}
+}
diff --git a/src/test/java/se/su/dsv/scipro/util/TestKeyValuePair.java b/src/test/java/se/su/dsv/scipro/util/TestKeyValuePair.java
new file mode 100644
index 0000000000..ac2c9fd764
--- /dev/null
+++ b/src/test/java/se/su/dsv/scipro/util/TestKeyValuePair.java
@@ -0,0 +1,22 @@
+package se.su.dsv.scipro.util;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestKeyValuePair {
+	@Test
+	public void testEqualsOperations() {
+		KeyValuePair<String> kvpOne = new KeyValuePair<String>("key","value");
+		KeyValuePair<String> kvpTwo = new KeyValuePair<String>("key","value");
+		KeyValuePair<String> kvpThree = new KeyValuePair<String>("key3","value");
+		KeyValuePair<String> kvpFour = new KeyValuePair<String>(null,null);
+		KeyValuePair<TestKeyValuePair> kvpFive = new KeyValuePair<TestKeyValuePair>("key",this);
+		
+		Assert.assertTrue(kvpOne.equals(kvpOne));
+		Assert.assertTrue(kvpFour.equals(kvpFour));
+		Assert.assertTrue(kvpOne.equals(kvpTwo) && kvpTwo.equals(kvpOne));
+		Assert.assertFalse(kvpOne.equals(kvpThree) && kvpThree.equals(kvpOne));
+		Assert.assertFalse(kvpFour.equals(kvpThree) && kvpThree.equals(kvpFour));
+		Assert.assertFalse(kvpOne.equals(kvpFive) && kvpFive.equals(kvpOne));
+	}
+}
diff --git a/src/test/java/se/su/dsv/scipro/wicket/BaseWicketTest.java b/src/test/java/se/su/dsv/scipro/wicket/BaseWicketTest.java
index 976579d098..464495f6a5 100644
--- a/src/test/java/se/su/dsv/scipro/wicket/BaseWicketTest.java
+++ b/src/test/java/se/su/dsv/scipro/wicket/BaseWicketTest.java
@@ -17,6 +17,7 @@ import org.mockito.stubbing.Answer;
 import org.springframework.orm.jpa.EntityManagerFactoryInfo;
 import org.springframework.orm.jpa.LocalEntityManagerFactoryBean;
 
+import se.su.dsv.scipro.ApplicationSettings;
 import se.su.dsv.scipro.SciProApplication;
 import se.su.dsv.scipro.data.controllers.FinalSeminarUploadController;
 import se.su.dsv.scipro.data.dao.interfaces.BoardMessageDao;
@@ -95,6 +96,7 @@ public class BaseWicketTest {
 	@Mock GroupEventDao groupEventDao;
 	@Mock HandInActivityDao handInActivityDao;
 	@Mock ScheduleTemplateDao scheduleTemplateDao;
+	@Mock ApplicationSettings applicationSettings;
 	
 	@Mock RepositoryManager repositoryManager;
 	@Mock StringResourceDao stringResourceDao;
diff --git a/src/test/java/se/su/dsv/scipro/wicket/TestWicketPages.java b/src/test/java/se/su/dsv/scipro/wicket/TestWicketPages.java
index 33fc6566e3..830ed93d27 100644
--- a/src/test/java/se/su/dsv/scipro/wicket/TestWicketPages.java
+++ b/src/test/java/se/su/dsv/scipro/wicket/TestWicketPages.java
@@ -8,6 +8,7 @@ import org.mockito.Mockito;
 import se.su.dsv.scipro.HomePage;
 import se.su.dsv.scipro.admin.pages.AdminProjectPartnerPage;
 import se.su.dsv.scipro.admin.pages.SystemMaintenancePage;
+import se.su.dsv.scipro.admin.pages.settings.AdminServerEnvironmentSettingsPage;
 import se.su.dsv.scipro.data.dataobjects.GeneralSystemSettings;
 import se.su.dsv.scipro.data.dataobjects.Project;
 import se.su.dsv.scipro.data.dataobjects.ProjectClass;
@@ -178,6 +179,11 @@ public class TestWicketPages extends BaseWicketTest {
 	public void testProjectPartnerPage() {
 		tester.startPage(ProjectPartnerPage.class);
 	}
+	
+	@Test
+	public void testAdminServerEnvironmentSettingsPage(){
+		tester.startPage(AdminServerEnvironmentSettingsPage.class);
+	}
 
 
 }