diff --git a/src/main/java/org/olat/core/servlets/HeadersFilter.java b/src/main/java/org/olat/core/servlets/HeadersFilter.java
index 413a22b480517f70e253b78028448a7a13e7ad51..b0df9635b57b369851ddd93a539256b6507aa371 100644
--- a/src/main/java/org/olat/core/servlets/HeadersFilter.java
+++ b/src/main/java/org/olat/core/servlets/HeadersFilter.java
@@ -31,6 +31,7 @@ import org.olat.modules.card2brain.Card2BrainModule;
 import org.olat.modules.edubase.EdubaseModule;
 import org.olat.modules.edusharing.EdusharingModule;
 import org.olat.modules.openmeetings.OpenMeetingsModule;
+import org.olat.modules.vitero.ViteroModule;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -45,6 +46,8 @@ public class HeadersFilter implements Filter {
 	@Autowired
 	private CSPModule securityModule;
 	@Autowired
+	private ViteroModule viteroModule;
+	@Autowired
 	private EdubaseModule edubaseModule;
 	@Autowired
 	private AnalyticsModule analyticsModule;
@@ -69,7 +72,8 @@ public class HeadersFilter implements Filter {
 	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
 		if(securityModule == null || edubaseModule != null
 				|| analyticsModule != null || card2BrainModule != null
-				|| openMeetingsModule != null|| edusharingModule != null) {
+				|| openMeetingsModule != null|| edusharingModule != null
+				|| viteroModule != null) {
 			CoreSpringFactory.autowireObject(this);
 		}
 		addSecurityHeaders(response);
@@ -214,6 +218,7 @@ public class HeadersFilter implements Filter {
 		appendCard2BrainUrl(sb);
 		appendEdubaseUrl(sb);
 		appendEdusharingUrl(sb);
+		appendViteroUrl(sb);
 		sb.append(";");
 	}
 	
@@ -277,6 +282,12 @@ public class HeadersFilter implements Filter {
 		}
 	}
 	
+	private void appendViteroUrl(StringBuilder sb) {
+		if(viteroModule != null && viteroModule.isEnabled()) {
+			appendUrl(sb, viteroModule.getVmsURI().toString());
+		}
+	}
+	
 	private void appendUrl(StringBuilder sb, String urlString) {
 		try {
 			URL url = new URL(urlString);
diff --git a/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java b/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java
index 325e871d0d94b8d34ec5199484e2d38ac8c28b24..ada7c640250d2e0ee78e675bd01679a23afa5f7a 100644
--- a/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java
+++ b/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java
@@ -23,6 +23,7 @@ import java.io.File;
 import java.io.StringWriter;
 import java.math.BigInteger;
 import java.net.ConnectException;
+import java.net.URI;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -156,6 +157,16 @@ public class ViteroManager implements UserDataDeletable {
 	private static final String VMS_CATEGORY = "vitero-category";
 	private static final String VMS_CATEGORY_ZOMBIE = "vitero-category-zombie";
 	
+	// We cache the ports because of Apache CXF (not the JAX-WS) implementation
+	// see: http://cxf.apache.org/faq.html#FAQ%2DAreJAX%2DWSclientproxiesthreadsafe%3F
+	// and because we only use one credential ( one user to access the service
+	private Mtom mtomWebService;
+	private Group groupWebService;
+	private Booking bookingWebService;
+	private Licence licenseWebService;
+	private SessionCode sessionCodeWebService;
+	private de.vitero.schema.user.User userWebService;
+	
 	@Autowired
 	private ViteroModule viteroModule;
 	@Autowired
@@ -1266,7 +1277,7 @@ public class ViteroManager implements UserDataDeletable {
 	public List<ViteroBooking> getBookings(BusinessGroup group, OLATResourceable ores, String subIdentifier)
 	throws VmsNotAvailableException {
 		List<Property> properties = propertyManager.listProperties(null, group, ores, VMS_CATEGORY, null);
-		List<ViteroBooking> bookings = new ArrayList<ViteroBooking>();
+		List<ViteroBooking> bookings = new ArrayList<>();
 		for(Property property:properties) {
 			String propIdentifier = property.getStringValue();
 			if((propIdentifier == null || subIdentifier == null)
@@ -1347,8 +1358,7 @@ public class ViteroManager implements UserDataDeletable {
 		try {
 			Bookingid bookingId = new Bookingid();
 			bookingId.setBookingid(id);
-			Bookingtype booking = getBookingWebService().getBookingById(bookingId);
-			return booking;
+			return getBookingWebService().getBookingById(bookingId);
 		} catch(SOAPFaultException f) {
 			ErrorCode code = handleAxisFault(f);
 			switch(code) {
@@ -1438,15 +1448,15 @@ public class ViteroManager implements UserDataDeletable {
 		try {
 			LicenceService ss = new LicenceService();
 	        ss.setHandlerResolver(new HandlerResolver() {
-						@SuppressWarnings("rawtypes")
-						@Override
-						public List<Handler> getHandlerChain(PortInfo portInfo) {
-							List<Handler> handlerList = new ArrayList<Handler>();
-							handlerList.add(new ViteroSecurityHandler(login, password));
-							return handlerList;
-						}
-	        	
+				@SuppressWarnings("rawtypes")
+				@Override
+				public List<Handler> getHandlerChain(PortInfo portInfo) {
+					List<Handler> handlerList = new ArrayList<>();
+					handlerList.add(new ViteroSecurityHandler(login, password));
+					return handlerList;
+				}
 	        });
+	        
 	        Licence port = ss.getLicenceSoap11();
 	        String endPoint = UriBuilder.fromUri(url).path("services").path("LicenseService").build().toString();
 	        ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPoint);
@@ -1524,7 +1534,7 @@ public class ViteroManager implements UserDataDeletable {
 		
 		if(f.getMessage() != null) {
 			if(sb.length() > 0) sb.append(" -> ");
-			sb.append(f.getMessage().toString());
+			sb.append(f.getMessage());
 		}
 		
 		if(StringHelper.containsNonWhitespace(f.getMessage())) {
@@ -1536,7 +1546,7 @@ public class ViteroManager implements UserDataDeletable {
 	}
 	
 	private final List<ViteroBooking> convert(List<Booking_Type> bookings) {
-		List<ViteroBooking> viteroBookings = new ArrayList<ViteroBooking>();
+		List<ViteroBooking> viteroBookings = new ArrayList<>();
 		
 		if(bookings != null && bookings.size() > 0) {
 			for(Booking_Type b:bookings) {
@@ -1576,7 +1586,7 @@ public class ViteroManager implements UserDataDeletable {
 	}
 	
 	private final List<ViteroUser> convertUsertype(List<Usertype> userTypes) {
-		List<ViteroUser> vUsers = new ArrayList<ViteroUser>();
+		List<ViteroUser> vUsers = new ArrayList<>();
 		if(userTypes != null) {
 			for(Usertype userType:userTypes) {
 				vUsers.add(convert(userType));
@@ -1625,7 +1635,7 @@ public class ViteroManager implements UserDataDeletable {
 	private final Property createProperty(final BusinessGroup group, final OLATResourceable courseResource, String subIdentifier, ViteroBooking booking) {
 		String serialized = serializeViteroBooking(booking);
 		String bookingId = Integer.toString(booking.getBookingId());
-		Long groupId = new Long(booking.getGroupId());
+		Long groupId = Long.valueOf(booking.getGroupId());
 		return propertyManager.createPropertyInstance(null, group, courseResource, VMS_CATEGORY, bookingId, null, groupId, subIdentifier, serialized);
 	}
 	
@@ -1647,58 +1657,106 @@ public class ViteroManager implements UserDataDeletable {
 	
 	//Factories for service stubs
 	private final  Booking getBookingWebService() {
+        if(bookingWebService != null && endPointMatch((BindingProvider)bookingWebService)) {
+        	return bookingWebService;
+        }
+		
 		BookingService ss = new BookingService();
         ss.setHandlerResolver(new VmsSecurityHandlerResolver());
         Booking port = ss.getBookingSoap11();
         String endPoint = getVmsEndPoint("BookingService");
         ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPoint);
+        bookingWebService = port;
 		return port;
 	}
 	
 	private final Licence getLicenceWebService() {
+        if(licenseWebService != null && endPointMatch((BindingProvider)licenseWebService)) {
+        	return licenseWebService;
+        }
+		
 		LicenceService ss = new LicenceService();
         ss.setHandlerResolver(new VmsSecurityHandlerResolver());
         Licence port = ss.getLicenceSoap11();
         String endPoint = getVmsEndPoint("LicenceService");
         ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPoint);
+        licenseWebService = port;
 		return port;
 	}
+
+
 	
 	private final Group getGroupWebService() {
+        if(groupWebService != null && endPointMatch((BindingProvider)groupWebService)) {
+        	return groupWebService;
+        }
+		
 		GroupService ss = new GroupService();
         ss.setHandlerResolver(new VmsSecurityHandlerResolver());
         Group port = ss.getGroupSoap11();
         String endPoint = getVmsEndPoint("GroupService");
         ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPoint);
+        groupWebService = port;
 		return port;
 	}
 	
 	private final de.vitero.schema.user.User getUserWebService() {
+        if(userWebService != null && endPointMatch((BindingProvider)userWebService)) {
+        	return userWebService;
+        }
+		
 		UserService ss = new UserService();
         ss.setHandlerResolver(new VmsSecurityHandlerResolver());
         de.vitero.schema.user.User port = ss.getUserSoap11();
         String endPoint = getVmsEndPoint("UserService");
         ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPoint);
+        userWebService = port;
 		return port;
 	}
 	
 	private final Mtom getMtomWebService() {
+        if(mtomWebService != null && endPointMatch((BindingProvider)mtomWebService)) {
+        	return mtomWebService;
+        }
+		
 		MtomService ss = new MtomService();
         ss.setHandlerResolver(new VmsSecurityHandlerResolver());
         Mtom port = ss.getMtomSoap11();
         String endPoint = getVmsEndPoint("MtomService");
         ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPoint);
+        mtomWebService = port;
 		return port;
 	}
 	
+	
 	private final SessionCode getSessionCodeWebService() {
+        if(sessionCodeWebService != null && endPointMatch((BindingProvider)sessionCodeWebService)) {
+        	return sessionCodeWebService;
+        }
+
+        String endPoint = getVmsEndPoint("SessionCodeService");
 		SessionCodeService ss = new SessionCodeService();
         ss.setHandlerResolver(new VmsSecurityHandlerResolver());
         SessionCode port = ss.getSessionCodeSoap11();
-        String endPoint = getVmsEndPoint("SessionCodeService");
         ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPoint);
+        sessionCodeWebService = port;
 		return port;
 	}
+	
+	/**
+	 * 
+	 * @param webservice The proxy to check
+	 * @return true if the proxy use the host configured in the module
+	 */
+	private boolean endPointMatch(BindingProvider webservice) {
+        Object endPoint = webservice.getRequestContext().get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
+        if(endPoint instanceof String) {
+        	URI configuredUri = viteroModule.getVmsURI();
+        	URI endpointUri = URI.create((String)endPoint);
+        	return endpointUri.getHost().equals(configuredUri.getHost());	
+        }
+        return false;
+	}
 
 	private final String getVmsEndPoint(String service) {
 	    UriBuilder builder = UriBuilder.fromUri(viteroModule.getVmsURI());
@@ -1742,7 +1800,7 @@ public class ViteroManager implements UserDataDeletable {
 		@SuppressWarnings("rawtypes")
 		@Override
 		public List<Handler> getHandlerChain(PortInfo portInfo) {
-			List<Handler> handlerList = new ArrayList<Handler>();
+			List<Handler> handlerList = new ArrayList<>();
 			handlerList.add(new ViteroSecurityHandler(viteroModule.getAdminLogin(), viteroModule.getAdminPassword()));
 			return handlerList;
 		}
diff --git a/src/main/java/org/olat/modules/vitero/ui/_content/opengroup.html b/src/main/java/org/olat/modules/vitero/ui/_content/opengroup.html
index 3e4e20065821beb869975dc3cb6e70d16779f818..427f0e20ead02b2346a90ed6e261afaf2721d044 100644
--- a/src/main/java/org/olat/modules/vitero/ui/_content/opengroup.html
+++ b/src/main/java/org/olat/modules/vitero/ui/_content/opengroup.html
@@ -1,3 +1,4 @@
 <div>
-	<iframe class=vitero_iframe src="$groupUrl"></iframe>
-</div>
\ No newline at end of file
+	<iframe class="vitero_iframe" src="$groupUrl"></iframe>
+</div>
+<div><a href="$groupUrl" target="_blanck"><i class="o_icon o_icon_content_popup"> </i> $r.translate("booking.group.alternate.url")</a></div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_de.properties
index 7f113eb57c5b958884f190cf7a31f151d67a265b..6ace44360881a01128aa41d6aca8c3774bc8bef8 100644
--- a/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_de.properties
@@ -37,6 +37,7 @@ booking.beginBuffer=Zeitpuffer vor Terminbeginn
 booking.end=Ende
 booking.endBuffer=Zeitpuffer nach Terminende
 booking.group=Datei Browser
+booking.group.alternate.url=Benutzen Sie dieser Link wenn der Dateibrowser nicht richtig angezeigt wird.
 booking.group.warning=Sie m\u00FCssen Teilnehmer dieses Meetings sein um Zugriff auf diese Dateien zu erhalten.
 booking.group.open=\u00D6ffnen
 booking.resource=Ressourcenname
diff --git a/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_en.properties
index 42fb1d920e522996ba5dd9de5e89241dd5440b93..f112437efa12d554ad02e6c1cc6a3c249cc760ee 100644
--- a/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_en.properties
@@ -8,6 +8,7 @@ booking.begin=Start
 booking.beginBuffer=Start buffer (minutes)
 booking.end=End
 booking.endBuffer=End buffer (minutes)
+booking.group.alternate.url=Use this link if the file browser doesn't appears correctly.
 booking.group=File browser
 booking.group.open=Open
 booking.group.warning=You need to be a participant of this group in order to open the file browser.
@@ -25,21 +26,6 @@ check.ok=The server connection and configuration test was successful. You can no
 check.users=Validate user
 check.users.nok=Validation fixed {2} problem.
 check.users.ok=Validation did not detect any problem
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 delete.confirm=Do you really want to delete the meeting? The meeting will also be removed on the vitero server and can not be restored.
 delete.nok=The meeting could not be deleted for unknown reasons. Please try again later or contact the administrator.
 delete.ok=The meeting has successfuly been deleted.
@@ -69,7 +55,6 @@ group.id=Group identifyer
 group.name=Title
 group.numOfParticipants=Booked seats
 group.open=File browser
-
 new=Create meeting
 new.booking.warning=The meeting settings are final and can not be modified later\!
 option.adminlogin=Web service user name
diff --git a/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_fr.properties
index 0f4ac2f950df696cfeef18f54efeb4abedba9fa2..883a9decf60093e60688e359c783520a3286e68e 100644
--- a/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/modules/vitero/ui/_i18n/LocalStrings_fr.properties
@@ -8,6 +8,7 @@ booking.begin=D\u00E9but
 booking.beginBuffer=Buffer de d\u00E9but (minutes)
 booking.end=Fin
 booking.endBuffer=Buffer de fin (minutes)
+booking.group.alternate.url=Utilisez ce lien si le navigateur de fichiers n'appara\u00EEt pas correctement.
 booking.group=Navigateur de fichiers
 booking.group.open=Ouvrir
 booking.group.warning=Vous devez \u00EAtre un participant de cette r\u00E9union pour avoir acc\u00E8s aux documents qu'elle contient.
@@ -25,21 +26,6 @@ check.ok=Le test de la connection a \u00E9t\u00E9 couronn\u00E9 de succ\u00E8s.
 check.users=Contr\u00F4ler les utilisateurs
 check.users.nok=Le contr\u00F4le des utilisateurs a r\u00E9solu {0} probl\u00E8mes.
 check.users.ok=Le contr\u00F4le des utilisateurs n'a pas trouv\u00E9 de probl\u00E8mes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 delete.confirm=Voulez-vous vraiment supprimer ce rendez-vous? Le rendez-vous sera supprim\u00E9 du syst\u00E8me vitero et ne pourra \u00EAtre restaur\u00E9.
 delete.nok=Le rendez-vous n'a pas pu \u00EAtre supprim\u00E9 pour des raisons ind\u00E9termin\u00E9es. Essayez un peu plus tard ou contactez un administrateur.
 delete.ok=Le rendez-vous a \u00E9t\u00E9 supprim\u00E9 avec succ\u00E8s.
@@ -69,7 +55,6 @@ group.id=Identification du groupe
 group.name=Titre
 group.numOfParticipants=Nombre de participants
 group.open=Navigateur de documents
-
 new=Cr\u00E9er un rendez-vous
 new.booking.warning=Les donn\u00E9es ne peuvent plus \u00EAtre chang\u00E9es\!
 option.adminlogin=Nom d'utilisateur du Web Service