diff --git a/pom.xml b/pom.xml
index 9722a75970..38bb6a6d38 100644
--- a/pom.xml
+++ b/pom.xml
@@ -161,7 +161,6 @@
             <scope>provided</scope>
         </dependency>
 
-
         <!-- JPA -->
         <!-- Hibernate impl -->
         <dependency>
@@ -321,6 +320,11 @@
             <artifactId>wicket-components</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-client</artifactId>
+            <version>1.10</version>
+        </dependency>
 
     </dependencies>
 
@@ -471,6 +475,7 @@
         <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
         <org.springframework.data.version>1.0.3.RELEASE</org.springframework.data.version>
         <querydsl.version>2.3.3</querydsl.version>
+        <remote.lookup.url>https://api.dsv.su.se/rest</remote.lookup.url>
     </properties>
 
     <profiles>
@@ -494,6 +499,7 @@
                 <database.showSql>true</database.showSql>
                 <database.generateDdl>true</database.generateDdl>
                 <wicket.mode>deployment</wicket.mode>
+                <remote.lookup.url>http://apitest.dsv.su.se:8080/rest</remote.lookup.url>
             </properties>
         </profile>
         <profile>
@@ -505,6 +511,7 @@
                 <database.showSql>false</database.showSql>
                 <database.generateDdl>false</database.generateDdl>
                 <wicket.mode>deployment</wicket.mode>
+                <remote.lookup.url>https://api.dsv.su.se/rest</remote.lookup.url>
             </properties>
         </profile>
     </profiles>
diff --git a/src/main/java/se/su/dsv/scipro/admin/panels/ManualImportExportPanel.java b/src/main/java/se/su/dsv/scipro/admin/panels/ManualImportExportPanel.java
index b947e7686f..70b48ae02d 100644
--- a/src/main/java/se/su/dsv/scipro/admin/panels/ManualImportExportPanel.java
+++ b/src/main/java/se/su/dsv/scipro/admin/panels/ManualImportExportPanel.java
@@ -1,10 +1,8 @@
 /**
- * 
+ *
  */
 package se.su.dsv.scipro.admin.panels;
 
-import java.io.Serializable;
-
 import org.apache.log4j.Logger;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.CheckBox;
@@ -13,16 +11,16 @@ import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.spring.injection.annot.SpringBean;
-import org.springframework.context.annotation.ImportResource;
-
 import se.su.dsv.scipro.ApplicationSettings;
 import se.su.dsv.scipro.io.ExternalImporter;
 import se.su.dsv.scipro.io.exceptions.ExternalImportException;
 import se.su.dsv.scipro.security.auth.roles.Roles;
 
+import java.io.Serializable;
+
 public class ManualImportExportPanel extends Panel {
 	private static final long serialVersionUID = 1L;
-	private Label statusMessage = new Label("statusMessage","");
+	private Label statusMessage = new Label("statusMessage", "");
 	@SpringBean
 	private ExternalImporter externalImporter;
 	@SpringBean
@@ -31,25 +29,30 @@ public class ManualImportExportPanel extends Panel {
 	private ApplicationSettings applicationSettings;
 	private Form<ImportExportParams> importExportForm;
 	private static final Logger logger = Logger.getLogger(ManualImportExportPanel.class);
-	
+
 	public ManualImportExportPanel(String id) {
 		super(id);
 		init();
 	}
-	private void init(){
+
+	private void init() {
 		statusMessage.setOutputMarkupId(true);
-		if(hasRemote())
-			setMessage("Using remote: "+getRemoteUrl());
-		else
+		if (hasRemote()) {
+			setMessage("Using remote: " + getRemoteUrl());
+		}
+		else {
 			setMessage("No remote configured");
+		}
 		add(statusMessage);
 		setupForm();
 	}
-	private void setupForm(){
-		importExportForm = new Form<ImportExportParams>("importExportForm",new CompoundPropertyModel<ImportExportParams>(new ImportExportParams())){
+
+	private void setupForm() {
+		importExportForm = new Form<ImportExportParams>("importExportForm", new CompoundPropertyModel<ImportExportParams>(new ImportExportParams())) {
 			private static final long serialVersionUID = 1L;
+
 			@Override
-			public void onSubmit(){
+			public void onSubmit() {
 				final ImportExportParams params = getModelObject();
 				final String userNameIn = params.getImportUserName();
 				final long userIdIn = params.getImportUserId();
@@ -60,78 +63,85 @@ public class ManualImportExportPanel extends Panel {
 				final String projectTitleIn = params.getImportProjectTitle();
 				final long projectIdOut = params.getExportProjectId();
 
-				if(userNameIn != null && !userNameIn.equals("")){
-					logger.debug("Attempting remote import of user: "+userNameIn);
-					try{
-						externalImporter.importUser(userNameIn,params.isIncludeLinkedProjects());
-						setMessage("Succesfully imported user with username: "+userNameIn + " from "+getRemoteUrl());
-					}catch(final ExternalImportException eie){
-						logger.warn("Caught error while importing user from remote system: "+eie.getMessage());
-						setMessage("Failed to import user with username: "+userNameIn+ " from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
+				if (userNameIn != null && !userNameIn.equals("")) {
+					logger.debug("Attempting remote import of user: " + userNameIn);
+					try {
+						externalImporter.importUser(userNameIn, params.isIncludeLinkedProjects());
+						setMessage("Succesfully imported user with username: " + userNameIn + " from " + getRemoteUrl());
+					}
+					catch (final ExternalImportException eie) {
+						logger.warn("Caught error while importing user from remote system: " + eie.getMessage());
+						setMessage("Failed to import user with username: " + userNameIn + " from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
 					}
 				}
-				if(userIdIn > 0){
-					logger.debug("Attempting remote import of id: "+userIdIn);
-					try{
-						externalImporter.importUser(userIdIn,params.isIncludeLinkedProjects());
-						setMessage("Succesfully imported user with id: "+userIdIn + " from "+getRemoteUrl());
-					}catch(final ExternalImportException eie){
-						logger.warn("Caught error while importing user from remote system: "+eie.getMessage());
-						setMessage("Failed to import user with id: "+userIdIn+ " from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
+				if (userIdIn > 0) {
+					logger.debug("Attempting remote import of id: " + userIdIn);
+					try {
+						externalImporter.importUser(userIdIn, params.isIncludeLinkedProjects());
+						setMessage("Succesfully imported user with id: " + userIdIn + " from " + getRemoteUrl());
+					}
+					catch (final ExternalImportException eie) {
+						logger.warn("Caught error while importing user from remote system: " + eie.getMessage());
+						setMessage("Failed to import user with id: " + userIdIn + " from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
 					}
 				}
-				if(importSupervisors){
+				if (importSupervisors) {
 					logger.debug("Importing all listed supervisors");
-					try{
-						externalImporter.importUsersOfRole(Roles.EMPLOYEE,params.isIncludeLinkedProjects());
+					try {
+						externalImporter.importUsersOfRole(Roles.EMPLOYEE, params.isIncludeLinkedProjects());
 						setMessage("Successfully imported supervisors from " + getRemoteUrl());
-					}catch(final ExternalImportException eie){
-						logger.warn("Caught error while importing supervisors from remote system: "+eie.getMessage());
-						setMessage("Failed to import supervisors from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
+					}
+					catch (final ExternalImportException eie) {
+						logger.warn("Caught error while importing supervisors from remote system: " + eie.getMessage());
+						setMessage("Failed to import supervisors from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
 					}
 				}
-				if(importSupervisorUnits){
+				if (importSupervisorUnits) {
 					logger.debug("Importing attached units for supervisors");
 					try {
 						externalImporter.importSupervisorUnits();
 						setMessage("Successfully imported attached units to supervisors from " + getRemoteUrl());
-					} catch (final ExternalImportException eie) {
-						logger.warn("Caught error while importing units to supervisors from remote system: "+eie.getMessage());
-						setMessage("Failed to import units from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
+					}
+					catch (final ExternalImportException eie) {
+						logger.warn("Caught error while importing units to supervisors from remote system: " + eie.getMessage());
+						setMessage("Failed to import units from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
 					}
 				}
-				if(importResearchAreas){
+				if (importResearchAreas) {
 					logger.debug("Importing all research areas from remote host");
 					try {
 						externalImporter.importResearchAreas();
 						setMessage("Successfully imported research areas from " + getRemoteUrl());
-					} catch (final ExternalImportException eie){
-						logger.warn("Caught error while importing research areas from remote system: "+eie.getMessage());
-						setMessage("Failed to import research areas from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
+					}
+					catch (final ExternalImportException eie) {
+						logger.warn("Caught error while importing research areas from remote system: " + eie.getMessage());
+						setMessage("Failed to import research areas from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
 					}
 				}
-				if(projectIdIn > 0){
-					logger.debug("Attempting remote import of project: "+projectIdIn);
-					try{
+				if (projectIdIn > 0) {
+					logger.debug("Attempting remote import of project: " + projectIdIn);
+					try {
 						externalImporter.importProject(projectIdIn);
-						setMessage("Successfully imported project with id "+projectIdIn+" from " + getRemoteUrl());
-					}catch (final ExternalImportException eie){
-						logger.warn("Caught error while importing project from remote system: "+eie.getMessage());
-						setMessage("Failed to import project with id "+projectIdIn+" from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
+						setMessage("Successfully imported project with id " + projectIdIn + " from " + getRemoteUrl());
+					}
+					catch (final ExternalImportException eie) {
+						logger.warn("Caught error while importing project from remote system: " + eie.getMessage());
+						setMessage("Failed to import project with id " + projectIdIn + " from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
 					}
 				}
-				if(projectTitleIn != null && !projectTitleIn.equals((""))){
-					logger.debug("Attempting remote import of projects matching: '"+projectTitleIn+"'");
-					try{
+				if (projectTitleIn != null && !projectTitleIn.equals((""))) {
+					logger.debug("Attempting remote import of projects matching: '" + projectTitleIn + "'");
+					try {
 						externalImporter.importProjects(projectTitleIn);
-						setMessage("Successfully imported all projects matching title '"+projectTitleIn+"' from " + getRemoteUrl());
-					}catch (final ExternalImportException eie){
-						logger.warn("Caught error while importing project from remote system: "+eie.getMessage());
-						setMessage("Failed to import projects matching title '"+projectTitleIn+"' from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
+						setMessage("Successfully imported all projects matching title '" + projectTitleIn + "' from " + getRemoteUrl());
+					}
+					catch (final ExternalImportException eie) {
+						logger.warn("Caught error while importing project from remote system: " + eie.getMessage());
+						setMessage("Failed to import projects matching title '" + projectTitleIn + "' from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
 					}
 				}
-				if(projectIdOut > 0){
-					logger.debug("Attempting remote export of project: "+projectIdOut);
+				if (projectIdOut > 0) {
+					logger.debug("Attempting remote export of project: " + projectIdOut);
 					throw new UnsupportedOperationException("Not implemented yet");
 				}
 			}
@@ -148,17 +158,21 @@ public class ManualImportExportPanel extends Panel {
 		importExportForm.add(new CheckBox("importResearchAreas"));
 		importExportForm.setVisible(hasRemote());
 	}
-	private boolean hasRemote(){
+
+	private boolean hasRemote() {
 		return externalImporter.supportsRemoteOperations();
 	}
-	private String getRemoteUrl(){
-		return applicationSettings.getRemoteLookupUrl();
+
+	private String getRemoteUrl() {
+		return externalImporter.getLookupUrl();
 	}
-	private void setMessage(final String message){
+
+	private void setMessage(final String message) {
 		statusMessage.setDefaultModelObject(message);
 	}
+
 	//Utility model-class
-	private class ImportExportParams implements Serializable{
+	private class ImportExportParams implements Serializable {
 		private static final long serialVersionUID = 5961088002006031317L;
 		private String importUserName;
 		private long importUserId;
@@ -168,58 +182,76 @@ public class ManualImportExportPanel extends Panel {
 		private long importProjectId;
 		private String importProjectTitle;
 		private long exportProjectId;
-		private boolean includeLinkedProjects=false;
+		private boolean includeLinkedProjects = false;
+
 		public String getImportUserName() {
 			return importUserName;
 		}
+
 		public void setImportUserName(String importUserName) {
 			this.importUserName = importUserName;
 		}
+
 		public long getImportProjectId() {
 			return importProjectId;
 		}
+
 		public void setImportProjectId(long importProjectId) {
 			this.importProjectId = importProjectId;
 		}
+
 		public String getImportProjectTitle() {
 			return importProjectTitle;
 		}
+
 		public void setImportProjectTitle(String importProjectTitle) {
 			this.importProjectTitle = importProjectTitle;
 		}
+
 		public long getExportProjectId() {
 			return exportProjectId;
 		}
+
 		public void setExportProjectId(long exportProjectId) {
 			this.exportProjectId = exportProjectId;
 		}
+
 		public boolean isImportSupervisors() {
 			return importSupervisors;
 		}
+
 		public void setImportSupervisors(boolean importSupervisors) {
 			this.importSupervisors = importSupervisors;
 		}
+
 		public boolean isImportSupervisorUnits() {
 			return importSupervisorUnits;
 		}
+
 		public void setImportSupervisorUnits(boolean importSupervisorUnits) {
 			this.importSupervisorUnits = importSupervisorUnits;
 		}
+
 		public long getImportUserId() {
 			return importUserId;
 		}
+
 		public void setImportUserId(long importUserId) {
 			this.importUserId = importUserId;
 		}
+
 		public boolean isIncludeLinkedProjects() {
 			return includeLinkedProjects;
 		}
+
 		public void setIncludeLinkedProjects(boolean includeLinkedProjects) {
 			this.includeLinkedProjects = includeLinkedProjects;
 		}
+
 		public void setImportResearchAreas(boolean importResearchAreas) {
 			this.importResearchAreas = importResearchAreas;
 		}
+
 		public boolean isImportResearchAreas() {
 			return importResearchAreas;
 		}
diff --git a/src/main/java/se/su/dsv/scipro/io/ExternalImporter.java b/src/main/java/se/su/dsv/scipro/io/ExternalImporter.java
index 21abfae753..d93bc7fb07 100644
--- a/src/main/java/se/su/dsv/scipro/io/ExternalImporter.java
+++ b/src/main/java/se/su/dsv/scipro/io/ExternalImporter.java
@@ -7,12 +7,21 @@ import se.su.dsv.scipro.security.auth.roles.Roles;
  * Specifies interaction of an importing service component.
  */
 public interface ExternalImporter {
+	String getLookupUrl();
+
 	void importUser(final String userName, boolean includeLinkedEntities) throws ExternalImportException;
+
 	void importUser(final long externalIdentifier, boolean includeLinkedEntities) throws ExternalImportException;
-	void importUsersOfRole(final Roles role,boolean includeLinkedEntities) throws ExternalImportException;
+
+	void importUsersOfRole(final Roles role, boolean includeLinkedEntities) throws ExternalImportException;
+
 	void importProject(final long externalIdentifier) throws ExternalImportException;
+
 	void importProjects(final String matchingTitle) throws ExternalImportException;
+
 	void importSupervisorUnits() throws ExternalImportException;
+
 	void importResearchAreas() throws ExternalImportException;
+
 	boolean supportsRemoteOperations();
 }
diff --git a/src/main/java/se/su/dsv/scipro/io/http/ApiClient.java b/src/main/java/se/su/dsv/scipro/io/http/ApiClient.java
new file mode 100644
index 0000000000..ae6e92f825
--- /dev/null
+++ b/src/main/java/se/su/dsv/scipro/io/http/ApiClient.java
@@ -0,0 +1,79 @@
+package se.su.dsv.scipro.io.http;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
+import org.apache.log4j.Logger;
+import se.su.dsv.scipro.io.exceptions.HttpRemoteRespondedWithFailureException;
+
+import javax.ws.rs.core.MediaType;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ApiClient {
+	public static final int CONN_TIMEOUT = 1000 * 60;
+	public static final int READ_TIMEOUT = 1000 * 120;
+	public static final String ENC_TYPE = "UTF8";
+
+
+	public enum REQUEST_TYPE {POST, GET}
+
+
+	private final Logger logger = Logger.getLogger(ApiClient.class);
+	private final Map<String, String> parameters = new HashMap<String, String>();
+	private String baseUrl;
+	private String user;
+	private String password;
+
+	public void setBaseUrl(String baseUrl) {
+		this.baseUrl = baseUrl;
+	}
+
+	public String getBaseUrl() {
+		return baseUrl;
+	}
+
+	private ApiClient() {
+	}
+
+	public void setUser(String user) {
+		this.user = user;
+	}
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	/**
+	 * Start to process the request
+	 *
+	 * @throws IOException if a connection error occurred
+	 */
+	public void processRequest(String urlPath, DtoResponseHandler responseHandler, Map<String, String> parameters, REQUEST_TYPE requestType) throws HttpRemoteRespondedWithFailureException {
+		logger.debug("Sending remote request (" + requestType + "): " + urlPath + "?" + parameters);
+		try {
+			WebResource resource = new Client().resource(baseUrl + urlPath);
+			resource.addFilter(new HTTPBasicAuthFilter(user, password));
+
+			String result = null;
+
+			switch (requestType) {
+			case GET:
+				for (Map.Entry<String, String> stringStringEntry : parameters.entrySet()) {
+					resource = resource.queryParam(stringStringEntry.getKey(), stringStringEntry.getValue());
+				}
+				result = resource.accept(MediaType.APPLICATION_JSON_TYPE).get(String.class);
+				break;
+			case POST:
+				result = resource.entity(parameters).accept(MediaType.APPLICATION_JSON).post(String.class);
+			}
+			responseHandler.handleResponse(result);
+		}
+		catch (UniformInterfaceException e) {
+			logger.error(e.getMessage(), e);
+			throw new HttpRemoteRespondedWithFailureException(e.getResponse().getStatus());
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/se/su/dsv/scipro/io/http/HttpRequestSender.java b/src/main/java/se/su/dsv/scipro/io/http/HttpRequestSender.java
deleted file mode 100644
index 30d9e6b184..0000000000
--- a/src/main/java/se/su/dsv/scipro/io/http/HttpRequestSender.java
+++ /dev/null
@@ -1,152 +0,0 @@
- package se.su.dsv.scipro.io.http;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.SocketTimeoutException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.log4j.Logger;
-
-import se.su.dsv.scipro.io.exceptions.HttpRemoteRespondedWithFailureException;
-
-public class HttpRequestSender {
-	public static final int CONN_TIMEOUT = 1000*60;
-	public static final int READ_TIMEOUT = 1000*120;
-	public static final String ENC_TYPE = "UTF8";
-	
-	public enum REQUEST_TYPE{POST,GET};
-	
-	private final REQUEST_TYPE requestType;
-	private final Logger logger = Logger.getLogger(HttpRequestSender.class);
-	private final DtoResponseHandler responseHandler;
-	private final Map<String, String> parameters = new HashMap<String,String>();
-	private final String url;
-	private final String user;
-	private final String password;
-	
-	public HttpRequestSender(final DtoResponseHandler responseHandler, final String url, final String user, final String password, final Map<String, String> parameters, final REQUEST_TYPE requestType){
-		if(responseHandler == null){
-			logger.error("Could not send request, no response handler was provided");
-			throw new IllegalArgumentException("You need to provide a handler for the response");
-		}
-		if(url == null){
-			logger.error("Can't create request for null url");
-			throw new IllegalArgumentException("url parameter must be non-null");
-		}
-		this.responseHandler = responseHandler;
-		this.url = url;
-		this.user = user;
-		this.password = password;
-		if(parameters!=null)
-			this.parameters.putAll(parameters);
-		this.requestType = requestType;
-	}
-	/**
-	 * Start to process the request
-	 * @throws IOException if a connection error occurred
-	 */
-	public void processRequest() throws IOException, HttpRemoteRespondedWithFailureException {
-		logger.debug("Sending remote request ("+requestType+"): " + url + "?"+parameters);
-		String parameterData = "";
-		int count = 0;
-		//Format request
-		for(Map.Entry<String, String> me : parameters.entrySet()){
-			if(count > 0){
-				parameterData += "&";
-			}
-			parameterData += me.getKey() + "=" + me.getValue();
-			count++;
-		}
-		//Add to request as appropriate
-		String urlString = url;
-		if(requestType == REQUEST_TYPE.GET && parameters.size() > 0){
-			urlString += "?" + parameterData;
-		}
-		
-		HttpURLConnection conn = null;
-		OutputStreamWriter osr = null;
-		BufferedReader br = null;
-		try{					
-			//This will throw an MalformedURLException if the url is not valid
-			URL u = new URL(urlString);
-			conn = (HttpURLConnection) getConnection(u);
-			conn.setRequestMethod(requestType.name());
-			//Set connection timeouts 
-			conn.setConnectTimeout(CONN_TIMEOUT);
-			conn.setReadTimeout(READ_TIMEOUT);
-			if(user != null && password != null)
-				conn.setRequestProperty("Authorization", getBasicEncodedAuthData());
-				conn.setRequestProperty("Accept", getAcceptContentType());
-			//Handle POST-style requests
-			if(requestType == REQUEST_TYPE.POST){
-				conn.setDoOutput(true);
-				osr = new OutputStreamWriter(conn.getOutputStream());
-				osr.write(parameterData);
-				osr.flush();
-			}
-			//Handle response errors early on
-			if(conn.getResponseCode() != HttpServletResponse.SC_OK){
-				logger.error("Request URL: "+ u + " responded with failure, status code: " + conn.getResponseCode());
-				dispatchError(conn.getResponseCode());
-			}
-			br = new BufferedReader(new InputStreamReader(conn.getInputStream(),ENC_TYPE));
-			String line = "";
-			StringBuffer response = new StringBuffer();
-			while((line = br.readLine()) != null){
-				response.append(line);
-			}		
-			responseHandler.handleResponse(response.toString());
-		}catch(final MalformedURLException mue){
-			logger.warn("Malformed url: " + urlString + " caused exception");
-			throw mue;
-		}catch(final SocketTimeoutException ste){
-			logger.warn("Socket timeout while talking to remote host on URL: " + urlString);
-			throw ste;
-		}catch(final UnknownHostException uhe){
-			logger.warn("Unknown host: " + urlString + " caused exception");
-			throw uhe;
-		}finally{
-			if(conn != null){
-				conn.disconnect();
-			}
-			if(osr != null){
-				try{
-					osr.close();
-				}catch(final IOException ioe){
-					logger.warn("Close on output stream caused an exception, not much to do about that");
-				}
-			}
-			if(br != null){
-				try{
-					br.close();
-				}catch(final IOException ioe){
-					logger.warn("Close on input stream caused an exception, not much to do about that");
-				}
-			}
-		}
-	}
-	private void dispatchError(int responseCode) {
-		throw new HttpRemoteRespondedWithFailureException(responseCode);
-	}
-	private String getBasicEncodedAuthData() {
-	    String userpassword = user + ":" + password;
-	    String encodedAuthorization = Base64.encodeBase64String(userpassword.getBytes());
-		return ("Basic "+encodedAuthorization);
-	}
-	private String getAcceptContentType() {
-		return "application/json";
-	}
-	protected HttpURLConnection getConnection(final URL url) throws IOException{
-		return (HttpURLConnection)url.openConnection();
-	}
-}
diff --git a/src/main/java/se/su/dsv/scipro/io/http/HttpsRequestSender.java b/src/main/java/se/su/dsv/scipro/io/http/HttpsRequestSender.java
deleted file mode 100644
index 3a39105c80..0000000000
--- a/src/main/java/se/su/dsv/scipro/io/http/HttpsRequestSender.java
+++ /dev/null
@@ -1,24 +0,0 @@
- package se.su.dsv.scipro.io.http;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Map;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSession;
-
-import org.apache.log4j.Logger;
-
-public class HttpsRequestSender extends HttpRequestSender{
-	private Logger logger = Logger.getLogger(HttpsRequestSender.class);
-	public HttpsRequestSender(final DtoResponseHandler responseHandler, final String url, final String user, final String password, final Map<String, String> parameters, final REQUEST_TYPE requestType){
-		super(responseHandler,url,user,password,parameters,requestType);
-	}
-	@Override
-	protected HttpURLConnection getConnection(final URL url) throws IOException{
-				HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
-				return con;
-	}
-}
diff --git a/src/main/java/se/su/dsv/scipro/io/impl/ExternalImporterDaisyImpl.java b/src/main/java/se/su/dsv/scipro/io/impl/ExternalImporterDaisyImpl.java
index 40722f4d89..813494655f 100644
--- a/src/main/java/se/su/dsv/scipro/io/impl/ExternalImporterDaisyImpl.java
+++ b/src/main/java/se/su/dsv/scipro/io/impl/ExternalImporterDaisyImpl.java
@@ -1,44 +1,25 @@
 package se.su.dsv.scipro.io.impl;
 
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
-
 import se.su.dsv.scipro.ApplicationSettings;
 import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
 import se.su.dsv.scipro.data.dao.interfaces.UserDao;
 import se.su.dsv.scipro.data.dataobjects.Project;
 import se.su.dsv.scipro.data.dataobjects.User;
 import se.su.dsv.scipro.io.ExternalImporter;
-import se.su.dsv.scipro.io.dto.AbstractDtoResponseHandler;
-import se.su.dsv.scipro.io.dto.ProjectDTO;
-import se.su.dsv.scipro.io.dto.ProjectDTOCollectionWrapper;
-import se.su.dsv.scipro.io.dto.ProjectParticipantDTO;
-import se.su.dsv.scipro.io.dto.ProjectParticipantDTOCollectionWrapper;
-import se.su.dsv.scipro.io.dto.ResearchAreaDTO;
-import se.su.dsv.scipro.io.dto.ResearchAreaDTOCollectionWrapper;
-import se.su.dsv.scipro.io.dto.PersonDTO;
-import se.su.dsv.scipro.io.dto.PersonDTOCollectionWrapper;
-import se.su.dsv.scipro.io.dto.UnitDTO;
-import se.su.dsv.scipro.io.dto.UnitDTOCollectionWrapper;
-import se.su.dsv.scipro.io.dto.UserDTO;
-import se.su.dsv.scipro.io.dto.UserDTOCollectionWrapper;
-import se.su.dsv.scipro.io.dto.UserRoleDTO;
-import se.su.dsv.scipro.io.dto.UsernameDTO;
-import se.su.dsv.scipro.io.dto.UsernameDTOCollectionWrapper;
+import se.su.dsv.scipro.io.dto.*;
 import se.su.dsv.scipro.io.exceptions.ExternalImportException;
-import se.su.dsv.scipro.io.exceptions.HttpRemoteRespondedWithFailureException;
 import se.su.dsv.scipro.io.facade.ImporterFacade;
-import se.su.dsv.scipro.io.http.HttpRequestSender;
-import se.su.dsv.scipro.io.http.HttpsRequestSender;
+import se.su.dsv.scipro.io.http.ApiClient;
 import se.su.dsv.scipro.security.auth.roles.Roles;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
 /**
  * Importer implementation, uses standard HTTP requests and Json-wrappers.
  * To use this class as the importer, configure it via applicationContext.xml.
@@ -53,355 +34,383 @@ public class ExternalImporterDaisyImpl implements ExternalImporter {
 	@Autowired
 	private ProjectDao projectDao;
 	private final Logger logger = Logger.getLogger(ExternalImporterDaisyImpl.class);
+
+	private ApiClient client;
+
+	public void setClient(ApiClient client) {
+		this.client = client;
+	}
+
+	public ApiClient getClient() {
+		return client;
+	}
+
+	@Override
+	public String getLookupUrl() {
+		return client.getBaseUrl();
+	}
+
 	@Override
 	@Transactional
-	public void importUser(final String userName, boolean includeLinkedEntities) throws ExternalImportException{
-		final Map<String,String> parameters = new HashMap<String,String>();
+	public void importUser(final String userName, boolean includeLinkedEntities) throws ExternalImportException {
+		final Map<String, String> parameters = new HashMap<String, String>();
 		final UserDTOPreProcessor userDTODecorator = getDefaultUserProcessor(includeLinkedEntities);
 		//parameters.put("showTheses", Boolean.valueOf(includeLinkedEntities).toString());
-		sendDefaultUserRequest(parameters,HttpRequestSender.REQUEST_TYPE.GET,userDTODecorator,new UrlProcessor(){
+		sendDefaultUserRequest(parameters, ApiClient.REQUEST_TYPE.GET, userDTODecorator, new UrlProcessor() {
 			@Override
-			String process(final String url){
-				return (url+"/person/username/"+userName);
+			String process(final String url) {
+				return (url + "/person/username/" + userName);
 			}
 		});
 	}
 
 	@Override
 	@Transactional
-	public void importUser(final long externalIdentifier, boolean includeLinkedEntities) throws ExternalImportException{
-		final Map<String,String> parameters = new HashMap<String,String>();
+	public void importUser(final long externalIdentifier, boolean includeLinkedEntities) throws ExternalImportException {
+		final Map<String, String> parameters = new HashMap<String, String>();
 		final UserDTOPreProcessor userDTODecorator = getDefaultUserProcessor(includeLinkedEntities);
-		sendDefaultUserRequest(parameters,HttpRequestSender.REQUEST_TYPE.GET,userDTODecorator,new UrlProcessor(){
+		sendDefaultUserRequest(parameters, ApiClient.REQUEST_TYPE.GET, userDTODecorator, new UrlProcessor() {
 			@Override
-			String process(final String url){
-				return (url+"/person/"+externalIdentifier);
+			String process(final String url) {
+				return (url + "/person/" + externalIdentifier);
 			}
 		});
 	}
+
 	@Override
 	@Transactional
-	public void importUsersOfRole(final Roles role, boolean includeLinkedEntities) throws ExternalImportException{
-		final Map<String,String> parameters = new HashMap<String,String>();
+	public void importUsersOfRole(final Roles role, boolean includeLinkedEntities) throws ExternalImportException {
+		final Map<String, String> parameters = new HashMap<String, String>();
 		final UserDTOPreProcessor employeeDTODecorator = getDefaultEmployeeUserProcessor(includeLinkedEntities);//Force all returned users to be assigned the local "Supervisor" role
-		if(!role.equals(Roles.EMPLOYEE)) //Only supports employees currently
+		if (!role.equals(Roles.EMPLOYEE)) //Only supports employees currently
+		{
 			throw new UnsupportedOperationException("Sorry, only the EMPLOYEE role is currently supported");
-		sendDefaultUserRequest(parameters,HttpRequestSender.REQUEST_TYPE.GET, employeeDTODecorator,new UrlProcessor(){
+		}
+		sendDefaultUserRequest(parameters, ApiClient.REQUEST_TYPE.GET, employeeDTODecorator, new UrlProcessor() {
 			@Override
-			String process(final String url){
-				return (url+"/orgunit/4/supervisors");//Hehe
+			String process(final String url) {
+				return (url + "/orgunit/4/supervisors");//Hehe
 			}
 		});
 	}
+
 	@Override
 	public void importProjects(final String title) throws ExternalImportException {
-		final Map<String,String> parameters = new HashMap<String,String>();
+		final Map<String, String> parameters = new HashMap<String, String>();
 		parameters.put("title", title);
-		Set<ProjectDTO> externalProjectSet = fetchRemoteProjects(parameters,HttpRequestSender.REQUEST_TYPE.GET,null, new UrlProcessor(){
+		Set<ProjectDTO> externalProjectSet = fetchRemoteProjects(parameters, ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 			@Override
-			String process(final String url){
-				return (url+"/thesis");
+			String process(final String url) {
+				return (url + "/thesis");
 			}
 		});
 		final Set<ProjectDTO> projectsWithParticipants = projectDTOWithParticipants(externalProjectSet);
 
-		for(ProjectDTO projectDTO : projectsWithParticipants){
+		for (ProjectDTO projectDTO : projectsWithParticipants) {
 			final Project project = projectDao.getProjectByIdentifier(projectDTO.id);
-			if(project == null)
-				logger.info("Importing new project: '" + projectDTO+"'");
-			else
-				logger.info("Updating existing project: '" + projectDTO+"'");
+			if (project == null) {
+				logger.info("Importing new project: '" + projectDTO + "'");
+			}
+			else {
+				logger.info("Updating existing project: '" + projectDTO + "'");
+			}
 			importerFacade.mergeProject(project, projectDTO);
 		}
 	}
+
 	@Override
 	public void importProject(final long externalIdentifier) throws ExternalImportException {
-		Set<ProjectDTO> externalProjectSet = fetchRemoteProjects(new HashMap<String,String>(),HttpRequestSender.REQUEST_TYPE.GET,null, new UrlProcessor(){
+		Set<ProjectDTO> externalProjectSet = fetchRemoteProjects(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 			@Override
-			String process(final String url){
-				return (url+"/thesis/"+externalIdentifier);
+			String process(final String url) {
+				return (url + "/thesis/" + externalIdentifier);
 			}
 		});
 		final Set<ProjectDTO> projectsWithParticipants = projectDTOWithParticipants(externalProjectSet);
 
-		for(ProjectDTO projectDTO : projectsWithParticipants){
+		for (ProjectDTO projectDTO : projectsWithParticipants) {
 			final Project project = projectDao.getProjectByIdentifier(projectDTO.id);
-			if(project == null)
-				logger.info("Importing new project: '" + projectDTO+"'");
-			else
-				logger.info("Updating existing project: '" + projectDTO+"'");
+			if (project == null) {
+				logger.info("Importing new project: '" + projectDTO + "'");
+			}
+			else {
+				logger.info("Updating existing project: '" + projectDTO + "'");
+			}
 			importerFacade.mergeProject(project, projectDTO);
 		}
 	}
-	
+
 	@Override
 	@Transactional
 	public void importSupervisorUnits() throws ExternalImportException {
-		Set<UnitDTO> unitSet = fetchRemoteUnits(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor() {
+		Set<UnitDTO> unitSet = fetchRemoteUnits(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 			@Override
-			String process(final String url){
-				return (url+"/orgunit/4/subunits");
+			String process(final String url) {
+				return (url + "/orgunit/4/subunits");
 			}
 		});
-		
+
 		importerFacade.addUnexistingUnitsAsKeywords(unitSet);
 		Set<PersonDTO> allSupervisorsOnUnits = new HashSet<PersonDTO>();
-		for (final UnitDTO unitDTO : unitSet){
-			Set<PersonDTO> supervisorSet = fetchSupervisorsOnUnit(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor() {
+		for (final UnitDTO unitDTO : unitSet) {
+			Set<PersonDTO> supervisorSet = fetchSupervisorsOnUnit(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 				@Override
-				String process(final String url){
-					return (url+"/orgunit/"+unitDTO.id+"/supervisors");
+				String process(final String url) {
+					return (url + "/orgunit/" + unitDTO.id + "/supervisors");
 				}
 			});
 			allSupervisorsOnUnits.addAll(supervisorSet);
-			if(!supervisorSet.isEmpty()){
+			if (!supervisorSet.isEmpty()) {
 				for (PersonDTO supervisorDTO : supervisorSet) {
-				importerFacade.addUnitToSupervisor(supervisorDTO, unitDTO);
-				} 
-			} else
-			logger.info("Unit: " + unitDTO.name + " has no supervisors attached.");	
+					importerFacade.addUnitToSupervisor(supervisorDTO, unitDTO);
+				}
+			}
+			else {
+				logger.info("Unit: " + unitDTO.name + " has no supervisors attached.");
+			}
 		}
-		
+
 		// Compare the list of supervisors with remote units with the list of
 		// all supervisors in scipro, to make sure to remove units from the
 		// users that doesn't have one in daisy.
 		logger.debug("Number of supervisors on remote units: " + allSupervisorsOnUnits.size());
 		importerFacade.removeUnitFromSupervisorsNotInSet(allSupervisorsOnUnits);
 	}
-	
+
 	@Override
 	@Transactional
 	public void importResearchAreas() throws ExternalImportException {
-		Set<ResearchAreaDTO> areaSet = fetchResearchAreas(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor() {
+		Set<ResearchAreaDTO> areaSet = fetchResearchAreas(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 			@Override
-			String process(final String url){
-				return (url+"/orgunit/4/researchAreas");
+			String process(final String url) {
+				return (url + "/orgunit/4/researchAreas");
 			}
 		});
 		logger.info("Received " + areaSet.size() + " research areas from remote and adding those who not exist to database");
-		if(!areaSet.isEmpty()){
+		if (!areaSet.isEmpty()) {
 			importerFacade.addUnexistingResearchAreas(areaSet);
-		}	
+		}
 	}
-	
-	private Set<PersonDTO> fetchSupervisorsOnUnit(final Map<String, String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, UrlProcessor urlProcessor) {
-		final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
+
+	private Set<PersonDTO> fetchSupervisorsOnUnit(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, UrlProcessor urlProcessor) {
+		final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
 		final Set<PersonDTO> dtoCache = new HashSet<PersonDTO>();
-		final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler() {
-			
-			@Override
-			public void handleResponse(String response) {
-				logger.info("Response received (from: "+ requestUrl+"): " + response);
-				final PersonDTOCollectionWrapper supervisorCollection = asSupervisorCollection(response);
-				if(supervisorCollection.size() == 0){
-					throw new ExternalImportException("No supervisors found in remote");
-				} else {
-					dtoCache.addAll(supervisorCollection.getPersons());
+		try {
+			client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
+
+				@Override
+				public void handleResponse(String response) {
+					logger.info("Response received (from: " + requestUrl + "): " + response);
+					final PersonDTOCollectionWrapper supervisorCollection = asSupervisorCollection(response);
+					if (supervisorCollection.size() == 0) {
+						throw new ExternalImportException("No supervisors found in remote");
+					}
+					else {
+						dtoCache.addAll(supervisorCollection.getPersons());
+					}
+					logger.info("Received " + supervisorCollection.size() + " supervisor" + (supervisorCollection.size() == 1 ? "" : "s") + " from remote");
 				}
-				logger.info("Received " + supervisorCollection.size() + " supervisor"+(supervisorCollection.size()==1?"":"s")+" from remote");
-			}
-		}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
-		try{
-			process(senderProxy);
-		} catch (final ExternalImportException eie){
+			}, parameters, requestType);
+		}
+		catch (final ExternalImportException eie) {
 			logger.warn("No supervisors found");
 		}
 		return dtoCache;
 	}
-	
-	private Set<UnitDTO> fetchRemoteUnits(final Map<String,String> parameters,final HttpRequestSender.REQUEST_TYPE requestType,
-			UrlProcessor urlProcessor) {
-		final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
+
+	private Set<UnitDTO> fetchRemoteUnits(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType,
+										  UrlProcessor urlProcessor) {
+		final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
 		final Set<UnitDTO> dtoCache = new HashSet<UnitDTO>();
-		final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler(){
-			@Override
-			public void handleResponse(String response) {
-				logger.info("Response received (from: "+requestUrl+"): " + response);
-				final UnitDTOCollectionWrapper unitCollection = asUnitCollection(response);//The query will always returns a collection, regardless of backing data
-				if(unitCollection.size() == 0){//If at this point we have nothing, we have to throw.
-					throw new ExternalImportException("No units found in remote");
-				}else{
-					dtoCache.addAll(unitCollection.getUnits());
+		try {
+			client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
+				@Override
+				public void handleResponse(String response) {
+					logger.info("Response received (from: " + requestUrl + "): " + response);
+					final UnitDTOCollectionWrapper unitCollection = asUnitCollection(response);//The query will always returns a collection, regardless of backing data
+					if (unitCollection.size() == 0) {//If at this point we have nothing, we have to throw.
+						throw new ExternalImportException("No units found in remote");
+					}
+					else {
+						dtoCache.addAll(unitCollection.getUnits());
+					}
+					logger.info("Received " + unitCollection.size() + " unit" + (unitCollection.size() == 1 ? "" : "s") + " from remote");
 				}
-				logger.info("Received " + unitCollection.size() + " unit"+(unitCollection.size()==1?"":"s")+" from remote");
-			}
-		}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
-		try{
-			process(senderProxy);
-		}catch(final ExternalImportException eie){
+			}, parameters, requestType);
+		}
+		catch (final ExternalImportException eie) {
 			logger.warn("No units found");
 		}
-		return dtoCache;	
+		return dtoCache;
 	}
 
 	@Override
 	public boolean supportsRemoteOperations() {
 		return true;
 	}
+
 	/**
 	 * Private utility method, sends request and signals failure via exceptions.
+	 *
 	 * @param parameters
 	 * @param requestType
 	 */
-	private void sendDefaultUserRequest(final Map<String,String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, final UserDTOPreProcessor preProcessor, final UrlProcessor urlProcessor){
-		final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
-		final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler(){
+	private void sendDefaultUserRequest(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, final UserDTOPreProcessor preProcessor, final UrlProcessor urlProcessor) {
+		final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
+		client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
 			@Override
 			public void handleResponse(String response) {
-				logger.info("Response recieved (from: "+requestUrl+"): " + response);
+				logger.info("Response recieved (from: " + requestUrl + "): " + response);
 				final UserDTOCollectionWrapper userCollection = asUserCollectionWrapper(response);//The query will always returns a collection, regardless of backing data
-				if(userCollection.size() == 0){//If at this point we have nothing, we have to throw.
+				if (userCollection.size() == 0) {//If at this point we have nothing, we have to throw.
 					throw new ExternalImportException("No users found in remote");
-				}else{
-					for(final UserDTO userDTO:userCollection){
+				}
+				else {
+					for (final UserDTO userDTO : userCollection) {
 						final User user = userDao.getUserByIdentifier(userDTO.id);
-						if(user == null)
-							logger.info("Importing new user: '" + userDTO+"'");
-						else
-							logger.info("Updating existing user: '" + userDTO+"'");
-						importerFacade.mergeUser(user, (preProcessor!=null?preProcessor.process(userDTO):userDTO));
+						if (user == null) {
+							logger.info("Importing new user: '" + userDTO + "'");
+						}
+						else {
+							logger.info("Updating existing user: '" + userDTO + "'");
+						}
+						importerFacade.mergeUser(user, (preProcessor != null ? preProcessor.process(userDTO) : userDTO));
 					}
 				}
-				logger.info("Recieved " + userCollection.size() + " user"+(userCollection.size()==1?"":"s")+" from remote");
+				logger.info("Recieved " + userCollection.size() + " user" + (userCollection.size() == 1 ? "" : "s") + " from remote");
 			}
-		}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
-		process(senderProxy);
+		}, parameters, requestType);
 	}
-	private Set<ProjectDTO> fetchRemoteProjects(final Map<String,String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, final ProjectDTOPreProcessor preProcessor, final UrlProcessor urlProcessor){
-		final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
+
+	private Set<ProjectDTO> fetchRemoteProjects(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
+		final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
 		final Set<ProjectDTO> dtoCache = new HashSet<ProjectDTO>();
-		final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler(){
-			@Override
-			public void handleResponse(String response) {
-				logger.info("Response recieved (from: "+requestUrl+"): " + response);
-				final ProjectDTOCollectionWrapper projectCollection = asProjectCollection(response);//The query will always returns a collection, regardless of backing data
-				if(projectCollection.size() == 0){//If at this point we have nothing, we have to throw.
-					throw new ExternalImportException("No projects found in remote");
-				}else{
-					dtoCache.addAll(projectCollection.getProjects());
+		try {
+			client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
+				@Override
+				public void handleResponse(String response) {
+					logger.info("Response recieved (from: " + requestUrl + "): " + response);
+					final ProjectDTOCollectionWrapper projectCollection = asProjectCollection(response);//The query will always returns a collection, regardless of backing data
+					if (projectCollection.size() == 0) {//If at this point we have nothing, we have to throw.
+						throw new ExternalImportException("No projects found in remote");
+					}
+					else {
+						dtoCache.addAll(projectCollection.getProjects());
+					}
+					logger.info("Recieved " + projectCollection.size() + " project" + (projectCollection.size() == 1 ? "" : "s") + " from remote");
 				}
-				logger.info("Recieved " + projectCollection.size() + " project"+(projectCollection.size()==1?"":"s")+" from remote");
-			}
-		}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
-		try{
-			process(senderProxy);
-		}catch(final ExternalImportException eie){
+			}, parameters, requestType);
+		}
+		catch (final ExternalImportException eie) {
 			logger.warn("No projects found, this may or may not indicate a problem");
 		}
 		return dtoCache;
 	}
-	
-	private Set<UsernameDTO> fetchRemoteUsernames(final Map<String,String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
-		final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
+
+	private Set<UsernameDTO> fetchRemoteUsernames(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
+		final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
 		final Set<UsernameDTO> dtoCache = new HashSet<UsernameDTO>();
-		final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler() {
-			
-			@Override
-			public void handleResponse(String response) {
-				logger.info("Response recieved (from: "+requestUrl+"): " + response);
-				final UsernameDTOCollectionWrapper usernameCollection = asUsernameCollection(response);
-				if(usernameCollection.size() == 0){
-					throw new ExternalImportException("No usernames found in remote");
-				}else{
-					dtoCache.addAll(usernameCollection.getUsernames());
+		try {
+			client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
+
+				@Override
+				public void handleResponse(String response) {
+					logger.info("Response recieved (from: " + requestUrl + "): " + response);
+					final UsernameDTOCollectionWrapper usernameCollection = asUsernameCollection(response);
+					if (usernameCollection.size() == 0) {
+						throw new ExternalImportException("No usernames found in remote");
+					}
+					else {
+						dtoCache.addAll(usernameCollection.getUsernames());
+					}
+					logger.info("Received " + usernameCollection.size() + " usernames" + (usernameCollection.size() == 1 ? "" : "s") + " from remote");
 				}
-				logger.info("Received " + usernameCollection.size() + " usernames"+(usernameCollection.size()==1?"":"s")+" from remote");
-			}
-		}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
-		try{
-			process(senderProxy);
-		} catch (final ExternalImportException eie){
+			}, parameters, requestType);
+		}
+		catch (final ExternalImportException eie) {
 			logger.warn("No usernames found");
 		}
+
 		return dtoCache;
 	}
-	
-	private Set<ResearchAreaDTO> fetchResearchAreas(final Map<String, String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
-		final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
+
+	private Set<ResearchAreaDTO> fetchResearchAreas(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
+		final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
 		final Set<ResearchAreaDTO> dtoCache = new HashSet<ResearchAreaDTO>();
-		final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler(){
-			@Override
-			public void handleResponse(String response) {
-				logger.info("Response recieved (from: "+requestUrl+"): " + response);
-				final ResearchAreaDTOCollectionWrapper areaCollection = asAreaCollection(response);//The query will always returns a collection, regardless of backing data
-				if(areaCollection.size() == 0){//If at this point we have nothing, we have to throw.
-					throw new ExternalImportException("No research areas found in remote");
-				}else{
-					dtoCache.addAll(areaCollection.getAreas());
+		try {
+			client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
+				@Override
+				public void handleResponse(String response) {
+					logger.info("Response recieved (from: " + requestUrl + "): " + response);
+					final ResearchAreaDTOCollectionWrapper areaCollection = asAreaCollection(response);//The query will always returns a collection, regardless of backing data
+					if (areaCollection.size() == 0) {//If at this point we have nothing, we have to throw.
+						throw new ExternalImportException("No research areas found in remote");
+					}
+					else {
+						dtoCache.addAll(areaCollection.getAreas());
+					}
+					logger.info("Recieved " + areaCollection.size() + " research area" + (areaCollection.size() == 1 ? "" : "s") + " from remote");
 				}
-				logger.info("Recieved " + areaCollection.size() + " research area"+(areaCollection.size()==1?"":"s")+" from remote");
-			}
-		}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
-		try{
-			process(senderProxy);
-		}catch(final ExternalImportException eie){
+			}, parameters, requestType);
+		}
+		catch (final ExternalImportException eie) {
 			logger.warn("No research areas found, this may or may not indicate a problem");
 		}
 		return dtoCache;
 	}
-	
-	private Set<ProjectParticipantDTO> fetchParticipants(final Map<String, String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
-		final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
+
+	private Set<ProjectParticipantDTO> fetchParticipants(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
+		final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
 		final Set<ProjectParticipantDTO> dtoCache = new HashSet<ProjectParticipantDTO>();
-		final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler(){
-			@Override
-			public void handleResponse(String response) {
-				logger.info("Response recieved (from: "+requestUrl+"): " + response);
-				final ProjectParticipantDTOCollectionWrapper participantCollection = asParticipantCollection(response);//The query will always returns a collection, regardless of backing data
-				if(participantCollection.size() == 0){//If at this point we have nothing, we have to throw.
-					throw new ExternalImportException("No project participants found in remote");
-				}else{
-					dtoCache.addAll(participantCollection.getParticipants());
+		try {
+			client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
+				@Override
+				public void handleResponse(String response) {
+					logger.info("Response recieved (from: " + requestUrl + "): " + response);
+					final ProjectParticipantDTOCollectionWrapper participantCollection = asParticipantCollection(response);//The query will always returns a collection, regardless of backing data
+					if (participantCollection.size() == 0) {//If at this point we have nothing, we have to throw.
+						throw new ExternalImportException("No project participants found in remote");
+					}
+					else {
+						dtoCache.addAll(participantCollection.getParticipants());
+					}
+					logger.info("Recieved " + participantCollection.size() + " project participant" + (participantCollection.size() == 1 ? "" : "s") + " from remote");
 				}
-				logger.info("Recieved " + participantCollection.size() + " project participant"+(participantCollection.size()==1?"":"s")+" from remote");
-			}
-		}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
-		try{
-			process(senderProxy);
-		}catch(final ExternalImportException eie){
+			}, parameters, requestType);
+		}
+		catch (final ExternalImportException eie) {
 			logger.warn("No project participants found, this may or may not indicate a problem");
 		}
 		return dtoCache;
 	}
 
-	private String getRequestUrl(){
-		return applicationSettings.getRemoteLookupUrl();
-	}
-	private String getRequestUser() {
-		return applicationSettings.getRemoteLookupUser();
-	}
-	private String getRequestPassword() {
-		return applicationSettings.getRemoteLookupPassword();
-	}
-	private void process(final HttpRequestSender proxy) throws ExternalImportException{
-		try{
-			proxy.processRequest();
-		}catch(final IOException ioe){
-			logger.error("A fatal IO exception has occured while contacting remote host at: " + getRequestUrl());
-			throw new ExternalImportException(ioe);
-		}catch(final HttpRemoteRespondedWithFailureException hrrwfe){
-			logger.error("Remote host: " + getRequestUrl() + " responded with failure: "+ hrrwfe.getMessage());
-			throw new ExternalImportException(hrrwfe);//Use getCause etc to find out the response code and act on it in some meaningful way
-		}
+	/**
+	 * @return
+	 * @deprecated Should be removed. This is set in the client config in applicationContext.xml
+	 */
+	private String getRequestUrl() {
+		return "";
 	}
+
 	private UserDTOPreProcessor getDefaultUserProcessor(boolean includeLinkedEntities) {
-		if(!includeLinkedEntities)
+		if (!includeLinkedEntities) {
 			return new UserDTOPreProcessor();
-		return new UserDTOPreProcessor(){
+		}
+		return new UserDTOPreProcessor() {
 			@Override
-			UserDTO process(final UserDTO userDTO){
-				final Set<ProjectDTO> fetchedProjects = fetchRemoteProjects(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, null, new UrlProcessor(){
+			UserDTO process(final UserDTO userDTO) {
+				final Set<ProjectDTO> fetchedProjects = fetchRemoteProjects(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 					@Override
-					String process(String url){
-						return (url+"/person/"+userDTO.id+"/theses");
+					String process(String url) {
+						return (url + "/person/" + userDTO.id + "/theses");
 					}
 				});
 				//Fetch authors and supervisors for each project
 				final Set<ProjectDTO> projectsWithParticipants = projectDTOWithParticipants(fetchedProjects);
-				final Set<UsernameDTO> fetchedUsernames =  fetchRemoteUsernames(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor(){
+				final Set<UsernameDTO> fetchedUsernames = fetchRemoteUsernames(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 					@Override
-					String process(String url){
-						return(url+"/person/"+userDTO.id+"/usernames");
+					String process(String url) {
+						return (url + "/person/" + userDTO.id + "/usernames");
 					}
 				});
 				userDTO.projects = projectsWithParticipants;
@@ -410,88 +419,85 @@ public class ExternalImporterDaisyImpl implements ExternalImporter {
 			}
 		};
 	}
+
 	private UserDTOPreProcessor getDefaultEmployeeUserProcessor(final boolean includeLinkedEntities) {
-		return new UserDTOPreProcessor(){
+		return new UserDTOPreProcessor() {
 			@Override
-			UserDTO process(final UserDTO userDTO){
-				if(includeLinkedEntities){
-					final Set<ProjectDTO> fetchedProjects = fetchRemoteProjects(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, null, new UrlProcessor(){
+			UserDTO process(final UserDTO userDTO) {
+				if (includeLinkedEntities) {
+					final Set<ProjectDTO> fetchedProjects = fetchRemoteProjects(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 						@Override
-						String process(String url){
-							return (url+"/person/"+userDTO.id+"/theses");
+						String process(String url) {
+							return (url + "/person/" + userDTO.id + "/theses");
 						}
 					});
 					final Set<ProjectDTO> projectsWithParticipants = projectDTOWithParticipants(fetchedProjects);
 					userDTO.projects = projectsWithParticipants;
 				}
-				final Set<UsernameDTO> fetchedUsernames =  fetchRemoteUsernames(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor(){
+				final Set<UsernameDTO> fetchedUsernames = fetchRemoteUsernames(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 					@Override
-					String process(String url){
-						return(url+"/person/"+userDTO.id+"/usernames");
+					String process(String url) {
+						return (url + "/person/" + userDTO.id + "/usernames");
 					}
 				});
 				userDTO.usernames = fetchedUsernames;
-				final Set<ResearchAreaDTO> fetchedResearchAreas = fetchResearchAreas(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor(){
+				final Set<ResearchAreaDTO> fetchedResearchAreas = fetchResearchAreas(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 					@Override
-					String process(String url){
-						return (url+"/person/"+userDTO.id+"/researchAreas");
+					String process(String url) {
+						return (url + "/person/" + userDTO.id + "/researchAreas");
 					}
 				});
 				userDTO.researchAreas = fetchedResearchAreas;
 				//Force employee role data to be on the DTO
 				UserRoleDTO employeeRole = new UserRoleDTO();
 				employeeRole.role = UserRoleDTO.EXTERNAL_USER_ROLES.SUPERVISOR_ROLE.asExternal();
-				if(!userDTO.roles.contains(employeeRole)){
+				if (!userDTO.roles.contains(employeeRole)) {
 					userDTO.roles.add(employeeRole);
 				}
 				return userDTO;
 			}
-			
+
 		};
 	}
-	
-	private Set<ProjectDTO> projectDTOWithParticipants(Set<ProjectDTO> fetchedProjects){
+
+	private Set<ProjectDTO> projectDTOWithParticipants(Set<ProjectDTO> fetchedProjects) {
 		Set<ProjectDTO> projects = new HashSet<ProjectDTO>(fetchedProjects);
 		for (final ProjectDTO projectDTO : projects) {
 			Set<ProjectParticipantDTO> combinedSet = new HashSet<ProjectParticipantDTO>();
-			
-			final Set<ProjectParticipantDTO> fetchedAuthors = fetchParticipants(new HashMap<String, String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor(){
+
+			final Set<ProjectParticipantDTO> fetchedAuthors = fetchParticipants(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 				@Override
-				String process(String url){
-					return(url+"/thesis/"+projectDTO.id+"/student");
+				String process(String url) {
+					return (url + "/thesis/" + projectDTO.id + "/student");
 				}
 			});
 			combinedSet.addAll(fetchedAuthors);
-			final Set<ProjectParticipantDTO> fetchedOtherParticipants = fetchParticipants(new HashMap<String, String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor(){
+			final Set<ProjectParticipantDTO> fetchedOtherParticipants = fetchParticipants(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
 				@Override
-				String process(String url){
-					return(url+"/thesis/"+projectDTO.id+"/contributor");
+				String process(String url) {
+					return (url + "/thesis/" + projectDTO.id + "/contributor");
 				}
 			});
 			combinedSet.addAll(fetchedOtherParticipants);
 			projectDTO.participants = combinedSet;
-			
+
 		}
 		return projects;
 	}
-	
+
 	/**
 	 * Small utility interface/default implementation used to preprocess DTO objects, intended for anonymous inner class-usage.
 	 */
-	private class UserDTOPreProcessor{
-		UserDTO process(UserDTO userDTO){
+	private class UserDTOPreProcessor {
+		UserDTO process(UserDTO userDTO) {
 			return userDTO;
 		}
 	}
-	private class ProjectDTOPreProcessor{
-		ProjectDTO process(ProjectDTO projectDTO){
-			return projectDTO;
-		}
-	}
-	private class UrlProcessor{
-		String process(String url){
+
+	private class UrlProcessor {
+		String process(String url) {
 			return url;
 		}
 	}
-	
+
 }
diff --git a/src/main/java/se/su/dsv/scipro/io/impl/ExternalImporterDefaultImpl.java b/src/main/java/se/su/dsv/scipro/io/impl/ExternalImporterDefaultImpl.java
index 2bc7b4b3ff..d846a80788 100644
--- a/src/main/java/se/su/dsv/scipro/io/impl/ExternalImporterDefaultImpl.java
+++ b/src/main/java/se/su/dsv/scipro/io/impl/ExternalImporterDefaultImpl.java
@@ -1,7 +1,6 @@
 package se.su.dsv.scipro.io.impl;
 
 import org.apache.log4j.Logger;
-
 import se.su.dsv.scipro.io.ExternalImporter;
 import se.su.dsv.scipro.io.exceptions.ExternalImportException;
 import se.su.dsv.scipro.security.auth.roles.Roles;
@@ -12,38 +11,51 @@ import se.su.dsv.scipro.security.auth.roles.Roles;
  */
 public class ExternalImporterDefaultImpl implements ExternalImporter {
 	private final Logger logger = Logger.getLogger(ExternalImporterDefaultImpl.class);
+
+	@Override
+	public String getLookupUrl() {
+		return "<not specified>";
+	}
+
 	@Override
 	public void importUser(final String userName, boolean includeLinkedEntities) {
-		logger.debug("Dummy implementation, the user: "+userName+" will not be imported");
+		logger.debug("Dummy implementation, the user: " + userName + " will not be imported");
 	}
+
 	@Override
 	public void importUser(final long externalIdentifier, boolean includeLinkedEntities) {
-		logger.debug("Dummy implementation, the user with identifier: "+externalIdentifier+" will not be imported");
+		logger.debug("Dummy implementation, the user with identifier: " + externalIdentifier + " will not be imported");
 	}
+
 	@Override
 	public void importUsersOfRole(final Roles role, boolean includeLinkedEntities) {
 		logger.debug("Dummy implementation, no users of role: " + role + " will be imported");
 	}
+
 	@Override
-	public void importProject(long externalIdentifier){
+	public void importProject(long externalIdentifier) {
 		logger.debug("Dummy implementation, no project with the id: " + externalIdentifier + " will be imported");
 	}
+
 	@Override
 	public void importProjects(String title) throws ExternalImportException {
 		logger.debug("Dummy implementation, no project matching the title: " + title + " will be imported");
 	}
+
 	@Override
 	public boolean supportsRemoteOperations() {
 		return false;
 	}
+
 	@Override
 	public void importSupervisorUnits() throws ExternalImportException {
 		// TODO Auto-generated method stub
 	}
+
 	@Override
 	public void importResearchAreas() throws ExternalImportException {
 		// TODO Auto-generated method stub
-		
+
 	}
 
 }
diff --git a/src/main/resources/applicationContext.xml b/src/main/resources/applicationContext.xml
index 0b972bbc05..5a4c578dfe 100644
--- a/src/main/resources/applicationContext.xml
+++ b/src/main/resources/applicationContext.xml
@@ -12,7 +12,7 @@
         http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
        default-autowire="byType">
 
-    <jpa:repositories base-package="se.su.dsv.scipro.springdata" />
+    <jpa:repositories base-package="se.su.dsv.scipro.springdata"/>
 
     <!-- Sets up spring autowire configuration based on annotations -->
     <context:annotation-config/>
@@ -63,13 +63,19 @@
     <!-- Load data initializer for default table-data -->
     <bean class="se.su.dsv.scipro.DataInitialiser" init-method="dataInit"/>
     <!-- Importer used for remote importing work, use "ExternalImporterDefaultImpl" if you have no remote-import implementation capable of satisfying "ExternalImporter" interface. -->
-    <bean id="externalImporter" class="se.su.dsv.scipro.io.impl.ExternalImporterDaisyImpl"/>
+    <bean id="externalImporter" class="se.su.dsv.scipro.io.impl.ExternalImporterDaisyImpl">
+        <property name="client" ref="dsvApiClient"/>
+    </bean>
+
+    <bean id="dsvApiClient" class="se.su.dsv.scipro.io.http.ApiClient">
+        <!-- This property points to the location of the remote system used for json requests -->
+        <property name="baseUrl" value="${remote.lookup.url}"/>
+        <property name="user" value="thesis"/>
+        <property name="password" value="dqyhIM8LU5LQ53T3aJNz4SVXeTQ95dLGkN7JlLOv7X7jeTR2NR"/>
+    </bean>
+
     <!-- Defines global settings for the application -->
     <bean id="applicationSettings" class="se.su.dsv.scipro.ApplicationSettings">
-        <property name="remoteLookupUrl" value="https://api.dsv.su.se/rest"/>
-        <property name="remoteLookupUser" value="thesis"/>
-        <property name="remoteLookupPassword" value="dqyhIM8LU5LQ53T3aJNz4SVXeTQ95dLGkN7JlLOv7X7jeTR2NR"/>
-        <!-- This property points to the location of the remote system used for json requests -->
         <!--  External auth support (via J2EE standard mechanism REMOTE_USER), if true: other authentication mechanics will be bypassed.-->
         <property name="acceptExternalAuthentication" value="true"/>
     </bean>