diff --git a/reactome/src/main/java/lcsb/mapviewer/reactome/utils/ReactomeConnector.java b/reactome/src/main/java/lcsb/mapviewer/reactome/utils/ReactomeConnector.java
index dcc5cdb14ec81803fbffab2d59318a2717d3aae1..f41b6ae6261905346b8845af1fe16a21fa5c64fc 100644
--- a/reactome/src/main/java/lcsb/mapviewer/reactome/utils/ReactomeConnector.java
+++ b/reactome/src/main/java/lcsb/mapviewer/reactome/utils/ReactomeConnector.java
@@ -1,778 +1,779 @@
-package lcsb.mapviewer.reactome.utils;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import lcsb.mapviewer.annotation.cache.CachableInterface;
-import lcsb.mapviewer.annotation.cache.GeneralCacheInterface;
-import lcsb.mapviewer.annotation.cache.SourceNotAvailable;
-import lcsb.mapviewer.annotation.services.ExternalServiceStatus;
-import lcsb.mapviewer.annotation.services.ExternalServiceStatusType;
-import lcsb.mapviewer.common.HttpConnectionMethodType;
-import lcsb.mapviewer.common.MimeType;
-import lcsb.mapviewer.common.exception.InvalidArgumentException;
-import lcsb.mapviewer.common.exception.InvalidXmlSchemaException;
-import lcsb.mapviewer.model.map.MiriamData;
-import lcsb.mapviewer.model.map.MiriamType;
-import lcsb.mapviewer.reactome.model.ReactomeCandidateSet;
-import lcsb.mapviewer.reactome.model.ReactomeCatalystActivity;
-import lcsb.mapviewer.reactome.model.ReactomeComplex;
-import lcsb.mapviewer.reactome.model.ReactomeDatabaseObject;
-import lcsb.mapviewer.reactome.model.ReactomeEntitySet;
-import lcsb.mapviewer.reactome.model.ReactomeEntityWithAccessionedSequence;
-import lcsb.mapviewer.reactome.model.ReactomePhysicalEntity;
-import lcsb.mapviewer.reactome.model.ReactomeReactionlikeEvent;
-import lcsb.mapviewer.reactome.model.ReactomeReferenceMolecule;
-import lcsb.mapviewer.reactome.model.ReactomeReferenceSequence;
-import lcsb.mapviewer.reactome.model.ReactomeSimpleEntity;
-import lcsb.mapviewer.reactome.model.ReactomeStableIdentifier;
-import lcsb.mapviewer.reactome.model.ReactomeStatus;
-import lcsb.mapviewer.reactome.xml.ReactomeNodeParser;
-import lcsb.mapviewer.reactome.xml.ReactomeParserFactory;
-
-/**
- * Data access object for reactome data.
- * 
- * @author Piotr Gawron
- * 
- */
-@Transactional
-@Service
-public class ReactomeConnector extends CachableInterface implements DataSourceUpdater {
-
-	/**
-	 * Identifier of the object in reactome database used for testing connection.
-	 */
-	private static final int		CHECK_SERVICE_STATUS_EXAMPLE = 109581;
-
-	/**
-	 * Default timeout of http connection (in miliseconds).
-	 */
-	private static final int		CONNECTION_TIMEOUT					 = 10000;
-
-	/**
-	 * Prefix used in cache entries for objects queried by the identifier.
-	 */
-	private static final String	IDENTIFIER_QUERY_PREFIX			 = "ID: ";
-
-	@Override
-	public Object refreshCacheQuery(Object query) throws SourceNotAvailable {
-		ReactomeConnector connector = new ReactomeConnector();
-
-		String name;
-		Object result = null;
-		if (query instanceof String) {
-			name = (String) query;
-			if (name.startsWith(IDENTIFIER_QUERY_PREFIX)) {
-				String strId = name.substring(IDENTIFIER_QUERY_PREFIX.length());
-				Integer id = Integer.valueOf(strId);
-				try {
-					return connector.getFullNodeForDbId(id);
-				} catch (InvalidXmlSchemaException e) {
-					throw new SourceNotAvailable(e);
-				}
-			} else if (name.contains("\n")) {
-				String[] tmp = name.split("\n");
-				if (tmp.length != 2) {
-					throw new InvalidArgumentException("Don't know what to do with string \"" + query + "\"");
-				} else {
-					String params = tmp[0];
-					String url = tmp[1];
-					try {
-						result = connector.getNodesFromServer(params, url);
-					} catch (Exception e) {
-						throw new SourceNotAvailable(e);
-					}
-				}
-			} else {
-				throw new InvalidArgumentException("Don't know what to do with string \"" + query + "\"");
-			}
-		} else {
-			throw new InvalidArgumentException("Don't know what to do with class: " + query.getClass());
-		}
-		return result;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public ReactomeConnector() {
-		super(ReactomeConnector.class);
-	}
-
-	/**
-	 * Determines if only one object instance should be created for single
-	 * reactome database identifier.
-	 */
-	private boolean															 oneInstancePerId	= true;
-
-	/**
-	 * Map of all reactome objects retrieved by this connector.
-	 */
-	private Map<Integer, ReactomeDatabaseObject> objectMap				= new HashMap<Integer, ReactomeDatabaseObject>();
-
-	/**
-	 * Default class logger.
-	 */
-	private static Logger												 logger						= Logger.getLogger(ReactomeConnector.class);
-	/**
-	 * Url used for accessing Reactome RestFULL API.
-	 */
-	private static final String									 REACTOME_URL			= "http://reactome.org/ReactomeRESTfulAPI/RESTfulWS/";
-
-	@Override
-	public List<ReactomePhysicalEntity> getEntitiesForName(String name) throws IOException {
-		return getEntitiesForName(name, true);
-	}
-
-	@Override
-	public List<ReactomePhysicalEntity> getEntitiesForName(String name, boolean full) throws IOException {
-		List<ReactomePhysicalEntity> result = new ArrayList<ReactomePhysicalEntity>();
-
-		String query = "name=" + name;
-		List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomePhysicalEntity.class);
-
-		for (ReactomeDatabaseObject object : objects) {
-			if (full) {
-				ReactomePhysicalEntity fullEntity = (ReactomePhysicalEntity) getFullObjectForDbId(object.getDbId());
-				result.add(fullEntity);
-			} else {
-				result.add((ReactomePhysicalEntity) object);
-			}
-		}
-		return result;
-	}
-
-	@Override
-	public List<ReactomePhysicalEntity> getEntitiesForChebiId(Set<MiriamData> ids, boolean deepSearch) throws IOException {
-		Set<ReactomePhysicalEntity> set = new HashSet<ReactomePhysicalEntity>();
-		List<ReactomePhysicalEntity> result = new ArrayList<ReactomePhysicalEntity>();
-		if (ids == null) {
-			return result;
-		}
-		for (MiriamData md : ids) {
-			if (md == null) {
-				return result;
-			}
-			String id = md.getResource().replace("CHEBI:", "");
-
-			String query = "identifier=" + id;
-			List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeReferenceMolecule.class);
-
-			for (ReactomeDatabaseObject object : objects) {
-				ReactomeReferenceMolecule reference = (ReactomeReferenceMolecule) getFullObjectForDbId(object.getDbId());
-				List<ReactomeSimpleEntity> list = getSimpleEntitiesByReferenceMolecule(reference);
-				set.addAll(list);
-			}
-			if (deepSearch) {
-				int lastSize = 0;
-				do {
-					lastSize = set.size();
-					Set<ReactomePhysicalEntity> complexes = getComplexesContainingOneOfElements(set);
-					set.addAll(complexes);
-					Set<ReactomePhysicalEntity> sets = getSetsContainingOneOfElements(set);
-					set.addAll(sets);
-				} while (lastSize != set.size());
-			}
-			result.addAll(set);
-		}
-		return result;
-	}
-
-	@Override
-	public List<ReactomePhysicalEntity> getEntitiesForUniprotId(Collection<MiriamData> uniprot) throws IOException {
-		Set<ReactomePhysicalEntity> set = new HashSet<ReactomePhysicalEntity>();
-
-		for (MiriamData md : uniprot) {
-			if (!MiriamType.UNIPROT.equals(md.getDataType())) {
-				throw new InvalidArgumentException("Only uniprot miriam are acceptable");
-			}
-			String id = md.getResource();
-			int lastSize = set.size();
-			do {
-				lastSize = set.size();
-
-				String query = "identifier=" + id;
-				List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeReferenceSequence.class);
-
-				for (ReactomeDatabaseObject object : objects) {
-					ReactomeReferenceSequence reference = (ReactomeReferenceSequence) getFullObjectForDbId(object.getDbId());
-					List<ReactomePhysicalEntity> list = getPhysicalEnitiesForReferenceSequence(reference);
-					set.addAll(list);
-				}
-				query = "secondaryIdentifier=" + id;
-				objects = getSimpleObjectListByQuery(query, ReactomeReferenceSequence.class);
-
-				for (ReactomeDatabaseObject object : objects) {
-					ReactomeReferenceSequence reference = (ReactomeReferenceSequence) getFullObjectForDbId(object.getDbId());
-					List<ReactomePhysicalEntity> list = getPhysicalEnitiesForReferenceSequence(reference);
-					set.addAll(list);
-				}
-
-				Set<ReactomePhysicalEntity> complexes = getComplexesContainingOneOfElements(set);
-				set.addAll(complexes);
-				Set<ReactomePhysicalEntity> sets = getSetsContainingOneOfElements(set);
-				set.addAll(sets);
-			} while (lastSize != set.size());
-		}
-		List<ReactomePhysicalEntity> result = new ArrayList<ReactomePhysicalEntity>();
-		result.addAll(set);
-		return result;
-	}
-
-	/**
-	 * Returns list of ReactomeComplex that contain one of the elements given in
-	 * the parameter.
-	 * 
-	 * @param objects
-	 *          list of objects for which we want to retrieve complexes
-	 * @return list of ReactomeComplex that contain one of the elements given in
-	 *         the parameter
-	 * @throws IOException
-	 *           thrown when there is a problem with connection to reactome
-	 *           database
-	 */
-	private Set<ReactomePhysicalEntity> getComplexesContainingOneOfElements(Collection<ReactomePhysicalEntity> objects) throws IOException {
-		Set<ReactomePhysicalEntity> result = new HashSet<ReactomePhysicalEntity>();
-		for (ReactomeDatabaseObject obj : objects) {
-			String query = "hasComponent=" + obj.getDbId();
-			List<ReactomeDatabaseObject> complexes = getSimpleObjectListByQuery(query, ReactomeComplex.class);
-			for (ReactomeDatabaseObject complex : complexes) {
-				result.add((ReactomePhysicalEntity) getFullObjectForDbId(complex.getDbId()));
-			}
-		}
-		return result;
-	}
-
-	/**
-	 * Returns list of ReactomeEntitySet that contain one of the elements given in
-	 * the parameter.
-	 * 
-	 * @param objects
-	 *          list of objects for which we want to retrieve sets
-	 * @return list of ReactomeEntitySet that contain one of the elements given in
-	 *         the parameter
-	 * @throws IOException
-	 *           thrown when there is a problem with connection to reactome
-	 *           database
-	 */
-	private Set<ReactomePhysicalEntity> getSetsContainingOneOfElements(Collection<ReactomePhysicalEntity> objects) throws IOException {
-
-		Set<ReactomePhysicalEntity> result = new HashSet<ReactomePhysicalEntity>();
-		for (ReactomeDatabaseObject obj : objects) {
-			String query = "hasMember=" + obj.getDbId();
-			List<ReactomeDatabaseObject> complexes = getSimpleObjectListByQuery(query, ReactomeEntitySet.class);
-			for (ReactomeDatabaseObject complex : complexes) {
-				result.add((ReactomeEntitySet) getFullObjectForDbId(complex.getDbId()));
-			}
-			query = "hasCandidate=" + obj.getDbId();
-			complexes = getSimpleObjectListByQuery(query, ReactomeCandidateSet.class);
-			for (ReactomeDatabaseObject complex : complexes) {
-				result.add((ReactomeCandidateSet) getFullObjectForDbId(complex.getDbId()));
-			}
-		}
-		return result;
-	}
-
-	/**
-	 * Returns list of ReactomeEntityWithAccessionedSequence that refers to
-	 * parameter reference.
-	 * 
-	 * @param reference
-	 *          object to which result should refer to
-	 * @return list of ReactomeEntityWithAccessionedSequence that contain one of
-	 *         the elements given in the parameter
-	 * @throws IOException
-	 *           thrown when there is a problem with connection to reactome
-	 *           database
-	 */
-	private List<ReactomePhysicalEntity> getPhysicalEnitiesForReferenceSequence(ReactomeReferenceSequence reference) throws IOException {
-		List<ReactomePhysicalEntity> result = new ArrayList<ReactomePhysicalEntity>();
-
-		String query = "referenceEntity=" + reference.getDbId();
-		List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeEntityWithAccessionedSequence.class);
-
-		for (ReactomeDatabaseObject object : objects) {
-			result.add((ReactomePhysicalEntity) getFullObjectForDbId(object.getDbId()));
-		}
-		return result;
-	}
-
-	/**
-	 * Returns list of ReactomeSimpleEntity that refers to parameter reference.
-	 * 
-	 * @param reference
-	 *          object to which result should refer to
-	 * @return list of ReactomeSimpleEntity that contain one of the elements given
-	 *         in the parameter
-	 * @throws IOException
-	 *           thrown when there is a problem with connection to reactome
-	 *           database
-	 */
-	private List<ReactomeSimpleEntity> getSimpleEntitiesByReferenceMolecule(ReactomeReferenceMolecule reference) throws IOException {
-		List<ReactomeSimpleEntity> result = new ArrayList<ReactomeSimpleEntity>();
-
-		String query = "referenceEntity=" + reference.getDbId();
-		List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeSimpleEntity.class);
-
-		for (ReactomeDatabaseObject object : objects) {
-			result.add((ReactomeSimpleEntity) getFullObjectForDbId(object.getDbId()));
-		}
-		return result;
-	}
-
-	/**
-	 * Ges list of reactions that interact with object given in the parameter.
-	 * 
-	 * @param id
-	 *          identifier of the object that should be included in the result
-	 *          reactions
-	 * @return list of reactions that interact with object given in the parameter
-	 * @throws IOException
-	 *           thrown when there is a problem with connection to reactome
-	 *           database
-	 */
-	public List<ReactomeReactionlikeEvent> getReactionsForEntityId(Integer id) throws IOException {
-		List<ReactomeReactionlikeEvent> result = new ArrayList<ReactomeReactionlikeEvent>();
-
-		String query = "input=" + id;
-		List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeReactionlikeEvent.class);
-
-		for (ReactomeDatabaseObject object : objects) {
-			ReactomeDatabaseObject entity = getFullObjectForDbId(object.getDbId());
-			if (entity instanceof ReactomeReactionlikeEvent) {
-				result.add((ReactomeReactionlikeEvent) entity);
-			}
-		}
-
-		query = "output=" + id;
-		objects = getSimpleObjectListByQuery(query, ReactomeReactionlikeEvent.class);
-
-		for (ReactomeDatabaseObject object : objects) {
-			ReactomeDatabaseObject entity = getFullObjectForDbId(object.getDbId());
-			if (entity instanceof ReactomeReactionlikeEvent) {
-				result.add((ReactomeReactionlikeEvent) entity);
-			}
-		}
-
-		// and now find reaction with apropriate catalyst
-		query = "physicalEntity=" + id;
-		List<ReactomeDatabaseObject> catalysts = getSimpleObjectListByQuery(query, ReactomeCatalystActivity.class);
-		for (ReactomeDatabaseObject catalyst : catalysts) {
-			query = "catalystActivity=" + catalyst.getDbId();
-			objects = getSimpleObjectListByQuery(query, ReactomeReactionlikeEvent.class);
-			for (ReactomeDatabaseObject object : objects) {
-				ReactomeDatabaseObject entity = getFullObjectForDbId(object.getDbId());
-				if (entity instanceof ReactomeReactionlikeEvent) {
-					result.add((ReactomeReactionlikeEvent) entity);
-				}
-			}
-		}
-
-		return result;
-	}
-
-	@Override
-	public Class<?> getTypeForDbId(Integer id) throws ClassNotFoundException, InvalidXmlSchemaException {
-		Node node = getFullNodeForDbId(id);
-		Class<?> result = getTypeForNode(node);
-		return result;
-	}
-
-	/**
-	 * Returns class type of the data represented in the xml node.
-	 * 
-	 * @param node
-	 *          xml node
-	 * @return class type of the data represented in the xml node
-	 * @throws ClassNotFoundException
-	 *           thrown when there is a problem with finding apropriate class
-	 */
-	protected Class<?> getTypeForNode(Node node) throws ClassNotFoundException {
-		Class<?> result = null;
-		for (int i = 0; i < node.getChildNodes().getLength(); i++) {
-			Node child = node.getChildNodes().item(i);
-			if (child.getNodeName().equals("schemaClass")) {
-				// our classes aren't exactly the same as reactome names, change what is
-				// different
-				String shortName = child.getTextContent().replaceAll("GO_", "Go");
-				String className = ReactomeDatabaseObject.class.getPackage().getName() + ".Reactome" + shortName;
-				result = Class.forName(className);
-			}
-		}
-		return result;
-	}
-
-	@Override
-	public ReactomeDatabaseObject getFullObjectForDbId(Integer id) {
-		try {
-			ReactomeDatabaseObject result = null;
-			if (oneInstancePerId) {
-				result = objectMap.get(id);
-				if (result != null) {
-					return result;
-				}
-			}
-			Class<?> classType;
-			Node node = getFullNodeForDbId(id);
-			classType = getTypeForNode(node);
-			ReactomeNodeParser<?> parser = ReactomeParserFactory.getParserForClass(classType);
-			result = parser.parseObject(node);
-			if (oneInstancePerId) {
-				objectMap.put(id, result);
-			}
-			return result;
-		} catch (ClassNotFoundException e) {
-			throw new InvalidArgumentException("Unknown class type: " + e.getMessage());
-		} catch (InvalidXmlSchemaException e) {
-			logger.error(e, e);
-			return null;
-		}
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public void updateOnlyIdFields(ReactomeDatabaseObject object) {
-		DataSourceUpdater dsu = this;
-		for (Method method : object.getClass().getMethods()) {
-
-			if (Modifier.isPublic(method.getModifiers()) && method.getParameterTypes().length == 0
-					&& (method.getName().startsWith("get") || method.getName().startsWith("is"))) {
-
-				if (ReactomeDatabaseObject.class.isAssignableFrom(method.getReturnType())) {
-					try {
-						ReactomeDatabaseObject value = (ReactomeDatabaseObject) method.invoke(object);
-						if (value != null) {
-							if (value.getStatus().equals(ReactomeStatus.ONLY_ID)) {
-								ReactomeDatabaseObject newValue = dsu.getFullObjectForDbId(value.getDbId());
-								String setterName = method.getName();
-								if (setterName.startsWith("get")) {
-									setterName = setterName.replaceFirst("get", "set");
-								} else {
-									setterName = setterName.replaceFirst("is", "set");
-								}
-								try {
-									Method setterMethod = object.getClass().getMethod(setterName, method.getReturnType());
-									setterMethod.invoke(object, newValue);
-								} catch (NoSuchMethodException e) {
-									e.printStackTrace();
-								} catch (IllegalArgumentException e) {
-									logger.error(
-											"Cannot assign " + newValue.getClass() + " (id: " + value.getDbId() + ") to field: " + setterName.replace("set", "") + " ("
-													+ method.getReturnType() + ")");
-								} catch (SecurityException e) {
-
-									e.printStackTrace();
-									// ignore it - however this would be strange
-								}
-							}
-						}
-					} catch (IllegalAccessException e) {
-						e.printStackTrace();
-					} catch (IllegalArgumentException e) {
-						e.printStackTrace();
-					} catch (InvocationTargetException e) {
-						e.printStackTrace();
-						// ignore it
-					}
-
-				} else if (List.class.isAssignableFrom(method.getReturnType())) {
-					try {
-						@SuppressWarnings("rawtypes")
-						List list = (List) method.invoke(object);
-						for (int i = 0; i < list.size(); i++) {
-							Object obj = list.get(i);
-							if (obj instanceof ReactomeDatabaseObject) {
-								if (((ReactomeDatabaseObject) obj).getStatus().equals(ReactomeStatus.ONLY_ID)) {
-									ReactomeDatabaseObject newValue = dsu.getFullObjectForDbId(((ReactomeDatabaseObject) obj).getDbId());
-									list.set(i, newValue);
-								}
-							}
-						}
-					} catch (IllegalAccessException e) {
-						e.printStackTrace();
-					} catch (IllegalArgumentException e) {
-						e.printStackTrace();
-					} catch (InvocationTargetException e) {
-						e.printStackTrace();
-						// ignore it
-					}
-				}
-			}
-		}
-	}
-
-	@Override
-	public ReactomeDatabaseObject getFullObjectForStableIdentifier(String stableIdentifier) throws IOException {
-		if (stableIdentifier == null) {
-			return null;
-		}
-		String[] tmp = stableIdentifier.split("\\.");
-		String identifier = tmp[0];
-		String version = "0";
-		if (tmp.length > 1) {
-			version = tmp[1];
-		}
-		return getFullObjectForStableIdentifier(identifier, version);
-	}
-
-	@Override
-	public ReactomeDatabaseObject getFullObjectForStableIdentifier(String identifier, String version) throws IOException {
-		String stableIdentifierQuery = "identifier=" + identifier;
-
-		List<ReactomeDatabaseObject> stableIdentifiers = getSimpleObjectListByQuery(stableIdentifierQuery, ReactomeStableIdentifier.class);
-
-		ReactomeStableIdentifier newestIdentifier = null;
-		ReactomeStableIdentifier matchedIdentifier = null;
-
-		for (ReactomeDatabaseObject object : stableIdentifiers) {
-			ReactomeStableIdentifier entity = (ReactomeStableIdentifier) getFullObjectForDbId(object.getDbId());
-			if (newestIdentifier == null) {
-				newestIdentifier = entity;
-			} else {
-				try {
-					Integer id1 = Integer.parseInt(newestIdentifier.getIdentifierVersion());
-					Integer id2 = Integer.parseInt(entity.getIdentifierVersion());
-					if (id2 > id1) {
-						newestIdentifier = entity;
-					}
-				} catch (Exception e) {
-					logger.error(e.getMessage(), e);
-				}
-			}
-			if (entity.getDisplayName().equals(identifier + "." + version) || entity.getIdentifierVersion().equalsIgnoreCase(version)) {
-				matchedIdentifier = entity;
-			}
-		}
-		if (matchedIdentifier == null) {
-			if (newestIdentifier != null) {
-				logger.warn(
-						"Invalid REACTOME stable identifier: \"" + identifier + "." + version + "\". Using another similar: " + newestIdentifier.getIdentifier() + "."
-								+ newestIdentifier.getIdentifierVersion());
-			}
-			matchedIdentifier = newestIdentifier;
-		}
-		if (matchedIdentifier != null) {
-			String query = "stableIdentifier=" + matchedIdentifier.getDbId();
-			List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeDatabaseObject.class);
-
-			for (ReactomeDatabaseObject object : objects) {
-				return getFullObjectForDbId(object.getDbId());
-			}
-
-		}
-		return null;
-	}
-
-	// ------------------------------------------------
-
-	// Methods that directly connect to reactome database (via restfull API)
-
-	// ------------------------------------------------
-
-	/**
-	 * This method get content of the page of the url (and post content).
-	 * 
-	 * @param url
-	 *          url address to connect
-	 * @param postParam
-	 *          params of the post method
-	 * @param type
-	 *          MIME type of the result
-	 * @param method
-	 *          request method (POST/GET)
-	 * @return return the string with the content of the webpage
-	 * @throws IOException
-	 *           thrown when there are some problem with network connection
-	 */
-	protected String getResponse(String url, String postParam, MimeType type, HttpConnectionMethodType method) throws IOException {
-		URL obj = new URL(url);
-		HttpURLConnection con = (HttpURLConnection) obj.openConnection();
-
-		// add reuqest header
-		con.setRequestMethod(method.name());
-		con.setRequestProperty("Accept", type.getTextRepresentation());
-		con.setRequestProperty("Content-Type", type.getTextRepresentation());
-		con.setConnectTimeout(CONNECTION_TIMEOUT);
-		con.setReadTimeout(CONNECTION_TIMEOUT);
-
-		String urlParameters = postParam;
-
-		logger.debug("Sending '" + method + "' request to URL : " + url);
-		if (method.name().equals("POST")) {
-			logger.debug("Parameters : " + urlParameters);
-		}
-
-		// Send post request
-		con.setDoOutput(true);
-		if (method.name().equalsIgnoreCase("POST")) {
-			DataOutputStream wr = new DataOutputStream(con.getOutputStream());
-			wr.writeBytes(urlParameters);
-			wr.flush();
-			wr.close();
-		}
-
-		int responseCode = con.getResponseCode();
-		logger.debug("Response Code : " + responseCode);
-
-		String result = IOUtils.toString(con.getInputStream());
-		logger.debug(result);
-		return result;
-	}
-
-	@Override
-	public List<ReactomeDatabaseObject> getSimpleObjectListByQuery(String query, Class<? extends ReactomeDatabaseObject> clazz) throws IOException {
-		if (query.contains("\n")) {
-			throw new InvalidArgumentException("Query cannot contain new line character");
-		}
-		ReactomeNodeParser<?> parser = ReactomeParserFactory.getParserForClass(clazz);
-		List<ReactomeDatabaseObject> result = new ArrayList<ReactomeDatabaseObject>();
-
-		String url = REACTOME_URL + "listByQuery/" + clazz.getSimpleName().replaceFirst("Reactome", "").replaceAll("Go", "GO_");
-
-		String key = query + "\n" + url;
-
-		Node node = getCacheNode(key);
-		NodeList nodes = null;
-		if (node != null) {
-			nodes = node.getChildNodes();
-		} else {
-			try {
-				nodes = getNodesFromServer(query, url);
-			} catch (InvalidXmlSchemaException e) {
-				throw new IOException(e);
-			}
-			setCacheNode(key, nodes.item(0));
-			nodes = nodes.item(0).getChildNodes();
-		}
-		for (int i = 0; i < nodes.getLength(); i++) {
-			if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
-				continue;
-			}
-			ReactomeDatabaseObject object = parser.parseSimplifiedObject(nodes.item(i));
-			result.add(object);
-		}
-		return result;
-	}
-
-	/**
-	 * Returns list of nodes from the server identified by the query and POST
-	 * params.
-	 * 
-	 * @param query
-	 *          string query to the database sent by POST method
-	 * @param url
-	 *          direct url to the API
-	 * @return list of nodes from the server identified by the query and POST
-	 *         params.
-	 * @throws IOException
-	 *           thrown when there are some problem with network connection
-	 * @throws InvalidXmlSchemaException
-	 *           thrown when there is a problem with xml
-	 */
-	private NodeList getNodesFromServer(String query, String url) throws IOException, InvalidXmlSchemaException {
-		String response = getResponse(url, query, MimeType.XML, HttpConnectionMethodType.POST);
-		logger.debug(response);
-		Node node = getXmlDocumentFromString(response);
-		NodeList nodes = node.getChildNodes();
-		if (nodes.getLength() < 1) {
-			throw new InvalidArgumentException("Problem with xml document");
-		}
-		return nodes;
-	}
-
-	/**
-	 * This method returns xml NODE for object identified by id (identifier in
-	 * reactome database). However if object is in local cache then local copy is
-	 * returned. If object doesn't exist in local cache then after retrieving it
-	 * from reactome is put to the cache.
-	 * 
-	 * @param id
-	 *          identifier in reactome database
-	 * @return xml node for the id given reactome id
-	 * @throws InvalidXmlSchemaException
-	 *           thrown when there is a problem with xml
-	 */
-	@Override
-	public Node getFullNodeForDbId(Integer id) throws InvalidXmlSchemaException {
-		Node result = getCacheNode(IDENTIFIER_QUERY_PREFIX + id);
-		if (result != null) {
-			return result;
-		}
-
-		String response;
-		String url = REACTOME_URL + "queryById/DatabaseObject/" + id;
-		try {
-			response = getResponse(url, "", MimeType.XML, HttpConnectionMethodType.GET);
-			Document doc = getXmlDocumentFromString(response);
-			NodeList nodes = doc.getChildNodes();
-			result = nodes.item(0);
-			setCacheNode(IDENTIFIER_QUERY_PREFIX + id, result);
-			return result;
-		} catch (IOException e) {
-			logger.error(e.getMessage(), e);
-			return null;
-		}
-	}
-
-	@Override
-	public Map<Integer, ReactomeDatabaseObject> getFullObjectsForDbIds(List<Integer> ids) throws ClassNotFoundException, IOException {
-		Map<Integer, ReactomeDatabaseObject> result = new HashMap<Integer, ReactomeDatabaseObject>();
-		for (Integer integer : ids) {
-			result.put(integer, getFullObjectForDbId(integer));
-		}
-
-		return result;
-
-	}
-
-	@Override
-	public List<ReactomePhysicalEntity> getEntitiesForSetOfIds(Set<MiriamData> identifiers) throws IOException {
-		return getEntitiesForUniprotId(identifiers);
-	}
-
-	@Override
-	public ExternalServiceStatus getServiceStatus() {
-		ExternalServiceStatus status = new ExternalServiceStatus(
-				"Reactome RESTful API", "http://reactome.org/ReactomeRESTfulAPI/ReactomeRESTFulAPI.html");
-
-		GeneralCacheInterface cacheCopy = getCache();
-		this.setCache(null);
-
-		try {
-			ReactomeDatabaseObject obj = getFullObjectForDbId(CHECK_SERVICE_STATUS_EXAMPLE);
-			status.setStatus(ExternalServiceStatusType.OK);
-			if (obj == null) {
-				status.setStatus(ExternalServiceStatusType.DOWN);
-			} else if (obj.getClass().equals(ReactomeDatabaseObject.class)) {
-				status.setStatus(ExternalServiceStatusType.CHANGED);
-			}
-		} catch (Exception e) {
-			logger.error(status.getName() + " is down", e);
-			status.setStatus(ExternalServiceStatusType.DOWN);
-		}
-		this.setCache(cacheCopy);
-		return status;
-	}
-
-}
+package lcsb.mapviewer.reactome.utils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import lcsb.mapviewer.common.XmlParser;
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import lcsb.mapviewer.annotation.cache.CachableInterface;
+import lcsb.mapviewer.annotation.cache.GeneralCacheInterface;
+import lcsb.mapviewer.annotation.cache.SourceNotAvailable;
+import lcsb.mapviewer.annotation.services.ExternalServiceStatus;
+import lcsb.mapviewer.annotation.services.ExternalServiceStatusType;
+import lcsb.mapviewer.common.HttpConnectionMethodType;
+import lcsb.mapviewer.common.MimeType;
+import lcsb.mapviewer.common.exception.InvalidArgumentException;
+import lcsb.mapviewer.common.exception.InvalidXmlSchemaException;
+import lcsb.mapviewer.model.map.MiriamData;
+import lcsb.mapviewer.model.map.MiriamType;
+import lcsb.mapviewer.reactome.model.ReactomeCandidateSet;
+import lcsb.mapviewer.reactome.model.ReactomeCatalystActivity;
+import lcsb.mapviewer.reactome.model.ReactomeComplex;
+import lcsb.mapviewer.reactome.model.ReactomeDatabaseObject;
+import lcsb.mapviewer.reactome.model.ReactomeEntitySet;
+import lcsb.mapviewer.reactome.model.ReactomeEntityWithAccessionedSequence;
+import lcsb.mapviewer.reactome.model.ReactomePhysicalEntity;
+import lcsb.mapviewer.reactome.model.ReactomeReactionlikeEvent;
+import lcsb.mapviewer.reactome.model.ReactomeReferenceMolecule;
+import lcsb.mapviewer.reactome.model.ReactomeReferenceSequence;
+import lcsb.mapviewer.reactome.model.ReactomeSimpleEntity;
+import lcsb.mapviewer.reactome.model.ReactomeStableIdentifier;
+import lcsb.mapviewer.reactome.model.ReactomeStatus;
+import lcsb.mapviewer.reactome.xml.ReactomeNodeParser;
+import lcsb.mapviewer.reactome.xml.ReactomeParserFactory;
+
+/**
+ * Data access object for reactome data.
+ * 
+ * @author Piotr Gawron
+ * 
+ */
+@Transactional
+@Service
+public class ReactomeConnector extends CachableInterface implements DataSourceUpdater {
+
+	/**
+	 * Identifier of the object in reactome database used for testing connection.
+	 */
+	private static final int		CHECK_SERVICE_STATUS_EXAMPLE = 109581;
+
+	/**
+	 * Default timeout of http connection (in miliseconds).
+	 */
+	private static final int		CONNECTION_TIMEOUT					 = 10000;
+
+	/**
+	 * Prefix used in cache entries for objects queried by the identifier.
+	 */
+	private static final String	IDENTIFIER_QUERY_PREFIX			 = "ID: ";
+
+	@Override
+	public Object refreshCacheQuery(Object query) throws SourceNotAvailable {
+		ReactomeConnector connector = new ReactomeConnector();
+
+		String name;
+		Object result = null;
+		if (query instanceof String) {
+			name = (String) query;
+			if (name.startsWith(IDENTIFIER_QUERY_PREFIX)) {
+				String strId = name.substring(IDENTIFIER_QUERY_PREFIX.length());
+				Integer id = Integer.valueOf(strId);
+				try {
+					return connector.getFullNodeForDbId(id);
+				} catch (InvalidXmlSchemaException e) {
+					throw new SourceNotAvailable(e);
+				}
+			} else if (name.contains("\n")) {
+				String[] tmp = name.split("\n");
+				if (tmp.length != 2) {
+					throw new InvalidArgumentException("Don't know what to do with string \"" + query + "\"");
+				} else {
+					String params = tmp[0];
+					String url = tmp[1];
+					try {
+						result = connector.getNodesFromServer(params, url);
+					} catch (Exception e) {
+						throw new SourceNotAvailable(e);
+					}
+				}
+			} else {
+				throw new InvalidArgumentException("Don't know what to do with string \"" + query + "\"");
+			}
+		} else {
+			throw new InvalidArgumentException("Don't know what to do with class: " + query.getClass());
+		}
+		return result;
+	}
+
+	/**
+	 * Default constructor.
+	 */
+	public ReactomeConnector() {
+		super(ReactomeConnector.class);
+	}
+
+	/**
+	 * Determines if only one object instance should be created for single
+	 * reactome database identifier.
+	 */
+	private boolean															 oneInstancePerId	= true;
+
+	/**
+	 * Map of all reactome objects retrieved by this connector.
+	 */
+	private Map<Integer, ReactomeDatabaseObject> objectMap				= new HashMap<Integer, ReactomeDatabaseObject>();
+
+	/**
+	 * Default class logger.
+	 */
+	private static Logger												 logger						= Logger.getLogger(ReactomeConnector.class);
+	/**
+	 * Url used for accessing Reactome RestFULL API.
+	 */
+	private static final String									 REACTOME_URL			= "http://reactome.org/ReactomeRESTfulAPI/RESTfulWS/";
+
+	@Override
+	public List<ReactomePhysicalEntity> getEntitiesForName(String name) throws IOException {
+		return getEntitiesForName(name, true);
+	}
+
+	@Override
+	public List<ReactomePhysicalEntity> getEntitiesForName(String name, boolean full) throws IOException {
+		List<ReactomePhysicalEntity> result = new ArrayList<ReactomePhysicalEntity>();
+
+		String query = "name=" + name;
+		List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomePhysicalEntity.class);
+
+		for (ReactomeDatabaseObject object : objects) {
+			if (full) {
+				ReactomePhysicalEntity fullEntity = (ReactomePhysicalEntity) getFullObjectForDbId(object.getDbId());
+				result.add(fullEntity);
+			} else {
+				result.add((ReactomePhysicalEntity) object);
+			}
+		}
+		return result;
+	}
+
+	@Override
+	public List<ReactomePhysicalEntity> getEntitiesForChebiId(Set<MiriamData> ids, boolean deepSearch) throws IOException {
+		Set<ReactomePhysicalEntity> set = new HashSet<ReactomePhysicalEntity>();
+		List<ReactomePhysicalEntity> result = new ArrayList<ReactomePhysicalEntity>();
+		if (ids == null) {
+			return result;
+		}
+		for (MiriamData md : ids) {
+			if (md == null) {
+				return result;
+			}
+			String id = md.getResource().replace("CHEBI:", "");
+
+			String query = "identifier=" + id;
+			List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeReferenceMolecule.class);
+
+			for (ReactomeDatabaseObject object : objects) {
+				ReactomeReferenceMolecule reference = (ReactomeReferenceMolecule) getFullObjectForDbId(object.getDbId());
+				List<ReactomeSimpleEntity> list = getSimpleEntitiesByReferenceMolecule(reference);
+				set.addAll(list);
+			}
+			if (deepSearch) {
+				int lastSize = 0;
+				do {
+					lastSize = set.size();
+					Set<ReactomePhysicalEntity> complexes = getComplexesContainingOneOfElements(set);
+					set.addAll(complexes);
+					Set<ReactomePhysicalEntity> sets = getSetsContainingOneOfElements(set);
+					set.addAll(sets);
+				} while (lastSize != set.size());
+			}
+			result.addAll(set);
+		}
+		return result;
+	}
+
+	@Override
+	public List<ReactomePhysicalEntity> getEntitiesForUniprotId(Collection<MiriamData> uniprot) throws IOException {
+		Set<ReactomePhysicalEntity> set = new HashSet<ReactomePhysicalEntity>();
+
+		for (MiriamData md : uniprot) {
+			if (!MiriamType.UNIPROT.equals(md.getDataType())) {
+				throw new InvalidArgumentException("Only uniprot miriam are acceptable");
+			}
+			String id = md.getResource();
+			int lastSize = set.size();
+			do {
+				lastSize = set.size();
+
+				String query = "identifier=" + id;
+				List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeReferenceSequence.class);
+
+				for (ReactomeDatabaseObject object : objects) {
+					ReactomeReferenceSequence reference = (ReactomeReferenceSequence) getFullObjectForDbId(object.getDbId());
+					List<ReactomePhysicalEntity> list = getPhysicalEnitiesForReferenceSequence(reference);
+					set.addAll(list);
+				}
+				query = "secondaryIdentifier=" + id;
+				objects = getSimpleObjectListByQuery(query, ReactomeReferenceSequence.class);
+
+				for (ReactomeDatabaseObject object : objects) {
+					ReactomeReferenceSequence reference = (ReactomeReferenceSequence) getFullObjectForDbId(object.getDbId());
+					List<ReactomePhysicalEntity> list = getPhysicalEnitiesForReferenceSequence(reference);
+					set.addAll(list);
+				}
+
+				Set<ReactomePhysicalEntity> complexes = getComplexesContainingOneOfElements(set);
+				set.addAll(complexes);
+				Set<ReactomePhysicalEntity> sets = getSetsContainingOneOfElements(set);
+				set.addAll(sets);
+			} while (lastSize != set.size());
+		}
+		List<ReactomePhysicalEntity> result = new ArrayList<ReactomePhysicalEntity>();
+		result.addAll(set);
+		return result;
+	}
+
+	/**
+	 * Returns list of ReactomeComplex that contain one of the elements given in
+	 * the parameter.
+	 * 
+	 * @param objects
+	 *          list of objects for which we want to retrieve complexes
+	 * @return list of ReactomeComplex that contain one of the elements given in
+	 *         the parameter
+	 * @throws IOException
+	 *           thrown when there is a problem with connection to reactome
+	 *           database
+	 */
+	private Set<ReactomePhysicalEntity> getComplexesContainingOneOfElements(Collection<ReactomePhysicalEntity> objects) throws IOException {
+		Set<ReactomePhysicalEntity> result = new HashSet<ReactomePhysicalEntity>();
+		for (ReactomeDatabaseObject obj : objects) {
+			String query = "hasComponent=" + obj.getDbId();
+			List<ReactomeDatabaseObject> complexes = getSimpleObjectListByQuery(query, ReactomeComplex.class);
+			for (ReactomeDatabaseObject complex : complexes) {
+				result.add((ReactomePhysicalEntity) getFullObjectForDbId(complex.getDbId()));
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Returns list of ReactomeEntitySet that contain one of the elements given in
+	 * the parameter.
+	 * 
+	 * @param objects
+	 *          list of objects for which we want to retrieve sets
+	 * @return list of ReactomeEntitySet that contain one of the elements given in
+	 *         the parameter
+	 * @throws IOException
+	 *           thrown when there is a problem with connection to reactome
+	 *           database
+	 */
+	private Set<ReactomePhysicalEntity> getSetsContainingOneOfElements(Collection<ReactomePhysicalEntity> objects) throws IOException {
+
+		Set<ReactomePhysicalEntity> result = new HashSet<ReactomePhysicalEntity>();
+		for (ReactomeDatabaseObject obj : objects) {
+			String query = "hasMember=" + obj.getDbId();
+			List<ReactomeDatabaseObject> complexes = getSimpleObjectListByQuery(query, ReactomeEntitySet.class);
+			for (ReactomeDatabaseObject complex : complexes) {
+				result.add((ReactomeEntitySet) getFullObjectForDbId(complex.getDbId()));
+			}
+			query = "hasCandidate=" + obj.getDbId();
+			complexes = getSimpleObjectListByQuery(query, ReactomeCandidateSet.class);
+			for (ReactomeDatabaseObject complex : complexes) {
+				result.add((ReactomeCandidateSet) getFullObjectForDbId(complex.getDbId()));
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Returns list of ReactomeEntityWithAccessionedSequence that refers to
+	 * parameter reference.
+	 * 
+	 * @param reference
+	 *          object to which result should refer to
+	 * @return list of ReactomeEntityWithAccessionedSequence that contain one of
+	 *         the elements given in the parameter
+	 * @throws IOException
+	 *           thrown when there is a problem with connection to reactome
+	 *           database
+	 */
+	private List<ReactomePhysicalEntity> getPhysicalEnitiesForReferenceSequence(ReactomeReferenceSequence reference) throws IOException {
+		List<ReactomePhysicalEntity> result = new ArrayList<ReactomePhysicalEntity>();
+
+		String query = "referenceEntity=" + reference.getDbId();
+		List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeEntityWithAccessionedSequence.class);
+
+		for (ReactomeDatabaseObject object : objects) {
+			result.add((ReactomePhysicalEntity) getFullObjectForDbId(object.getDbId()));
+		}
+		return result;
+	}
+
+	/**
+	 * Returns list of ReactomeSimpleEntity that refers to parameter reference.
+	 * 
+	 * @param reference
+	 *          object to which result should refer to
+	 * @return list of ReactomeSimpleEntity that contain one of the elements given
+	 *         in the parameter
+	 * @throws IOException
+	 *           thrown when there is a problem with connection to reactome
+	 *           database
+	 */
+	private List<ReactomeSimpleEntity> getSimpleEntitiesByReferenceMolecule(ReactomeReferenceMolecule reference) throws IOException {
+		List<ReactomeSimpleEntity> result = new ArrayList<ReactomeSimpleEntity>();
+
+		String query = "referenceEntity=" + reference.getDbId();
+		List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeSimpleEntity.class);
+
+		for (ReactomeDatabaseObject object : objects) {
+			result.add((ReactomeSimpleEntity) getFullObjectForDbId(object.getDbId()));
+		}
+		return result;
+	}
+
+	/**
+	 * Ges list of reactions that interact with object given in the parameter.
+	 * 
+	 * @param id
+	 *          identifier of the object that should be included in the result
+	 *          reactions
+	 * @return list of reactions that interact with object given in the parameter
+	 * @throws IOException
+	 *           thrown when there is a problem with connection to reactome
+	 *           database
+	 */
+	public List<ReactomeReactionlikeEvent> getReactionsForEntityId(Integer id) throws IOException {
+		List<ReactomeReactionlikeEvent> result = new ArrayList<ReactomeReactionlikeEvent>();
+
+		String query = "input=" + id;
+		List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeReactionlikeEvent.class);
+
+		for (ReactomeDatabaseObject object : objects) {
+			ReactomeDatabaseObject entity = getFullObjectForDbId(object.getDbId());
+			if (entity instanceof ReactomeReactionlikeEvent) {
+				result.add((ReactomeReactionlikeEvent) entity);
+			}
+		}
+
+		query = "output=" + id;
+		objects = getSimpleObjectListByQuery(query, ReactomeReactionlikeEvent.class);
+
+		for (ReactomeDatabaseObject object : objects) {
+			ReactomeDatabaseObject entity = getFullObjectForDbId(object.getDbId());
+			if (entity instanceof ReactomeReactionlikeEvent) {
+				result.add((ReactomeReactionlikeEvent) entity);
+			}
+		}
+
+		// and now find reaction with apropriate catalyst
+		query = "physicalEntity=" + id;
+		List<ReactomeDatabaseObject> catalysts = getSimpleObjectListByQuery(query, ReactomeCatalystActivity.class);
+		for (ReactomeDatabaseObject catalyst : catalysts) {
+			query = "catalystActivity=" + catalyst.getDbId();
+			objects = getSimpleObjectListByQuery(query, ReactomeReactionlikeEvent.class);
+			for (ReactomeDatabaseObject object : objects) {
+				ReactomeDatabaseObject entity = getFullObjectForDbId(object.getDbId());
+				if (entity instanceof ReactomeReactionlikeEvent) {
+					result.add((ReactomeReactionlikeEvent) entity);
+				}
+			}
+		}
+
+		return result;
+	}
+
+	@Override
+	public Class<?> getTypeForDbId(Integer id) throws ClassNotFoundException, InvalidXmlSchemaException {
+		Node node = getFullNodeForDbId(id);
+		Class<?> result = getTypeForNode(node);
+		return result;
+	}
+
+	/**
+	 * Returns class type of the data represented in the xml node.
+	 * 
+	 * @param node
+	 *          xml node
+	 * @return class type of the data represented in the xml node
+	 * @throws ClassNotFoundException
+	 *           thrown when there is a problem with finding apropriate class
+	 */
+	protected Class<?> getTypeForNode(Node node) throws ClassNotFoundException {
+		Class<?> result = null;
+		for (int i = 0; i < node.getChildNodes().getLength(); i++) {
+			Node child = node.getChildNodes().item(i);
+			if (child.getNodeName().equals("schemaClass")) {
+				// our classes aren't exactly the same as reactome names, change what is
+				// different
+				String shortName = child.getTextContent().replaceAll("GO_", "Go");
+				String className = ReactomeDatabaseObject.class.getPackage().getName() + ".Reactome" + shortName;
+				result = Class.forName(className);
+			}
+		}
+		return result;
+	}
+
+	@Override
+	public ReactomeDatabaseObject getFullObjectForDbId(Integer id) {
+		try {
+			ReactomeDatabaseObject result = null;
+			if (oneInstancePerId) {
+				result = objectMap.get(id);
+				if (result != null) {
+					return result;
+				}
+			}
+			Class<?> classType;
+			Node node = getFullNodeForDbId(id);
+			classType = getTypeForNode(node);
+			ReactomeNodeParser<?> parser = ReactomeParserFactory.getParserForClass(classType);
+			result = parser.parseObject(node);
+			if (oneInstancePerId) {
+				objectMap.put(id, result);
+			}
+			return result;
+		} catch (ClassNotFoundException e) {
+			throw new InvalidArgumentException("Unknown class type: " + e.getMessage());
+		} catch (InvalidXmlSchemaException e) {
+			logger.error(e, e);
+			return null;
+		}
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public void updateOnlyIdFields(ReactomeDatabaseObject object) {
+		DataSourceUpdater dsu = this;
+		for (Method method : object.getClass().getMethods()) {
+
+			if (Modifier.isPublic(method.getModifiers()) && method.getParameterTypes().length == 0
+					&& (method.getName().startsWith("get") || method.getName().startsWith("is"))) {
+
+				if (ReactomeDatabaseObject.class.isAssignableFrom(method.getReturnType())) {
+					try {
+						ReactomeDatabaseObject value = (ReactomeDatabaseObject) method.invoke(object);
+						if (value != null) {
+							if (value.getStatus().equals(ReactomeStatus.ONLY_ID)) {
+								ReactomeDatabaseObject newValue = dsu.getFullObjectForDbId(value.getDbId());
+								String setterName = method.getName();
+								if (setterName.startsWith("get")) {
+									setterName = setterName.replaceFirst("get", "set");
+								} else {
+									setterName = setterName.replaceFirst("is", "set");
+								}
+								try {
+									Method setterMethod = object.getClass().getMethod(setterName, method.getReturnType());
+									setterMethod.invoke(object, newValue);
+								} catch (NoSuchMethodException e) {
+									e.printStackTrace();
+								} catch (IllegalArgumentException e) {
+									logger.error(
+											"Cannot assign " + newValue.getClass() + " (id: " + value.getDbId() + ") to field: " + setterName.replace("set", "") + " ("
+													+ method.getReturnType() + ")");
+								} catch (SecurityException e) {
+
+									e.printStackTrace();
+									// ignore it - however this would be strange
+								}
+							}
+						}
+					} catch (IllegalAccessException e) {
+						e.printStackTrace();
+					} catch (IllegalArgumentException e) {
+						e.printStackTrace();
+					} catch (InvocationTargetException e) {
+						e.printStackTrace();
+						// ignore it
+					}
+
+				} else if (List.class.isAssignableFrom(method.getReturnType())) {
+					try {
+						@SuppressWarnings("rawtypes")
+						List list = (List) method.invoke(object);
+						for (int i = 0; i < list.size(); i++) {
+							Object obj = list.get(i);
+							if (obj instanceof ReactomeDatabaseObject) {
+								if (((ReactomeDatabaseObject) obj).getStatus().equals(ReactomeStatus.ONLY_ID)) {
+									ReactomeDatabaseObject newValue = dsu.getFullObjectForDbId(((ReactomeDatabaseObject) obj).getDbId());
+									list.set(i, newValue);
+								}
+							}
+						}
+					} catch (IllegalAccessException e) {
+						e.printStackTrace();
+					} catch (IllegalArgumentException e) {
+						e.printStackTrace();
+					} catch (InvocationTargetException e) {
+						e.printStackTrace();
+						// ignore it
+					}
+				}
+			}
+		}
+	}
+
+	@Override
+	public ReactomeDatabaseObject getFullObjectForStableIdentifier(String stableIdentifier) throws IOException {
+		if (stableIdentifier == null) {
+			return null;
+		}
+		String[] tmp = stableIdentifier.split("\\.");
+		String identifier = tmp[0];
+		String version = "0";
+		if (tmp.length > 1) {
+			version = tmp[1];
+		}
+		return getFullObjectForStableIdentifier(identifier, version);
+	}
+
+	@Override
+	public ReactomeDatabaseObject getFullObjectForStableIdentifier(String identifier, String version) throws IOException {
+		String stableIdentifierQuery = "identifier=" + identifier;
+
+		List<ReactomeDatabaseObject> stableIdentifiers = getSimpleObjectListByQuery(stableIdentifierQuery, ReactomeStableIdentifier.class);
+
+		ReactomeStableIdentifier newestIdentifier = null;
+		ReactomeStableIdentifier matchedIdentifier = null;
+
+		for (ReactomeDatabaseObject object : stableIdentifiers) {
+			ReactomeStableIdentifier entity = (ReactomeStableIdentifier) getFullObjectForDbId(object.getDbId());
+			if (newestIdentifier == null) {
+				newestIdentifier = entity;
+			} else {
+				try {
+					Integer id1 = Integer.parseInt(newestIdentifier.getIdentifierVersion());
+					Integer id2 = Integer.parseInt(entity.getIdentifierVersion());
+					if (id2 > id1) {
+						newestIdentifier = entity;
+					}
+				} catch (Exception e) {
+					logger.error(e.getMessage(), e);
+				}
+			}
+			if (entity.getDisplayName().equals(identifier + "." + version) || entity.getIdentifierVersion().equalsIgnoreCase(version)) {
+				matchedIdentifier = entity;
+			}
+		}
+		if (matchedIdentifier == null) {
+			if (newestIdentifier != null) {
+				logger.warn(
+						"Invalid REACTOME stable identifier: \"" + identifier + "." + version + "\". Using another similar: " + newestIdentifier.getIdentifier() + "."
+								+ newestIdentifier.getIdentifierVersion());
+			}
+			matchedIdentifier = newestIdentifier;
+		}
+		if (matchedIdentifier != null) {
+			String query = "stableIdentifier=" + matchedIdentifier.getDbId();
+			List<ReactomeDatabaseObject> objects = getSimpleObjectListByQuery(query, ReactomeDatabaseObject.class);
+
+			for (ReactomeDatabaseObject object : objects) {
+				return getFullObjectForDbId(object.getDbId());
+			}
+
+		}
+		return null;
+	}
+
+	// ------------------------------------------------
+
+	// Methods that directly connect to reactome database (via restfull API)
+
+	// ------------------------------------------------
+
+	/**
+	 * This method get content of the page of the url (and post content).
+	 * 
+	 * @param url
+	 *          url address to connect
+	 * @param postParam
+	 *          params of the post method
+	 * @param type
+	 *          MIME type of the result
+	 * @param method
+	 *          request method (POST/GET)
+	 * @return return the string with the content of the webpage
+	 * @throws IOException
+	 *           thrown when there are some problem with network connection
+	 */
+	protected String getResponse(String url, String postParam, MimeType type, HttpConnectionMethodType method) throws IOException {
+		URL obj = new URL(url);
+		HttpURLConnection con = (HttpURLConnection) obj.openConnection();
+
+		// add reuqest header
+		con.setRequestMethod(method.name());
+		con.setRequestProperty("Accept", type.getTextRepresentation());
+		con.setRequestProperty("Content-Type", type.getTextRepresentation());
+		con.setConnectTimeout(CONNECTION_TIMEOUT);
+		con.setReadTimeout(CONNECTION_TIMEOUT);
+
+		String urlParameters = postParam;
+
+		logger.debug("Sending '" + method + "' request to URL : " + url);
+		if (method.name().equals("POST")) {
+			logger.debug("Parameters : " + urlParameters);
+		}
+
+		// Send post request
+		con.setDoOutput(true);
+		if (method.name().equalsIgnoreCase("POST")) {
+			DataOutputStream wr = new DataOutputStream(con.getOutputStream());
+			wr.writeBytes(urlParameters);
+			wr.flush();
+			wr.close();
+		}
+
+		int responseCode = con.getResponseCode();
+		logger.debug("Response Code : " + responseCode);
+
+		String result = IOUtils.toString(con.getInputStream());
+		logger.debug(result);
+		return result;
+	}
+
+	@Override
+	public List<ReactomeDatabaseObject> getSimpleObjectListByQuery(String query, Class<? extends ReactomeDatabaseObject> clazz) throws IOException {
+		if (query.contains("\n")) {
+			throw new InvalidArgumentException("Query cannot contain new line character");
+		}
+		ReactomeNodeParser<?> parser = ReactomeParserFactory.getParserForClass(clazz);
+		List<ReactomeDatabaseObject> result = new ArrayList<ReactomeDatabaseObject>();
+
+		String url = REACTOME_URL + "listByQuery/" + clazz.getSimpleName().replaceFirst("Reactome", "").replaceAll("Go", "GO_");
+
+		String key = query + "\n" + url;
+
+		Node node = getCacheNode(key);
+		NodeList nodes = null;
+		if (node != null) {
+			nodes = node.getChildNodes();
+		} else {
+			try {
+				nodes = getNodesFromServer(query, url);
+			} catch (InvalidXmlSchemaException e) {
+				throw new IOException(e);
+			}
+			setCacheNode(key, nodes.item(0));
+			nodes = nodes.item(0).getChildNodes();
+		}
+		for (int i = 0; i < nodes.getLength(); i++) {
+			if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
+				continue;
+			}
+			ReactomeDatabaseObject object = parser.parseSimplifiedObject(nodes.item(i));
+			result.add(object);
+		}
+		return result;
+	}
+
+	/**
+	 * Returns list of nodes from the server identified by the query and POST
+	 * params.
+	 * 
+	 * @param query
+	 *          string query to the database sent by POST method
+	 * @param url
+	 *          direct url to the API
+	 * @return list of nodes from the server identified by the query and POST
+	 *         params.
+	 * @throws IOException
+	 *           thrown when there are some problem with network connection
+	 * @throws InvalidXmlSchemaException
+	 *           thrown when there is a problem with xml
+	 */
+	private NodeList getNodesFromServer(String query, String url) throws IOException, InvalidXmlSchemaException {
+		String response = getResponse(url, query, MimeType.XML, HttpConnectionMethodType.POST);
+		logger.debug(response);
+		Node node = XmlParser.getXmlDocumentFromString(response);
+		NodeList nodes = node.getChildNodes();
+		if (nodes.getLength() < 1) {
+			throw new InvalidArgumentException("Problem with xml document");
+		}
+		return nodes;
+	}
+
+	/**
+	 * This method returns xml NODE for object identified by id (identifier in
+	 * reactome database). However if object is in local cache then local copy is
+	 * returned. If object doesn't exist in local cache then after retrieving it
+	 * from reactome is put to the cache.
+	 * 
+	 * @param id
+	 *          identifier in reactome database
+	 * @return xml node for the id given reactome id
+	 * @throws InvalidXmlSchemaException
+	 *           thrown when there is a problem with xml
+	 */
+	@Override
+	public Node getFullNodeForDbId(Integer id) throws InvalidXmlSchemaException {
+		Node result = getCacheNode(IDENTIFIER_QUERY_PREFIX + id);
+		if (result != null) {
+			return result;
+		}
+
+		String response;
+		String url = REACTOME_URL + "queryById/DatabaseObject/" + id;
+		try {
+			response = getResponse(url, "", MimeType.XML, HttpConnectionMethodType.GET);
+			Document doc = XmlParser.getXmlDocumentFromString(response);
+			NodeList nodes = doc.getChildNodes();
+			result = nodes.item(0);
+			setCacheNode(IDENTIFIER_QUERY_PREFIX + id, result);
+			return result;
+		} catch (IOException e) {
+			logger.error(e.getMessage(), e);
+			return null;
+		}
+	}
+
+	@Override
+	public Map<Integer, ReactomeDatabaseObject> getFullObjectsForDbIds(List<Integer> ids) throws ClassNotFoundException, IOException {
+		Map<Integer, ReactomeDatabaseObject> result = new HashMap<Integer, ReactomeDatabaseObject>();
+		for (Integer integer : ids) {
+			result.put(integer, getFullObjectForDbId(integer));
+		}
+
+		return result;
+
+	}
+
+	@Override
+	public List<ReactomePhysicalEntity> getEntitiesForSetOfIds(Set<MiriamData> identifiers) throws IOException {
+		return getEntitiesForUniprotId(identifiers);
+	}
+
+	@Override
+	public ExternalServiceStatus getServiceStatus() {
+		ExternalServiceStatus status = new ExternalServiceStatus(
+				"Reactome RESTful API", "http://reactome.org/ReactomeRESTfulAPI/ReactomeRESTFulAPI.html");
+
+		GeneralCacheInterface cacheCopy = getCache();
+		this.setCache(null);
+
+		try {
+			ReactomeDatabaseObject obj = getFullObjectForDbId(CHECK_SERVICE_STATUS_EXAMPLE);
+			status.setStatus(ExternalServiceStatusType.OK);
+			if (obj == null) {
+				status.setStatus(ExternalServiceStatusType.DOWN);
+			} else if (obj.getClass().equals(ReactomeDatabaseObject.class)) {
+				status.setStatus(ExternalServiceStatusType.CHANGED);
+			}
+		} catch (Exception e) {
+			logger.error(status.getName() + " is down", e);
+			status.setStatus(ExternalServiceStatusType.DOWN);
+		}
+		this.setCache(cacheCopy);
+		return status;
+	}
+
+}