gt: 			throw new UserException("Name required");
context: package org.bimserver.webservices.impl;
  
  /******************************************************************************
   * Copyright (C) 2009-2019  BIMserver.org
   * 
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Affero General Public License as
   * published by the Free Software Foundation, either version 3 of the
   * License, or (at your option) any later version.
   * 
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU Affero General Public License for more details.
   * 
   * You should have received a copy of the GNU Affero General Public License
   * along with this program.  If not, see {@literal<http://www.gnu.org/licenses/>}.
   *****************************************************************************/
  
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.io.UnsupportedEncodingException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URLConnection;
  import java.net.URLDecoder;
  import java.nio.file.FileAlreadyExistsException;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Comparator;
  import java.util.Date;
  import java.util.HashSet;
  import java.util.LinkedHashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.concurrent.atomic.AtomicInteger;
  
  import javax.activation.DataHandler;
  import javax.activation.DataSource;
  import javax.mail.Message;
  import javax.mail.MessagingException;
  import javax.mail.internet.AddressException;
  import javax.mail.internet.InternetAddress;
  import javax.mail.util.ByteArrayDataSource;
  
  import org.apache.commons.collections.comparators.ComparatorChain;
  import org.apache.http.Header;
  import org.apache.http.client.methods.CloseableHttpResponse;
  import org.apache.http.client.methods.HttpPost;
  import org.apache.http.entity.ByteArrayEntity;
  import org.apache.http.impl.client.CloseableHttpClient;
  import org.apache.http.impl.client.HttpClients;
  import org.bimserver.BimServerImporter;
  import org.bimserver.BimserverDatabaseException;
  import org.bimserver.client.json.JsonBimServerClientFactory;
  import org.bimserver.database.DatabaseSession;
  import org.bimserver.database.OldQuery;
  import org.bimserver.database.OperationType;
  import org.bimserver.database.actions.AddExtendedDataSchemaDatabaseAction;
  import org.bimserver.database.actions.AddExtendedDataToProjectDatabaseAction;
  import org.bimserver.database.actions.AddExtendedDataToRevisionDatabaseAction;
  import org.bimserver.database.actions.AddLocalServiceToProjectDatabaseAction;
  import org.bimserver.database.actions.AddModelCheckerDatabaseAction;
  import org.bimserver.database.actions.AddModelCheckerToProjectDatabaseAction;
  import org.bimserver.database.actions.AddNewServiceToProjectDatabaseAction;
  import org.bimserver.database.actions.AddProjectDatabaseAction;
  import org.bimserver.database.actions.AddServiceToProjectDatabaseAction;
  import org.bimserver.database.actions.AddUserDatabaseAction;
  import org.bimserver.database.actions.AddUserToExtendedDataSchemaDatabaseAction;
  import org.bimserver.database.actions.AddUserToProjectDatabaseAction;
  import org.bimserver.database.actions.BimDatabaseAction;
  import org.bimserver.database.actions.BranchToExistingProjectDatabaseAction;
  import org.bimserver.database.actions.BranchToNewProjectDatabaseAction;
  import org.bimserver.database.actions.ChangeUserTypeDatabaseAction;
  import org.bimserver.database.actions.CheckinDatabaseAction;
  import org.bimserver.database.actions.CloneToNewProjectDatabaseAction;
  import org.bimserver.database.actions.CompareDatabaseAction;
  import org.bimserver.database.actions.DeleteProjectDatabaseAction;
  import org.bimserver.database.actions.DeleteServiceDatabaseAction;
  import org.bimserver.database.actions.DeleteUserDatabaseAction;
  import org.bimserver.database.actions.GetAllAuthorizedUsersOfProjectDatabaseAction;
  import org.bimserver.database.actions.GetAllCheckoutsByUserDatabaseAction;
  import org.bimserver.database.actions.GetAllCheckoutsOfProjectDatabaseAction;
  import org.bimserver.database.actions.GetAllCheckoutsOfRevisionDatabaseAction;
  import org.bimserver.database.actions.GetAllExtendedDataSchemasDatabaseAction;
  import org.bimserver.database.actions.GetAllModelCheckersDatabaseAction;
  import org.bimserver.database.actions.GetAllNewServicesOfProjectDatabaseAction;
  import org.bimserver.database.actions.GetAllNonAuthorizedProjectsOfUserDatabaseAction;
  import org.bimserver.database.actions.GetAllNonAuthorizedUsersOfProjectDatabaseAction;
  import org.bimserver.database.actions.GetAllProjectsDatabaseAction;
  import org.bimserver.database.actions.GetAllProjectsSmallDatabaseAction;
  import org.bimserver.database.actions.GetAllReadableProjectsDatabaseAction;
  import org.bimserver.database.actions.GetAllRelatedProjectsDatabaseAction;
  import org.bimserver.database.actions.GetAllRevisionsByUserDatabaseAction;
  import org.bimserver.database.actions.GetAllRevisionsOfProjectDatabaseAction;
  import org.bimserver.database.actions.GetAllServicesOfProjectDatabaseAction;
  import org.bimserver.database.actions.GetAllUsersDatabaseAction;
  import org.bimserver.database.actions.GetAllWritableProjectsDatabaseAction;
  import org.bimserver.database.actions.GetAreaDatabaseAction;
  import org.bimserver.database.actions.GetAvailableClassesDatabaseAction;
  import org.bimserver.database.actions.GetAvailableClassesInRevisionDatabaseAction;
  import org.bimserver.database.actions.GetCheckinWarningsDatabaseAction;
  import org.bimserver.database.actions.GetCheckoutWarningsDatabaseAction;
  import org.bimserver.database.actions.GetDeserializerByIdDatabaseAction;
  import org.bimserver.database.actions.GetDeserializerByNameDatabaseAction;
  import org.bimserver.database.actions.GetExtendedDataByIdDatabaseAction;
  import org.bimserver.database.actions.GetExtendedDataSchemaByIdDatabaseAction;
  import org.bimserver.database.actions.GetExtendedDataSchemaByNameDatabaseAction;
  import org.bimserver.database.actions.GetGeoTagDatabaseAction;
  import org.bimserver.database.actions.GetGeometryInfoDatabaseAction;
  import org.bimserver.database.actions.GetIfcHeaderDatabaseAction;
  import org.bimserver.database.actions.GetModelCheckerOidDatabaseAction;
  import org.bimserver.database.actions.GetNrPrimitivesDatabaseAction;
  import org.bimserver.database.actions.GetNrPrimitivesTotalDatabaseAction;
  import org.bimserver.database.actions.GetOidByGuidDatabaseAction;
  import org.bimserver.database.actions.GetProjectByPoidDatabaseAction;
  import org.bimserver.database.actions.GetProjectByUuidDatabaseAction;
  import org.bimserver.database.actions.GetProjectsByNameDatabaseAction;
  import org.bimserver.database.actions.GetProjectsOfUserDatabaseAction;
  import org.bimserver.database.actions.GetQueryEngineByIdDatabaseAction;
  import org.bimserver.database.actions.GetQueryEngineByNameDatabaseAction;
  import org.bimserver.database.actions.GetRevisionDatabaseAction;
  import org.bimserver.database.actions.GetRevisionSummaryDatabaseAction;
  import org.bimserver.database.actions.GetSerializerByContentTypeDatabaseAction;
  import org.bimserver.database.actions.GetSerializerByIdDatabaseAction;
  import org.bimserver.database.actions.GetSerializerByNameDatabaseAction;
  import org.bimserver.database.actions.GetSubProjectByNameDatabaseAction;
  import org.bimserver.database.actions.GetSubProjectsDatabaseAction;
  import org.bimserver.database.actions.GetTopLevelProjectByNameDatabaseAction;
  import org.bimserver.database.actions.GetUserByUoidDatabaseAction;
  import org.bimserver.database.actions.GetUserByUserNameDatabaseAction;
  import org.bimserver.database.actions.GetVolumeDatabaseAction;
  import org.bimserver.database.actions.RegenerateGeometryDatabaseAction;
  import org.bimserver.database.actions.RemoveModelCheckerFromProjectDatabaseAction;
  import org.bimserver.database.actions.RemoveNewServiceFromProjectDatabaseAction;
  import org.bimserver.database.actions.RemoveServiceFromProjectDatabaseAction;
  import org.bimserver.database.actions.RemoveUserFromExtendedDataSchemaDatabaseAction;
  import org.bimserver.database.actions.RemoveUserFromProjectDatabaseAction;
  import org.bimserver.database.actions.SetRevisionTagDatabaseAction;
  import org.bimserver.database.actions.StreamingCheckinDatabaseAction;
  import org.bimserver.database.actions.UndeleteProjectDatabaseAction;
  import org.bimserver.database.actions.UndeleteUserDatabaseAction;
  import org.bimserver.database.actions.UpdateGeoTagDatabaseAction;
  import org.bimserver.database.actions.UpdateModelCheckerDatabaseAction;
  import org.bimserver.database.actions.UpdateProjectDatabaseAction;
  import org.bimserver.database.actions.UpdateRevisionDatabaseAction;
  import org.bimserver.database.actions.UploadFileDatabaseAction;
  import org.bimserver.database.actions.UserHasCheckinRightsDatabaseAction;
  import org.bimserver.database.actions.UserHasRightsDatabaseAction;
  import org.bimserver.database.actions.ValidateModelCheckerDatabaseAction;
  import org.bimserver.database.queries.om.DefaultQueries;
  import org.bimserver.database.queries.om.JsonQueryObjectModelConverter;
  import org.bimserver.database.queries.om.Query;
  import org.bimserver.database.query.conditions.AttributeCondition;
  import org.bimserver.database.query.conditions.Condition;
  import org.bimserver.database.query.literals.StringLiteral;
  import org.bimserver.emf.IdEObject;
  import org.bimserver.emf.IfcModelInterface;
  import org.bimserver.emf.PackageMetaData;
  import org.bimserver.emf.Schema;
  import org.bimserver.geometry.accellerator.Node;
  import org.bimserver.geometry.accellerator.NodeCounter;
  import org.bimserver.geometry.accellerator.Octree;
  import org.bimserver.interfaces.objects.SAccessMethod;
  import org.bimserver.interfaces.objects.SAction;
  import org.bimserver.interfaces.objects.SBounds;
  import org.bimserver.interfaces.objects.SCheckout;
  import org.bimserver.interfaces.objects.SCheckoutResult;
  import org.bimserver.interfaces.objects.SCompareResult;
  import org.bimserver.interfaces.objects.SCompareType;
  import org.bimserver.interfaces.objects.SDensity;
  import org.bimserver.interfaces.objects.SDeserializerPluginConfiguration;
  import org.bimserver.interfaces.objects.SDownloadResult;
  import org.bimserver.interfaces.objects.SExtendedData;
  import org.bimserver.interfaces.objects.SExtendedDataAddedToRevision;
  import org.bimserver.interfaces.objects.SExtendedDataSchema;
  import org.bimserver.interfaces.objects.SFile;
  import org.bimserver.interfaces.objects.SGeoTag;
  import org.bimserver.interfaces.objects.SGeometryInfo;
  import org.bimserver.interfaces.objects.SIfcHeader;
  import org.bimserver.interfaces.objects.SLogAction;
  import org.bimserver.interfaces.objects.SLongActionState;
  import org.bimserver.interfaces.objects.SLongCheckinActionState;
  import org.bimserver.interfaces.objects.SModelCheckerInstance;
  import org.bimserver.interfaces.objects.SNewService;
  import org.bimserver.interfaces.objects.SPluginDescriptor;
  import org.bimserver.interfaces.objects.SProfileDescriptor;
  import org.bimserver.interfaces.objects.SProgressTopicType;
  import org.bimserver.interfaces.objects.SProject;
  import org.bimserver.interfaces.objects.SProjectSmall;
  import org.bimserver.interfaces.objects.SQueryEnginePluginConfiguration;
  import org.bimserver.interfaces.objects.SRevision;
  import org.bimserver.interfaces.objects.SRevisionSummary;
  import org.bimserver.interfaces.objects.SSerializerPluginConfiguration;
  import org.bimserver.interfaces.objects.SServiceDescriptor;
  import org.bimserver.interfaces.objects.STile;
  import org.bimserver.interfaces.objects.STrigger;
  import org.bimserver.interfaces.objects.SUser;
  import org.bimserver.interfaces.objects.SUserSettings;
  import org.bimserver.interfaces.objects.SUserType;
  import org.bimserver.interfaces.objects.SVector3f;
  import org.bimserver.longaction.CannotBeScheduledException;
  import org.bimserver.longaction.DownloadParameters;
  import org.bimserver.longaction.DownloadParameters.DownloadType;
  import org.bimserver.longaction.LongAction;
  import org.bimserver.longaction.LongBranchAction;
  import org.bimserver.longaction.LongCheckinAction;
  import org.bimserver.longaction.LongCheckoutAction;
  import org.bimserver.longaction.LongCopyAction;
  import org.bimserver.longaction.LongDownloadAction;
  import org.bimserver.longaction.LongDownloadOrCheckoutAction;
  import org.bimserver.longaction.LongGenericAction;
  import org.bimserver.longaction.LongStreamingCheckinAction;
  import org.bimserver.longaction.LongStreamingDownloadAction;
  import org.bimserver.mail.EmailMessage;
  import org.bimserver.mail.MailSystem;
  import org.bimserver.models.geometry.Bounds;
  import org.bimserver.models.geometry.Vector3f;
  import org.bimserver.models.log.LogAction;
  import org.bimserver.models.store.Action;
  import org.bimserver.models.store.CheckinRevision;
  import org.bimserver.models.store.Checkout;
  import org.bimserver.models.store.CompareResult;
  import org.bimserver.models.store.ConcreteRevision;
  import org.bimserver.models.store.DeserializerPluginConfiguration;
  import org.bimserver.models.store.ExtendedData;
  import org.bimserver.models.store.ExtendedDataSchema;
  import org.bimserver.models.store.File;
  import org.bimserver.models.store.GeoTag;
  import org.bimserver.models.store.InternalServicePluginConfiguration;
  import org.bimserver.models.store.ModelCheckerInstance;
  import org.bimserver.models.store.NewService;
  import org.bimserver.models.store.OAuthAuthorizationCode;
  import org.bimserver.models.store.OAuthServer;
  import org.bimserver.models.store.ObjectState;
  import org.bimserver.models.store.PluginBundleVersion;
  import org.bimserver.models.store.Project;
  import org.bimserver.models.store.Revision;
  import org.bimserver.models.store.RevisionSummary;
  import org.bimserver.models.store.SerializerPluginConfiguration;
  import org.bimserver.models.store.Service;
  import org.bimserver.models.store.ServiceDescriptor;
  import org.bimserver.models.store.StoreExtendedData;
  import org.bimserver.models.store.StorePackage;
  import org.bimserver.models.store.User;
  import org.bimserver.models.store.UserSettings;
  import org.bimserver.models.store.UserType;
  import org.bimserver.notifications.NewExtendedDataOnRevisionNotification;
  import org.bimserver.notifications.NewRevisionNotification;
  import org.bimserver.notifications.ProgressOnProjectTopic;
  import org.bimserver.notifications.ProgressTopic;
  import org.bimserver.plugins.Plugin;
  import org.bimserver.plugins.deserializers.DeserializeException;
  import org.bimserver.plugins.deserializers.Deserializer;
  import org.bimserver.plugins.deserializers.DeserializerPlugin;
  import org.bimserver.plugins.deserializers.IfcSchemaDeterminer;
  import org.bimserver.plugins.deserializers.StreamingDeserializer;
  import org.bimserver.plugins.deserializers.StreamingDeserializerPlugin;
  import org.bimserver.plugins.queryengine.QueryEnginePlugin;
  import org.bimserver.plugins.serializers.ExtendedDataSource;
  import org.bimserver.plugins.serializers.MessagingSerializerPlugin;
  import org.bimserver.plugins.serializers.MessagingStreamingSerializerPlugin;
  import org.bimserver.plugins.serializers.SerializerException;
  import org.bimserver.plugins.serializers.SerializerPlugin;
  import org.bimserver.plugins.serializers.StreamingSerializerPlugin;
  import org.bimserver.plugins.services.BimServerClientInterface;
  import org.bimserver.shared.BimServerClientFactory;
  import org.bimserver.shared.compare.CompareWriter;
  import org.bimserver.shared.exceptions.PluginException;
  import org.bimserver.shared.exceptions.ServerException;
  import org.bimserver.shared.exceptions.ServiceException;
  import org.bimserver.shared.exceptions.UserException;
  import org.bimserver.shared.interfaces.ServiceInterface;
  import org.bimserver.shared.interfaces.SettingsInterface;
  import org.bimserver.utils.MultiplexingInputStream;
  import org.bimserver.utils.NetUtils;
  import org.bimserver.webservices.CheckoutComparator;
  import org.bimserver.webservices.SNewServiceComparator;
  import org.bimserver.webservices.SProjectComparator;
  import org.bimserver.webservices.SRevisionComparator;
  import org.bimserver.webservices.SServiceComparator;
  import org.bimserver.webservices.SUserComparator;
  import org.bimserver.webservices.ServiceMap;
  import org.bimserver.webservices.authorization.ExplicitRightsAuthorization;
  import org.codehaus.jettison.json.JSONArray;
  import org.codehaus.jettison.json.JSONObject;
  import org.codehaus.jettison.json.JSONTokener;
  import org.eclipse.emf.common.util.EList;
  import org.opensourcebim.bcf.BcfException;
  import org.opensourcebim.bcf.BcfFile;
  import org.opensourcebim.bcf.ReadOptions;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import com.google.common.base.Charsets;
  import com.google.common.io.ByteStreams;
  
  public class ServiceImpl extends GenericServiceImpl implements ServiceInterface {
  	private static final Logger LOGGER = LoggerFactory.getLogger(ServiceImpl.class);
  
  	@Override
  	public Long checkout(Long roid, Long serializerOid, Boolean sync) throws ServerException, UserException {
  		requireAuthenticationAndRunningServer();
  		getAuthorization().canDownload(roid);
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		User user = null;
  		try {
  			SerializerPluginConfiguration serializerPluginConfiguration = (SerializerPluginConfiguration) session.get(serializerOid, OldQuery.getDefault());
  //			org.bimserver.plugins.serializers.Serializer serializer = getBimServer().getEmfSerializerFactory().get(serializerOid).createSerializer(new org.bimserver.plugins.serializers.PluginConfiguration());
  			if (serializerPluginConfiguration == null) {
  				throw new UserException("No serializer with id " + serializerOid + " could be found");
  			}
  			if (!serializerPluginConfiguration.getPluginDescriptor().getPluginClassName().equals("org.bimserver.ifc.step.serializer.Ifc4StepSerializerPlugin")
  					&& !serializerPluginConfiguration.getPluginDescriptor().getPluginClassName().equals("org.bimserver.ifc.step.serializer.Ifc2x3tc1StepSerializerPlugin")) {
  				throw new UserException("Only IFC allowed when checking out");
  			}
  			DownloadParameters downloadParameters = new DownloadParameters(getBimServer(), DownloadType.DOWNLOAD_PROJECTS);
  			downloadParameters.setRoid(roid);
  			downloadParameters.setSerializerOid(serializerOid);
  
  			user = (User) session.get(StorePackage.eINSTANCE.getUser(), getAuthorization().getUoid(), OldQuery.getDefault());
  			LongDownloadOrCheckoutAction longDownloadAction = new LongCheckoutAction(getBimServer(), user.getName(), user.getUsername(), downloadParameters, getAuthorization(), getInternalAccessMethod());
  			try {
  				getBimServer().getLongActionManager().start(longDownloadAction);
  			} catch (CannotBeScheduledException e) {
  				LOGGER.error("", e);
  			}
  			if (sync) {
  				longDownloadAction.waitForCompletion();
  			}
  			return longDownloadAction.getProgressTopic().getKey().getId();
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public void terminateLongRunningAction(Long topicId) throws ServerException, UserException {
  		LongAction<?> longAction = getBimServer().getLongActionManager().getLongAction(topicId);
  		if (longAction != null) {
  			longAction.terminate();
  		} else {
  			throw new UserException("No data found for topicId " + topicId);
  		}
  	}
  
  	@Override
  	public SDownloadResult getDownloadData(final Long topicId) throws ServerException, UserException {
  		LongAction<?> longAction = getBimServer().getLongActionManager().getLongAction(topicId);
  		if (longAction == null) {
  			throw new UserException("No data found for topicId " + topicId);
  		}
  		if (longAction instanceof LongStreamingDownloadAction) {
  			LongStreamingDownloadAction longStreamingDownloadAction = (LongStreamingDownloadAction) longAction;
  			if (longStreamingDownloadAction.getErrors().isEmpty()) {
  				SCheckoutResult result;
  				try {
  					result = longStreamingDownloadAction.getCheckoutResult();
  				} catch (SerializerException e) {
  					throw new UserException(e);
  				}
  				return result;
  			} else {
  				LOGGER.error(longStreamingDownloadAction.getErrors().get(0));
  				throw new ServerException(longStreamingDownloadAction.getErrors().get(0));
  			}
  		} else {
  			LongDownloadOrCheckoutAction longDownloadAction = (LongDownloadOrCheckoutAction) longAction;
  			try {
  				longDownloadAction.waitForCompletion();
  				if (longDownloadAction.getErrors().isEmpty()) {
  					SCheckoutResult result = longDownloadAction.getCheckoutResult();
  					return result;
  				} else {
  					LOGGER.error(longDownloadAction.getErrors().get(0));
  					throw new ServerException(longDownloadAction.getErrors().get(0));
  				}
  			} catch (Exception e) {
  				LOGGER.error("", e);
  				throw new ServerException(e);
  			}
  		}
  	}
  
  	public Long download(DownloadParameters downloadParameters, Boolean sync) throws ServerException, UserException {
  		requireAuthenticationAndRunningServer();
  		User user = null;
  		for (long roid : downloadParameters.getRoids()) {
  			getAuthorization().canDownload(roid);
  		}
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			user = (User) session.get(StorePackage.eINSTANCE.getUser(), getAuthorization().getUoid(), OldQuery.getDefault());
  		} catch (BimserverDatabaseException e) {
  			throw new UserException(e);
  		} finally {
  			session.close();
  		}
  		LongDownloadOrCheckoutAction longDownloadAction = new LongDownloadAction(getBimServer(), user == null ? "Unknown" : user.getName(), user == null ? "Unknown" : user.getUsername(), downloadParameters, getAuthorization(),
  				getInternalAccessMethod());
  		try {
  			getBimServer().getLongActionManager().start(longDownloadAction);
  		} catch (Exception e) {
  			LOGGER.error("", e);
  		}
  		if (sync) {
  			longDownloadAction.waitForCompletion();
  		}
  		return longDownloadAction.getProgressTopic().getKey().getId();
  	}
  
  	@Override
  	public Long download(Set<Long> roids, String jsonQuery, Long serializerOid, Boolean sync) throws ServerException, UserException {
  		try {
  			String username = getAuthorization().getUsername();
  			DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  			Plugin plugin = null;
  			try {
  				SerializerPluginConfiguration serializerPluginConfiguration = session.get(StorePackage.eINSTANCE.getSerializerPluginConfiguration(), serializerOid, OldQuery.getDefault());
  				plugin = getBimServer().getPluginManager().getPlugin(serializerPluginConfiguration.getPluginDescriptor().getPluginClassName(), true);
  			} catch (BimserverDatabaseException e) {
  				throw new UserException(e);
  			} finally {
  				session.close();
  			}
  
  			if (plugin instanceof StreamingSerializerPlugin || plugin instanceof MessagingStreamingSerializerPlugin) {
  				LongStreamingDownloadAction longDownloadAction = new LongStreamingDownloadAction(getBimServer(), username, username, getAuthorization(), serializerOid, jsonQuery, roids);
  				try {
  					getBimServer().getLongActionManager().start(longDownloadAction);
  				} catch (Exception e) {
  					LOGGER.error("", e);
  				}
  				if (sync) {
  					longDownloadAction.waitForCompletion();
  				}
  				return longDownloadAction.getProgressTopic().getKey().getId();
  			} else if (plugin instanceof MessagingSerializerPlugin) {
  				requireAuthenticationAndRunningServer();
  				DownloadParameters downloadParameters = new DownloadParameters(getBimServer(), DownloadType.DOWNLOAD_BY_NEW_JSON_QUERY);
  				downloadParameters.setRoids(roids);
  				downloadParameters.setJsonQuery(jsonQuery);
  				downloadParameters.setSerializerOid(serializerOid);
  				return download(downloadParameters, sync);
  			} else if (plugin instanceof SerializerPlugin) {
  				requireAuthenticationAndRunningServer();
  				DownloadParameters downloadParameters = new DownloadParameters(getBimServer(), DownloadType.DOWNLOAD_BY_NEW_JSON_QUERY);
  				downloadParameters.setRoids(roids);
  				downloadParameters.setJsonQuery(jsonQuery);
  				downloadParameters.setSerializerOid(serializerOid);
  				return download(downloadParameters, sync);
  			} else {
  				throw new UserException("Unimplemented type of plugin: " + plugin);
  			}
  		} catch (Exception e) {
  			return handleException(e);
  		}
  	}
  
  	@Override
  	public SSerializerPluginConfiguration getSerializerByName(String serializerName) throws ServerException, UserException {
  		requireAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(new GetSerializerByNameDatabaseAction(session, getInternalAccessMethod(), serializerName)));
  		} catch (Exception e) {
  			handleException(e);
  		} finally {
  			session.close();
  		}
  		return null;
  	}
  
  	@Override
  	public SDeserializerPluginConfiguration getDeserializerByName(String deserializerName) throws ServerException, UserException {
  		requireAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(new GetDeserializerByNameDatabaseAction(session, getInternalAccessMethod(), deserializerName)));
  		} catch (Exception e) {
  			handleException(e);
  		} finally {
  			session.close();
  		}
  		return null;
  	}
  
  	@Override
  	public SDeserializerPluginConfiguration getDeserializerById(Long oid) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(new GetDeserializerByIdDatabaseAction(session, getInternalAccessMethod(), oid)));
  		} catch (Exception e) {
  			handleException(e);
  		} finally {
  			session.close();
  		}
  		return null;
  	}
  
  	@Override
  	public SQueryEnginePluginConfiguration getQueryEngineByName(String name) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(new GetQueryEngineByNameDatabaseAction(session, getInternalAccessMethod(), name)));
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public SQueryEnginePluginConfiguration getQueryEngineById(Long oid) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(new GetQueryEngineByIdDatabaseAction(session, getInternalAccessMethod(), oid)));
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public SSerializerPluginConfiguration getSerializerById(Long oid) throws ServerException, UserException {
  		requireAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(new GetSerializerByIdDatabaseAction(session, getInternalAccessMethod(), oid)));
  		} catch (Exception e) {
  			handleException(e);
  		} finally {
  			session.close();
  		}
  		return null;
  	}
  
  	@Override
  	public SSerializerPluginConfiguration getSerializerByContentType(String contentType) throws ServerException, UserException {
  		// Not checking for real authentication here because a remote service should be
  		// able to use a serializer for download call
  		requireAuthenticationAndRunningServer();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(new GetSerializerByContentTypeDatabaseAction(getBimServer(), session, getInternalAccessMethod(), contentType)));
  		} catch (Exception e) {
  			handleException(e);
  		} finally {
  			session.close();
  		}
  		return null;
  	}
  
  	@Override
  	public SDeserializerPluginConfiguration getSuggestedDeserializerForExtension(String extension, Long poid) throws ServerException, UserException {
  		if (extension.startsWith(".")) {
  			extension = extension.substring(1);
  		}
  		// Token authenticated users should also be able to call this method
  		try {
  			requireAuthenticationAndRunningServer();
  			DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  			List<DeserializerPluginConfiguration> list = new ArrayList<>();
  			try {
  				Project project = session.get(poid, OldQuery.getDefault());
  				UserSettings userSettings = getUserSettings(session);
  				for (DeserializerPluginConfiguration deserializer : userSettings.getDeserializers()) {
  					Plugin plugin = getBimServer().getPluginManager().getPlugin(deserializer.getPluginDescriptor().getIdentifier(), true);
  					if (plugin instanceof DeserializerPlugin) {
  						DeserializerPlugin deserializerPlugin = (DeserializerPlugin) plugin;
  						if (deserializerPlugin.getSupportedSchemas().contains(Schema.valueOf(project.getSchema().toUpperCase()))) {
  							if (deserializerPlugin.canHandleExtension(extension)) {
  								list.add(deserializer);
  							}
  						}
  					} else if (plugin instanceof StreamingDeserializerPlugin) {
  						StreamingDeserializerPlugin streamingDeserializerPlugin = (StreamingDeserializerPlugin) plugin;
  						if (streamingDeserializerPlugin.getSupportedSchemas().contains(Schema.valueOf(project.getSchema().toUpperCase()))) {
  							if (streamingDeserializerPlugin.canHandleExtension(extension)) {
  								list.add(deserializer);
  							}
  						}
  					}
  				}
  			} finally {
  				session.close();
  			}
  			if (list.size() == 1) {
  				return getBimServer().getSConverter().convertToSObject(list.get(0));
  			} else if (list.size() > 1) {
  				for (DeserializerPluginConfiguration deserializerPluginConfiguration : list) {
  					Plugin plugin = getBimServer().getPluginManager().getPlugin(deserializerPluginConfiguration.getPluginDescriptor().getIdentifier(), true);
  					// Prefer the streaming version
  					if (plugin instanceof StreamingDeserializerPlugin) {
  						return getBimServer().getSConverter().convertToSObject(deserializerPluginConfiguration);
  					}
  				}
  				// Just return the first one
  				return getBimServer().getSConverter().convertToSObject(list.get(0));
  			}
  		} catch (Exception e) {
  			return handleException(e);
  		}
  		return null;
  	}
  
  	@Override
  	public void addExtendedDataToRevision(Long roid, SExtendedData extendedData) throws ServerException, UserException {
  		requireAuthenticationAndRunningServer();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.POSSIBLY_WRITE);
  		try {
  			ExtendedData convert = getBimServer().getSConverter().convertFromSObject(extendedData, session.create(ExtendedData.class), session);
  			session.executeAndCommitAction(new AddExtendedDataToRevisionDatabaseAction(getBimServer(), session, getInternalAccessMethod(), roid, getAuthorization(), convert));
  		} catch (Exception e) {
  			handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public SExtendedDataSchema getExtendedDataSchemaById(Long oid) throws ServerException, UserException {
  		requireAuthenticationAndRunningServer();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(new GetExtendedDataSchemaByIdDatabaseAction(session, getInternalAccessMethod(), oid)));
  		} catch (Exception e) {
  			handleException(e);
  		} finally {
  			session.close();
  		}
  		return null;
  	}
  
  	@Override
  	public SExtendedData getExtendedData(Long oid) throws ServerException, UserException {
  		requireAuthenticationAndRunningServer();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(new GetExtendedDataByIdDatabaseAction(session, getInternalAccessMethod(), getAuthorization(), oid)));
  		} catch (Exception e) {
  			handleException(e);
  		} finally {
  			session.close();
  		}
  		return null;
  	}
  
  	@Override
  	public SRevision getRevision(Long roid) throws ServerException, UserException {
  		requireAuthenticationAndRunningServer();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			BimDatabaseAction<Revision> action = new GetRevisionDatabaseAction(session, getInternalAccessMethod(), roid, getAuthorization());
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(action));
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public SProject addProjectAsSubProject(String projectName, Long parentPoid, String schema) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.POSSIBLY_WRITE);
  		try {
  			BimDatabaseAction<Project> action = new AddProjectDatabaseAction(getBimServer(), session, getInternalAccessMethod(), projectName, parentPoid, schema, getAuthorization());
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(action));
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public Long clone(Long roid, String projectName, String comment, Boolean sync) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.POSSIBLY_WRITE);
  		try {
  			CloneToNewProjectDatabaseAction action = new CloneToNewProjectDatabaseAction(session, getInternalAccessMethod(), getBimServer(), getAuthorization(), roid, projectName, comment);
  			User user = (User) session.get(StorePackage.eINSTANCE.getUser(), getAuthorization().getUoid(), OldQuery.getDefault());
  			String username = user.getName();
  			String userUsername = user.getUsername();
  			LongCopyAction longAction = new LongCopyAction(getBimServer(), username, userUsername, getAuthorization(), action);
  			getBimServer().getLongActionManager().start(longAction);
  			if (sync) {
  				longAction.waitForCompletion();
  			}
  			return longAction.getProgressTopic().getKey().getId();
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  	
  	@Override
  	public Long branchToNewProject(Long roid, String projectName, String comment, Boolean sync) throws UserException, ServerException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.POSSIBLY_WRITE);
  		try {
  			BranchToNewProjectDatabaseAction action = new BranchToNewProjectDatabaseAction(session, getInternalAccessMethod(), getBimServer(), getAuthorization(), roid, projectName, comment);
  			User user = (User) session.get(StorePackage.eINSTANCE.getUser(), getAuthorization().getUoid(), OldQuery.getDefault());
  			String username = user.getName();
  			String userUsername = user.getUsername();
  			LongBranchAction longAction = new LongBranchAction(getBimServer(), username, userUsername, getAuthorization(), action);
  			getBimServer().getLongActionManager().start(longAction);
  			if (sync) {
  				longAction.waitForCompletion();
  			}
  			return longAction.getProgressTopic().getKey().getId();
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public Long branchToExistingProject(Long roid, Long destPoid, String comment, Boolean sync) throws UserException, ServerException {
  		requireRealUserAuthentication();
  		final DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.POSSIBLY_WRITE);
  		try {
  			BranchToExistingProjectDatabaseAction action = new BranchToExistingProjectDatabaseAction(session, getInternalAccessMethod(), getBimServer(), getAuthorization(), roid, destPoid, comment);
  			User user = (User) session.get(StorePackage.eINSTANCE.getUser(), getAuthorization().getUoid(), OldQuery.getDefault());
  			String username = user.getName();
  			String userUsername = user.getUsername();
  			LongBranchAction longBranchAction = new LongBranchAction(getBimServer(), username, userUsername, getAuthorization(), action);
  			getBimServer().getLongActionManager().start(longBranchAction);
  			if (sync) {
  				longBranchAction.waitForCompletion();
  			}
  			return longBranchAction.getProgressTopic().getKey().getId();
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public SProject getProjectByPoid(Long poid) throws ServerException, UserException {
  		requireAuthenticationAndRunningServer();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			GetProjectByPoidDatabaseAction action = new GetProjectByPoidDatabaseAction(session, getInternalAccessMethod(), poid, getAuthorization());
  			SProject result = getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(action));
  			return result;
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public SProject getProjectByUuid(String uuid) throws ServerException, UserException {
  		requireAuthenticationAndRunningServer();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			GetProjectByUuidDatabaseAction action = new GetProjectByUuidDatabaseAction(session, getInternalAccessMethod(), uuid, getAuthorization());
  			SProject result = getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(action));
  			return result;
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public SProjectSmall getProjectSmallByPoid(Long poid) throws ServerException, UserException {
  		requireAuthenticationAndRunningServer();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			GetProjectByPoidDatabaseAction action = new GetProjectByPoidDatabaseAction(session, getInternalAccessMethod(), poid, getAuthorization());
  			Project project = session.executeAndCommitAction(action);
  			User user = session.get(getAuthorization().getUoid(), OldQuery.getDefault());
  			return GetAllProjectsSmallDatabaseAction.createSmallProject(getAuthorization(), getBimServer(), project, user);
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public List<SProject> getProjectsByName(String name) throws UserException, ServerException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			GetProjectsByNameDatabaseAction action = new GetProjectsByNameDatabaseAction(session, getInternalAccessMethod(), name, getAuthorization());
  			return getBimServer().getSConverter().convertToSListProject(session.executeAndCommitAction(action));
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public SProject getTopLevelProjectByName(String name) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			GetTopLevelProjectByNameDatabaseAction action = new GetTopLevelProjectByNameDatabaseAction(session, getInternalAccessMethod(), name, getAuthorization());
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(action));
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public List<SProject> getSubProjects(Long poid) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			BimDatabaseAction<Set<Project>> action = new GetSubProjectsDatabaseAction(session, getInternalAccessMethod(), getAuthorization(), poid);
  			List<SProject> convertToSListProject = getBimServer().getSConverter().convertToSListProject(session.executeAndCommitAction(action));
  			Collections.sort(convertToSListProject, new SProjectComparator());
  			return convertToSListProject;
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public List<SExtendedData> getAllExtendedDataOfRevision(Long roid) throws ServerException, UserException {
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			Revision revision = (Revision) session.get(StorePackage.eINSTANCE.getRevision(), roid, OldQuery.getDefault());
  			if (revision == null) {
  				throw new UserException("No revision found with roid " + roid);
  			}
  			return getBimServer().getSConverter().convertToSListExtendedData(revision.getExtendedData());
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public List<SExtendedData> getAllExtendedDataOfRevisionAndSchema(Long roid, Long schemaId) throws ServerException, UserException {
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			Revision revision = (Revision) session.get(StorePackage.eINSTANCE.getRevision(), roid, OldQuery.getDefault());
  			if (revision == null) {
  				throw new UserException("No revision found with roid " + roid);
  			}
  			EList<ExtendedData> list = revision.getExtendedData();
  			List<SExtendedData> result = new ArrayList<>();
  			for (ExtendedData extendedData : list) {
  				if (extendedData.getSchema().getOid() == schemaId) {
  					result.add(getBimServer().getSConverter().convertToSObject(extendedData));
  				}
  			}
  			return result;
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public SExtendedData getLastExtendedDataOfRevisionAndSchema(Long roid, Long schemaId) throws ServerException, UserException {
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			Revision revision = (Revision) session.get(StorePackage.eINSTANCE.getRevision(), roid, OldQuery.getDefault());
  			if (revision == null) {
  				throw new UserException("No revision found with roid " + roid);
  			}
  			EList<ExtendedData> list = revision.getExtendedData();
  			ExtendedData last = null;
  			for (ExtendedData extendedData : list) {
  				if (extendedData.getSchema().getOid() == schemaId) {
  					if (last == null || last.getAdded().before(extendedData.getAdded())) {
  						last = extendedData;
  					}
  				}
  			}
  			if (last != null) {
  				return getBimServer().getSConverter().convertToSObject(last);
  			}
  			return null;
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public Boolean undeleteProject(Long poid) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.POSSIBLY_WRITE);
  		try {
  			BimDatabaseAction<Boolean> action = new UndeleteProjectDatabaseAction(getBimServer(), session, getInternalAccessMethod(), poid, getAuthorization());
  			return session.executeAndCommitAction(action);
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public Boolean deleteProject(Long poid) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.POSSIBLY_WRITE);
  		try {
  			BimDatabaseAction<Boolean> action = new DeleteProjectDatabaseAction(getBimServer(), session, getInternalAccessMethod(), poid, getAuthorization());
  			return session.executeAndCommitAction(action);
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public List<SRevision> getAllRevisionsOfProject(Long poid) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			BimDatabaseAction<Set<Revision>> action = new GetAllRevisionsOfProjectDatabaseAction(session, getInternalAccessMethod(), poid);
  			List<SRevision> convertToSListRevision = getBimServer().getSConverter().convertToSListRevision(session.executeAndCommitAction(action));
  			Collections.sort(convertToSListRevision, new SRevisionComparator(true));
  			return convertToSListRevision;
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public List<SProject> getAllProjects(Boolean onlyTopLevel, Boolean onlyActive) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			BimDatabaseAction<Set<Project>> action = new GetAllProjectsDatabaseAction(session, getInternalAccessMethod(), onlyTopLevel, onlyActive, getAuthorization());
  			List<SProject> convertToSListProject = getBimServer().getSConverter().convertToSListProject(session.executeAndCommitAction(action));
  			Collections.sort(convertToSListProject, new SProjectComparator());
  			return convertToSListProject;
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public List<SProjectSmall> getAllProjectsSmall() throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY);
  		try {
  			BimDatabaseAction<List<SProjectSmall>> action = new GetAllProjectsSmallDatabaseAction(getBimServer(), session, getInternalAccessMethod(), getAuthorization());
  			return action.execute();
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	@Override
  	public SProject addProject(String projectName, String schema) throws ServerException, UserException {
  		requireRealUserAuthentication();
  		DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.POSSIBLY_WRITE);
  		try {
  			BimDatabaseAction<Project> action = new AddProjectDatabaseAction(getBimServer(), session, getInternalAccessMethod(), projectName, schema, getAuthorization());
  			return getBimServer().getSConverter().convertToSObject(session.executeAndCommitAction(action));
  		} catch (Exception e) {
  			return handleException(e);
  		} finally {
  			session.close();
  		}
  	}
  
  	public SExtendedDataSchema getExtendedDataSchemaByName(String nameSpace) throws UserException, ServerException {
  		// Not checking for real authentication here because a remote service should be
  		// able to use an exs
  		if (nameSpace == null) {
  