diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotator.java
index a95985e33938f17feadd1366c4d683bb82a491dd..99b71fdd1085e3955d2fd206b883390e3f8cd96a 100644
--- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotator.java
+++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotator.java
@@ -1,5 +1,7 @@
 package lcsb.mapviewer.annotation.services.annotators;
 
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -7,6 +9,7 @@ import java.util.List;
 import java.util.Queue;
 import java.util.Set;
 
+import javax.xml.namespace.QName;
 import javax.xml.ws.WebServiceException;
 
 import org.apache.log4j.Logger;
@@ -44,464 +47,466 @@ import uk.ac.ebi.chebi.webapps.chebiWS.model.StarsCategory;
  */
 public class ChebiAnnotator extends ElementAnnotator implements IExternalService {
 
-	/**
-	 * What is the maximum number of results that should be retrieved from chebi
-	 * API.
-	 */
-	static final int						MAX_SEARCH_RESULTS_FROM_CHEBI_API	= 50;
-
-	/**
-	 * Prefix used for entries identified by chebi id.
-	 */
-	public static final String	ID_PREFIX													= "id: ";
-
-	/**
-	 * Prefix used for ontology list for single chebi id.
-	 */
-	static final String					ONTOLOGY_PREFIX										= "ontology: ";
-
-	/**
-	 * Length of the prefix used for entries identified by chebi id.
-	 */
-	private static final int		ID_PREFIX_LENGTH									= ID_PREFIX.length();
-
-	/**
-	 * Prefix used for entries identified by name.
-	 */
-	private static final String	NAME_PREFIX												= "name: ";
-
-	/**
-	 * Length of the prefix used for entries identified by name.
-	 */
-	private static final int		NAME_PREFIX_LENGTH								= NAME_PREFIX.length();
-
-	/**
-	 * Class used for some simple operations on {@link BioEntity} elements.
-	 */
-	private ElementUtils				elementUtils											= new ElementUtils();
-
-	@Override
-	public String refreshCacheQuery(Object query) throws SourceNotAvailable {
-		String result = null;
-		try {
-			if (query instanceof String) {
-				String name = (String) query;
-				if (name.startsWith(ID_PREFIX)) {
-					String id = name.substring(ID_PREFIX_LENGTH);
-					result = chebiSerializer.objectToString(getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, id)));
-				} else if (name.startsWith(ONTOLOGY_PREFIX)) {
-					String id = name.substring(ONTOLOGY_PREFIX.length());
-					result = miriamListToStringList(getOntologyChebiIdsForChebi(new MiriamData(MiriamType.CHEBI, id)));
-				} else if (name.startsWith(NAME_PREFIX)) {
-					name = name.substring(NAME_PREFIX_LENGTH);
-					MiriamData md = getChebiForChebiName(name);
-					if (md != null) {
-						result = md.getResource();
-					}
-				} 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());
-			}
-		} catch (ChebiSearchException e) {
-			throw new SourceNotAvailable(e);
-		}
-
-		return result;
-	}
-
-	/**
-	 * Default class logger.
-	 */
-	private static Logger					logger = Logger.getLogger(ChebiAnnotator.class);
-
-	/**
-	 * Client to chebi API.
-	 */
-	private ChebiWebServiceClient	client = null;
-
-	/**
-	 * Object that allows to serialize {@link Chebi} elements into xml string and
-	 * deserialize xml into {@link Chebi} objects.
-	 */
-	private XmlSerializer<Chebi>	chebiSerializer;
-
-	/**
-	 * Default constructor. Initializes structures used for transforming
-	 * {@link Chebi} from/to xml.
-	 */
-	public ChebiAnnotator() {
-		super(ChebiAnnotator.class, new Class[] { Chemical.class }, true);
-		chebiSerializer = new XmlSerializer<>(Chebi.class);
-	}
-
-	/**
-	 * Returns {@link MiriamData} for given chebi name.
-	 * 
-	 * @param name
-	 *          name of the entry in chebi database.
-	 * @return {@link MiriamData} entry for given chebi name
-	 * @throws ChebiSearchException
-	 *           thrown when there is aproblem with accessing data from external
-	 *           chebi database
-	 */
-	public MiriamData getChebiForChebiName(String name) throws ChebiSearchException {
-		if (name == null) {
-			return null;
-		}
-		// Japanese people use strange dash symbol
-		name = name.replace("−", "-").toLowerCase().trim();
-
-		String id = getCacheValue("name: " + name);
-		if (id != null) {
-			return new MiriamData(MiriamType.CHEBI, id);
-		}
-		try {
-			ChebiWebServiceClient client = getClient();
-
-			LiteEntityList entities = client.getLiteEntity(name, SearchCategory.CHEBI_NAME, MAX_SEARCH_RESULTS_FROM_CHEBI_API, StarsCategory.ALL);
-			List<LiteEntity> resultList = entities.getListElement();
-
-			for (LiteEntity liteEntity : resultList) {
-				Entity entity = client.getCompleteEntity(liteEntity.getChebiId());
-				String chebiName = entity.getChebiAsciiName();
-				if (chebiName.trim().equalsIgnoreCase(name)) {
-					setCacheValue("name: " + name, entity.getChebiId());
-					return new MiriamData(MiriamType.CHEBI, entity.getChebiId());
-				}
-				for (DataItem dataItem : entity.getFormulae()) {
-					String synonym = dataItem.getData();
-					if (synonym.trim().equalsIgnoreCase(name)) {
-						setCacheValue("name: " + name, entity.getChebiId());
-						return new MiriamData(MiriamType.CHEBI, entity.getChebiId());
-					}
-				}
-				for (DataItem dataItem : entity.getSynonyms()) {
-					String synonym = dataItem.getData();
-					if (synonym.trim().equalsIgnoreCase(name)) {
-						setCacheValue("name: " + name, entity.getChebiId());
-						return new MiriamData(MiriamType.CHEBI, entity.getChebiId());
-					}
-				}
-			}
-			entities = client.getLiteEntity(name, SearchCategory.ALL, MAX_SEARCH_RESULTS_FROM_CHEBI_API, StarsCategory.ALL);
-			resultList = entities.getListElement();
-			for (LiteEntity liteEntity : resultList) {
-				Entity entity = client.getCompleteEntity(liteEntity.getChebiId());
-				for (DataItem dataItem : entity.getFormulae()) {
-					String formula = dataItem.getData();
-					if (formula.trim().equalsIgnoreCase(name)) {
-						setCacheValue("name: " + name, entity.getChebiId());
-						return new MiriamData(MiriamType.CHEBI, entity.getChebiId());
-					}
-				}
-				for (DataItem dataItem : entity.getSynonyms()) {
-					String synonym = dataItem.getData();
-					if (synonym.trim().equalsIgnoreCase(name)) {
-						setCacheValue("name: " + name, entity.getChebiId());
-						return new MiriamData(MiriamType.CHEBI, entity.getChebiId());
-					}
-				}
-			}
-		} catch (ChebiWebServiceFault_Exception e) {
-			throw new ChebiSearchException("Problem with chebi connection", e);
-		}
-		return null;
-	}
-
-	/**
-	 * This method returns list of ChEBI identifiers that correspond to the whole
-	 * chebi tree for a given chemical name.
-	 * 
-	 * @param name
-	 *          - name of chemical
-	 * @return - list of ChEBI identifiers
-	 * @throws ChebiSearchException
-	 *           thrown when there is aproblem with accessing data from external
-	 *           chebi database
-	 */
-	public List<MiriamData> getOntologyChebiIdsForChebiName(String name) throws ChebiSearchException {
-		// Japanese people use strange dash symbol
-		name = name.replace("−", "-").toLowerCase().trim();
-
-		MiriamData md = getChebiForChebiName(name);
-		return getOntologyChebiIdsForChebi(md);
-	}
-
-	/**
-	 * This method returns list of ChEBI identifiers that correspond to the whole
-	 * chebi tree for a given chebi identifier.
-	 * 
-	 * @param md
-	 *          - chebi identifier
-	 * @return - list of ChEBI identifiers
-	 * @throws ChebiSearchException
-	 *           thrown when there is a problemw ith accessing information from
-	 *           external chebi database
-	 */
-	public List<MiriamData> getOntologyChebiIdsForChebi(MiriamData md) throws ChebiSearchException {
-		if (md == null) {
-			return new ArrayList<>();
-		}
-		String query = ONTOLOGY_PREFIX + md.getResource();
-
-		String res = getCacheValue(query);
-		if (res != null) {
-			return chebiStringListToMiriam(res);
-		}
-
-		List<MiriamData> result = new ArrayList<MiriamData>();
-		try {
-			ChebiWebServiceClient client = getClient();
-
-			Set<String> children = new HashSet<String>();
-			children.add(md.getResource());
-			Queue<String> queue = new LinkedList<String>();
-			queue.add(md.getResource());
-			while (!queue.isEmpty()) {
-				String element = queue.poll();
-				result.add(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CHEBI, element));
-				Entity entity = client.getCompleteEntity(element);
-				for (OntologyDataItem di : entity.getOntologyChildren()) {
-					if (!children.contains(di.getChebiId()) && "is a".equals(di.getType())) {
-						children.add(di.getChebiId());
-						queue.add(di.getChebiId());
-					}
-				}
-			}
-
-			Set<String> parents = new HashSet<String>();
-			parents.add(md.getResource());
-			queue = new LinkedList<String>();
-			queue.add(md.getResource());
-			while (!queue.isEmpty()) {
-				String element = queue.poll();
-				Entity entity = client.getCompleteEntity(element);
-				for (OntologyDataItem di : entity.getOntologyParents()) {
-					if (!parents.contains(di.getChebiId()) && "is a".equals(di.getType())) {
-						result.add(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CHEBI, di.getChebiId()));
-						parents.add(di.getChebiId());
-						queue.add(di.getChebiId());
-					}
-				}
-			}
-			String value = miriamListToStringList(result);
-
-			setCacheValue(query, value);
-		} catch (ChebiWebServiceFault_Exception e) {
-			throw new ChebiSearchException("Problem with chebi", e);
-		}
-		return result;
-	}
-
-	/**
-	 * Serialize list of chebi identifiers.
-	 * 
-	 * @param list
-	 *          list of chebi identfiers
-	 * @return string with identifiers
-	 */
-	private String miriamListToStringList(List<MiriamData> list) {
-		StringBuilder result = new StringBuilder("");
-		boolean first = true;
-		for (MiriamData miriamData : list) {
-			if (!first) {
-				result.append(",");
-			}
-			first = false;
-			result.append(miriamData.getResource());
-		}
-
-		return result.toString();
-	}
-
-	/**
-	 * Deserialize list of chebi identifiers.
-	 * 
-	 * @param res
-	 *          text with list of chebi identifeirs
-	 * @return list with chebi identifiers
-	 */
-	private List<MiriamData> chebiStringListToMiriam(String res) {
-		String[] tmp = res.split(",");
-		List<MiriamData> result = new ArrayList<MiriamData>();
-		for (String string : tmp) {
-			result.add(new MiriamData(MiriamType.CHEBI, string));
-		}
-		return result;
-	}
-
-	/**
-	 * This method returns ChEBI structure for identifier given as a parameter.
-	 * 
-	 * @param md
-	 *          {@link MiriamData} with ChEBI identifier
-	 * @return - ChEBI structure
-	 * @throws ChebiSearchException
-	 *           thrown when there is a problemw ith accessing information from
-	 *           external chebi database
-	 */
-	public Chebi getChebiElementForChebiId(MiriamData md) throws ChebiSearchException {
-		if (!MiriamType.CHEBI.equals(md.getDataType())) {
-			throw new InvalidArgumentException(MiriamType.CHEBI + " expected");
-		}
-		String id = md.getResource().toLowerCase().trim();
-		if (!id.contains("chebi")) {
-			id = "chebi:" + id;
-		}
-		Chebi result = chebiSerializer.xmlToObject(getCacheNode("id: " + id));
-		if (result != null) {
-			return result;
-		}
-		try {
-			ChebiWebServiceClient client = getClient();
-
-			LiteEntityList entities = client.getLiteEntity(id, SearchCategory.CHEBI_ID, MAX_SEARCH_RESULTS_FROM_CHEBI_API, StarsCategory.ALL);
-			List<LiteEntity> resultList = entities.getListElement();
-
-			for (LiteEntity liteEntity : resultList) {
-				Entity entity = client.getCompleteEntity(liteEntity.getChebiId());
-
-				if (entity.getChebiId().trim().equalsIgnoreCase(id)) {
-					result = new Chebi(entity);
-				}
-			}
-
-			if (result != null) {
-				setCacheValue("id: " + id, chebiSerializer.objectToString(result));
-			}
-			return result;
-		} catch (ChebiWebServiceFault_Exception e) {
-			throw new ChebiSearchException("Problem with chebi", e);
-		}
-	}
-
-	/**
-	 * This method returns common name for chemical identified by chebi id.
-	 * 
-	 * @param id
-	 *          - chebi identifier in format (XXXXX represents numerical
-	 *          identifier): "CHEBI:XXXXX" or "XXXXX"
-	 * @return common name of chemical
-	 * @throws ChebiSearchException
-	 *           thrown when there is a problemw ith accessing information from
-	 *           external chebi database
-	 */
-	protected String getChebiNameForChebiId(MiriamData id) throws ChebiSearchException {
-		if (id == null) {
-			return null;
-		}
-		Chebi chebi = getChebiElementForChebiId(id);
-		if (chebi == null) {
-			return null;
-		}
-		return chebi.getName();
-	}
-
-	@Override
-	public ExternalServiceStatus getServiceStatus() {
-		ExternalServiceStatus status = new ExternalServiceStatus(getCommonName(), getUrl());
-
-		GeneralCacheInterface cacheCopy = getCache();
-		this.setCache(null);
-		try {
-			MiriamData data = getChebiForChebiName("water");
-			status.setStatus(ExternalServiceStatusType.OK);
-			if (data == null || !data.getResource().equals("CHEBI:15377")) {
-				status.setStatus(ExternalServiceStatusType.CHANGED);
-			}
-		} catch (Exception e) {
-			logger.error(status.getName() + " is down", e);
-			status.setStatus(ExternalServiceStatusType.DOWN);
-		}
-		this.setCache(cacheCopy);
-		return status;
-	}
-
-	/**
-	 * 
-	 * @return {@link #client}
-	 * @throws ChebiSearchException
-	 *           thrown when there is a problemw ith accessing information from
-	 *           external chebi database
-	 */
-	private ChebiWebServiceClient getClient() throws ChebiSearchException {
-		if (client == null) {
-			try {
-				client = new ChebiWebServiceClient();
-			} catch (WebServiceException exception) {
-				throw new ChebiSearchException("Cannot initialize chebi connector", exception);
-			}
-		}
-		return client;
-	}
-
-	@Override
-	public void annotateElement(BioEntity element) throws AnnotatorException {
-		if (isAnnotatable(element)) {
-			try {
-				String warnPrefix = elementUtils.getElementTag(element, this);
-				if (element.getMiriamData().size() == 0) {
-
-					MiriamData chebi = getChebiForChebiName(element.getName());
-					if (chebi != null) {
-						element.addMiriamData(chebi);
-					} else {
-						logger.warn(warnPrefix + "Chemical name cannot be found in chebi: " + element.getName());
-					}
-				}
-				Chebi chebi = null;
-				for (MiriamData md : element.getMiriamData()) {
-					if (MiriamType.CHEBI.equals(md.getDataType())) {
-						chebi = getChebiElementForChebiId(md);
-					}
-				}
-				Chemical species = (Chemical) element;
-				if (chebi != null) {
-					super.setFullName(species, chebi.getName(), warnPrefix);
-
-					setInchi(species, chebi.getInchi(), warnPrefix);
-					setInchiKey(species, chebi.getInchiKey(), warnPrefix);
-					setSmile(species, chebi.getSmiles(), warnPrefix);
-
-					if (species.getSynonyms().size() == 0) {
-						species.addSynonyms(chebi.getSynonyms());
-					} else {
-						StringSetComparator stringSetComparator = new StringSetComparator();
-						Set<String> set1 = new HashSet<String>();
-						Set<String> set2 = new HashSet<String>();
-
-						set1.addAll(species.getSynonyms());
-						set2.addAll(chebi.getSynonyms());
-
-						if (stringSetComparator.compare(set1, set2) != 0) {
-							logger.warn(warnPrefix + "Different set of synonyms: " + species.getFullName() + ", " + chebi.getName());
-						}
-					}
-				}
-			} catch (ChebiSearchException e) {
-				throw new AnnotatorException("Problem with getting information about chebi", e);
-			}
-		}
-	}
-
-	@Override
-	public String getCommonName() {
-		return MiriamType.CHEBI.getCommonName();
-	}
-
-	@Override
-	public String getUrl() {
-		return MiriamType.CHEBI.getDbHomepage();
-	}
-
-	/**
-	 * @param client
-	 *          the client to set
-	 * @see #client
-	 */
-	void setClient(ChebiWebServiceClient client) {
-		this.client = client;
-	}
+  /**
+   * What is the maximum number of results that should be retrieved from chebi
+   * API.
+   */
+  static final int MAX_SEARCH_RESULTS_FROM_CHEBI_API = 50;
+
+  /**
+   * Prefix used for entries identified by chebi id.
+   */
+  public static final String ID_PREFIX = "id: ";
+
+  /**
+   * Prefix used for ontology list for single chebi id.
+   */
+  static final String ONTOLOGY_PREFIX = "ontology: ";
+
+  /**
+   * Length of the prefix used for entries identified by chebi id.
+   */
+  private static final int ID_PREFIX_LENGTH = ID_PREFIX.length();
+
+  /**
+   * Prefix used for entries identified by name.
+   */
+  private static final String NAME_PREFIX = "name: ";
+
+  /**
+   * Length of the prefix used for entries identified by name.
+   */
+  private static final int NAME_PREFIX_LENGTH = NAME_PREFIX.length();
+
+  /**
+   * Class used for some simple operations on {@link BioEntity} elements.
+   */
+  private ElementUtils elementUtils = new ElementUtils();
+
+  @Override
+  public String refreshCacheQuery(Object query) throws SourceNotAvailable {
+    String result = null;
+    try {
+      if (query instanceof String) {
+        String name = (String) query;
+        if (name.startsWith(ID_PREFIX)) {
+          String id = name.substring(ID_PREFIX_LENGTH);
+          result = chebiSerializer.objectToString(getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, id)));
+        } else if (name.startsWith(ONTOLOGY_PREFIX)) {
+          String id = name.substring(ONTOLOGY_PREFIX.length());
+          result = miriamListToStringList(getOntologyChebiIdsForChebi(new MiriamData(MiriamType.CHEBI, id)));
+        } else if (name.startsWith(NAME_PREFIX)) {
+          name = name.substring(NAME_PREFIX_LENGTH);
+          MiriamData md = getChebiForChebiName(name);
+          if (md != null) {
+            result = md.getResource();
+          }
+        } 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());
+      }
+    } catch (ChebiSearchException e) {
+      throw new SourceNotAvailable(e);
+    }
+
+    return result;
+  }
+
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(ChebiAnnotator.class);
+
+  /**
+   * Client to chebi API.
+   */
+  private ChebiWebServiceClient client = null;
+
+  /**
+   * Object that allows to serialize {@link Chebi} elements into xml string and
+   * deserialize xml into {@link Chebi} objects.
+   */
+  private XmlSerializer<Chebi> chebiSerializer;
+
+  /**
+   * Default constructor. Initializes structures used for transforming
+   * {@link Chebi} from/to xml.
+   */
+  public ChebiAnnotator() {
+    super(ChebiAnnotator.class, new Class[] { Chemical.class }, true);
+    chebiSerializer = new XmlSerializer<>(Chebi.class);
+  }
+
+  /**
+   * Returns {@link MiriamData} for given chebi name.
+   * 
+   * @param name
+   *          name of the entry in chebi database.
+   * @return {@link MiriamData} entry for given chebi name
+   * @throws ChebiSearchException
+   *           thrown when there is aproblem with accessing data from external
+   *           chebi database
+   */
+  public MiriamData getChebiForChebiName(String name) throws ChebiSearchException {
+    if (name == null) {
+      return null;
+    }
+    // Japanese people use strange dash symbol
+    name = name.replace("−", "-").toLowerCase().trim();
+
+    String id = getCacheValue("name: " + name);
+    if (id != null) {
+      return new MiriamData(MiriamType.CHEBI, id);
+    }
+    try {
+      ChebiWebServiceClient client = getClient();
+
+      LiteEntityList entities = client.getLiteEntity(name, SearchCategory.CHEBI_NAME, MAX_SEARCH_RESULTS_FROM_CHEBI_API,
+          StarsCategory.ALL);
+      List<LiteEntity> resultList = entities.getListElement();
+
+      for (LiteEntity liteEntity : resultList) {
+        Entity entity = client.getCompleteEntity(liteEntity.getChebiId());
+        String chebiName = entity.getChebiAsciiName();
+        if (chebiName.trim().equalsIgnoreCase(name)) {
+          setCacheValue("name: " + name, entity.getChebiId());
+          return new MiriamData(MiriamType.CHEBI, entity.getChebiId());
+        }
+        for (DataItem dataItem : entity.getFormulae()) {
+          String synonym = dataItem.getData();
+          if (synonym.trim().equalsIgnoreCase(name)) {
+            setCacheValue("name: " + name, entity.getChebiId());
+            return new MiriamData(MiriamType.CHEBI, entity.getChebiId());
+          }
+        }
+        for (DataItem dataItem : entity.getSynonyms()) {
+          String synonym = dataItem.getData();
+          if (synonym.trim().equalsIgnoreCase(name)) {
+            setCacheValue("name: " + name, entity.getChebiId());
+            return new MiriamData(MiriamType.CHEBI, entity.getChebiId());
+          }
+        }
+      }
+      entities = client.getLiteEntity(name, SearchCategory.ALL, MAX_SEARCH_RESULTS_FROM_CHEBI_API, StarsCategory.ALL);
+      resultList = entities.getListElement();
+      for (LiteEntity liteEntity : resultList) {
+        Entity entity = client.getCompleteEntity(liteEntity.getChebiId());
+        for (DataItem dataItem : entity.getFormulae()) {
+          String formula = dataItem.getData();
+          if (formula.trim().equalsIgnoreCase(name)) {
+            setCacheValue("name: " + name, entity.getChebiId());
+            return new MiriamData(MiriamType.CHEBI, entity.getChebiId());
+          }
+        }
+        for (DataItem dataItem : entity.getSynonyms()) {
+          String synonym = dataItem.getData();
+          if (synonym.trim().equalsIgnoreCase(name)) {
+            setCacheValue("name: " + name, entity.getChebiId());
+            return new MiriamData(MiriamType.CHEBI, entity.getChebiId());
+          }
+        }
+      }
+    } catch (ChebiWebServiceFault_Exception e) {
+      throw new ChebiSearchException("Problem with chebi connection", e);
+    }
+    return null;
+  }
+
+  /**
+   * This method returns list of ChEBI identifiers that correspond to the whole
+   * chebi tree for a given chemical name.
+   * 
+   * @param name
+   *          - name of chemical
+   * @return - list of ChEBI identifiers
+   * @throws ChebiSearchException
+   *           thrown when there is aproblem with accessing data from external
+   *           chebi database
+   */
+  public List<MiriamData> getOntologyChebiIdsForChebiName(String name) throws ChebiSearchException {
+    // Japanese people use strange dash symbol
+    name = name.replace("−", "-").toLowerCase().trim();
+
+    MiriamData md = getChebiForChebiName(name);
+    return getOntologyChebiIdsForChebi(md);
+  }
+
+  /**
+   * This method returns list of ChEBI identifiers that correspond to the whole
+   * chebi tree for a given chebi identifier.
+   * 
+   * @param md
+   *          - chebi identifier
+   * @return - list of ChEBI identifiers
+   * @throws ChebiSearchException
+   *           thrown when there is a problemw ith accessing information from
+   *           external chebi database
+   */
+  public List<MiriamData> getOntologyChebiIdsForChebi(MiriamData md) throws ChebiSearchException {
+    if (md == null) {
+      return new ArrayList<>();
+    }
+    String query = ONTOLOGY_PREFIX + md.getResource();
+
+    String res = getCacheValue(query);
+    if (res != null) {
+      return chebiStringListToMiriam(res);
+    }
+
+    List<MiriamData> result = new ArrayList<MiriamData>();
+    try {
+      ChebiWebServiceClient client = getClient();
+
+      Set<String> children = new HashSet<String>();
+      children.add(md.getResource());
+      Queue<String> queue = new LinkedList<String>();
+      queue.add(md.getResource());
+      while (!queue.isEmpty()) {
+        String element = queue.poll();
+        result.add(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CHEBI, element));
+        Entity entity = client.getCompleteEntity(element);
+        for (OntologyDataItem di : entity.getOntologyChildren()) {
+          if (!children.contains(di.getChebiId()) && "is a".equals(di.getType())) {
+            children.add(di.getChebiId());
+            queue.add(di.getChebiId());
+          }
+        }
+      }
+
+      Set<String> parents = new HashSet<String>();
+      parents.add(md.getResource());
+      queue = new LinkedList<String>();
+      queue.add(md.getResource());
+      while (!queue.isEmpty()) {
+        String element = queue.poll();
+        Entity entity = client.getCompleteEntity(element);
+        for (OntologyDataItem di : entity.getOntologyParents()) {
+          if (!parents.contains(di.getChebiId()) && "is a".equals(di.getType())) {
+            result.add(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CHEBI, di.getChebiId()));
+            parents.add(di.getChebiId());
+            queue.add(di.getChebiId());
+          }
+        }
+      }
+      String value = miriamListToStringList(result);
+
+      setCacheValue(query, value);
+    } catch (ChebiWebServiceFault_Exception e) {
+      throw new ChebiSearchException("Problem with chebi", e);
+    }
+    return result;
+  }
+
+  /**
+   * Serialize list of chebi identifiers.
+   * 
+   * @param list
+   *          list of chebi identfiers
+   * @return string with identifiers
+   */
+  private String miriamListToStringList(List<MiriamData> list) {
+    StringBuilder result = new StringBuilder("");
+    boolean first = true;
+    for (MiriamData miriamData : list) {
+      if (!first) {
+        result.append(",");
+      }
+      first = false;
+      result.append(miriamData.getResource());
+    }
+
+    return result.toString();
+  }
+
+  /**
+   * Deserialize list of chebi identifiers.
+   * 
+   * @param res
+   *          text with list of chebi identifeirs
+   * @return list with chebi identifiers
+   */
+  private List<MiriamData> chebiStringListToMiriam(String res) {
+    String[] tmp = res.split(",");
+    List<MiriamData> result = new ArrayList<MiriamData>();
+    for (String string : tmp) {
+      result.add(new MiriamData(MiriamType.CHEBI, string));
+    }
+    return result;
+  }
+
+  /**
+   * This method returns ChEBI structure for identifier given as a parameter.
+   * 
+   * @param md
+   *          {@link MiriamData} with ChEBI identifier
+   * @return - ChEBI structure
+   * @throws ChebiSearchException
+   *           thrown when there is a problemw ith accessing information from
+   *           external chebi database
+   */
+  public Chebi getChebiElementForChebiId(MiriamData md) throws ChebiSearchException {
+    if (!MiriamType.CHEBI.equals(md.getDataType())) {
+      throw new InvalidArgumentException(MiriamType.CHEBI + " expected");
+    }
+    String id = md.getResource().toLowerCase().trim();
+    if (!id.contains("chebi")) {
+      id = "chebi:" + id;
+    }
+    Chebi result = chebiSerializer.xmlToObject(getCacheNode("id: " + id));
+    if (result != null) {
+      return result;
+    }
+    try {
+      ChebiWebServiceClient client = getClient();
+
+      LiteEntityList entities = client.getLiteEntity(id, SearchCategory.CHEBI_ID, MAX_SEARCH_RESULTS_FROM_CHEBI_API,
+          StarsCategory.ALL);
+      List<LiteEntity> resultList = entities.getListElement();
+
+      for (LiteEntity liteEntity : resultList) {
+        Entity entity = client.getCompleteEntity(liteEntity.getChebiId());
+
+        if (entity.getChebiId().trim().equalsIgnoreCase(id)) {
+          result = new Chebi(entity);
+        }
+      }
+
+      if (result != null) {
+        setCacheValue("id: " + id, chebiSerializer.objectToString(result));
+      }
+      return result;
+    } catch (ChebiWebServiceFault_Exception e) {
+      throw new ChebiSearchException("Problem with chebi", e);
+    }
+  }
+
+  /**
+   * This method returns common name for chemical identified by chebi id.
+   * 
+   * @param id
+   *          - chebi identifier in format (XXXXX represents numerical
+   *          identifier): "CHEBI:XXXXX" or "XXXXX"
+   * @return common name of chemical
+   * @throws ChebiSearchException
+   *           thrown when there is a problemw ith accessing information from
+   *           external chebi database
+   */
+  protected String getChebiNameForChebiId(MiriamData id) throws ChebiSearchException {
+    if (id == null) {
+      return null;
+    }
+    Chebi chebi = getChebiElementForChebiId(id);
+    if (chebi == null) {
+      return null;
+    }
+    return chebi.getName();
+  }
+
+  @Override
+  public ExternalServiceStatus getServiceStatus() {
+    ExternalServiceStatus status = new ExternalServiceStatus(getCommonName(), getUrl());
+
+    GeneralCacheInterface cacheCopy = getCache();
+    this.setCache(null);
+    try {
+      MiriamData data = getChebiForChebiName("water");
+      status.setStatus(ExternalServiceStatusType.OK);
+      if (data == null || !data.getResource().equals("CHEBI:15377")) {
+        status.setStatus(ExternalServiceStatusType.CHANGED);
+      }
+    } catch (Exception e) {
+      logger.error(status.getName() + " is down", e);
+      status.setStatus(ExternalServiceStatusType.DOWN);
+    }
+    this.setCache(cacheCopy);
+    return status;
+  }
+
+  /**
+   * 
+   * @return {@link #client}
+   * @throws ChebiSearchException
+   *           thrown when there is a problem with accessing information from
+   *           external chebi database
+   */
+  private ChebiWebServiceClient getClient() throws ChebiSearchException {
+    if (client == null) {
+      try {
+        client = new ChebiWebServiceClient();
+      } catch (WebServiceException exception) {
+        throw new ChebiSearchException("Cannot initialize chebi connector", exception);
+      }
+    }
+    return client;
+  }
+
+  @Override
+  public void annotateElement(BioEntity element) throws AnnotatorException {
+    if (isAnnotatable(element)) {
+      try {
+        String warnPrefix = elementUtils.getElementTag(element, this);
+        if (element.getMiriamData().size() == 0) {
+
+          MiriamData chebi = getChebiForChebiName(element.getName());
+          if (chebi != null) {
+            element.addMiriamData(chebi);
+          } else {
+            logger.warn(warnPrefix + "Chemical name cannot be found in chebi: " + element.getName());
+          }
+        }
+        Chebi chebi = null;
+        for (MiriamData md : element.getMiriamData()) {
+          if (MiriamType.CHEBI.equals(md.getDataType())) {
+            chebi = getChebiElementForChebiId(md);
+          }
+        }
+        Chemical species = (Chemical) element;
+        if (chebi != null) {
+          super.setFullName(species, chebi.getName(), warnPrefix);
+
+          setInchi(species, chebi.getInchi(), warnPrefix);
+          setInchiKey(species, chebi.getInchiKey(), warnPrefix);
+          setSmile(species, chebi.getSmiles(), warnPrefix);
+
+          if (species.getSynonyms().size() == 0) {
+            species.addSynonyms(chebi.getSynonyms());
+          } else {
+            StringSetComparator stringSetComparator = new StringSetComparator();
+            Set<String> set1 = new HashSet<String>();
+            Set<String> set2 = new HashSet<String>();
+
+            set1.addAll(species.getSynonyms());
+            set2.addAll(chebi.getSynonyms());
+
+            if (stringSetComparator.compare(set1, set2) != 0) {
+              logger.warn(warnPrefix + "Different set of synonyms: " + species.getFullName() + ", " + chebi.getName());
+            }
+          }
+        }
+      } catch (ChebiSearchException e) {
+        throw new AnnotatorException("Problem with getting information about chebi", e);
+      }
+    }
+  }
+
+  @Override
+  public String getCommonName() {
+    return MiriamType.CHEBI.getCommonName();
+  }
+
+  @Override
+  public String getUrl() {
+    return MiriamType.CHEBI.getDbHomepage();
+  }
+
+  /**
+   * @param client
+   *          the client to set
+   * @see #client
+   */
+  void setClient(ChebiWebServiceClient client) {
+    this.client = client;
+  }
 }
diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotatorTest.java
index 8ca9b43561724061b813fab1ca5c433d3673665e..a000cdc242deaf393ac42530947149713043b521 100644
--- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotatorTest.java
+++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotatorTest.java
@@ -39,808 +39,814 @@ import uk.ac.ebi.chebi.webapps.chebiWS.model.OntologyDataItem;
 import uk.ac.ebi.chebi.webapps.chebiWS.model.SearchCategory;
 
 public class ChebiAnnotatorTest extends AnnotationTestFunctions {
-	static Logger									logger = Logger.getLogger(ChebiAnnotatorTest.class);
-
-	@Autowired
-	ChebiAnnotator								backend;
-
-	@Autowired
-	private GeneralCacheInterface	cache;
-
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testGetIdByName() throws Exception {
-		try {
-			MiriamData id = backend.getChebiForChebiName("adenine");
-			assertEquals(new MiriamData(MiriamType.CHEBI, "CHEBI:16708"), id);
-			id = backend.getChebiForChebiName("asdf bvclcx lcxj vxlcvkj");
-			assertNull(id);
-			assertNull(backend.getChebiForChebiName(null));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testNameById() throws Exception {
-		try {
-			String name = backend.getChebiNameForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:16708"));
-			assertEquals("adenine", name);
-			name = backend.getChebiNameForChebiId(new MiriamData(MiriamType.CHEBI, "16708"));
-			assertEquals("adenine", name);
-			name = backend.getChebiNameForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:16708a"));
-			assertNull(name);
-			name = backend.getChebiNameForChebiId(null);
-			assertNull(name);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testChebiById() throws Exception {
-		try {
-			Chebi chebi = backend.getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:16708"));
-			assertNotNull(chebi);
-			assertEquals("adenine", chebi.getName());
-			assertEquals("Nc1ncnc2[nH]cnc12", chebi.getSmiles());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testChebiByIdWhenConnectionFails() throws Exception {
-		try {
-			cache = backend.getCache();
-			// exclude first cached value
-			backend.setCache(null);
-
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-
-			OntologyDataItem item = new OntologyDataItem();
-			item.setChebiId("CHEBI:18008");
-			item.setType("is a");
-
-			Entity entity = new Entity();
-			entity.getOntologyChildren().add(item);
-			entity.getOntologyParents().add(item);
-			when(chebiWebServiceClient.getLiteEntity(any(), any(), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenThrow(new ChebiWebServiceFault_Exception(null, null));
-
-			// we will use mock object as a connection to chebi server
-			backend.setClient(chebiWebServiceClient);
-
-			backend.getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:16708"));
-			fail("Exception expected");
-
-		} catch (ChebiSearchException e) {
-			assertTrue(e.getMessage().contains("Problem with chebi"));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			// restore cache for other tests
-			backend.setCache(cache);
-			// remove mock
-			backend.setClient(null);
-		}
-	}
-
-	@Test
-	public void testChebiByInvalidId() throws Exception {
-		try {
-			backend.getChebiElementForChebiId(new MiriamData(MiriamType.WIKIPEDIA, "water"));
-			fail("Exception expected");
-		} catch (InvalidArgumentException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testChebi() throws Exception {
-		try {
-
-			Chebi chebi = backend.getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:16708"));
-			assertNotNull(chebi);
-			assertEquals("adenine", chebi.getName());
-			assertEquals("Nc1ncnc2[nH]cnc12", chebi.getSmiles());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testChebiOntologyForWater() throws Exception {
-		try {
-
-			Chebi chebi = backend.getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:15377"));
-			assertNotNull(chebi);
-			assertTrue(chebi.getIncomingChebi().size() > 0);
-			assertTrue(chebi.getOutgoingChebi().size() > 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test(timeout = 15000)
-	public void testCachableInterfaceById() throws Exception {
-		String query = "id: CHEBI:28423";
-		String newRes = "hello";
-		try {
-			waitForRefreshCacheQueueToEmpty();
-
-			cache.setCachedQuery(query, backend.getCacheType(), newRes);
-			cache.invalidateByQuery(query, backend.getCacheType());
-
-			waitForRefreshCacheQueueToEmpty();
-
-			String res = cache.getStringByQuery(query, backend.getCacheType());
-
-			assertNotNull(res);
-
-			assertFalse("Value wasn't refreshed from db", newRes.equals(res));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test(timeout = 15000)
-	public void testCachableInterfaceByName() throws Exception {
-		String query = "name: water";
-		String newRes = "hello";
-		try {
-			waitForRefreshCacheQueueToEmpty();
-
-			cache.setCachedQuery(query, backend.getCacheType(), newRes);
-			cache.invalidateByQuery(query, backend.getCacheType());
-
-			waitForRefreshCacheQueueToEmpty();
-
-			String res = cache.getStringByQuery(query, backend.getCacheType());
-
-			assertNotNull(res);
-
-			assertFalse("Value wasn't refreshed from db", newRes.equals(res));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testChebiNameToId1() throws Exception {
-		try {
-			// easy tests with some molecule
-			MiriamData result = backend.getChebiForChebiName("L-glutamate(2-)");
-			assertNotNull(result);
-			assertTrue(result.getResource().contains("CHEBI:29988"));
-			// unknown molecule
-			MiriamData string = backend.getChebiForChebiName("blablasblasblsabsal");
-			assertNull(string);
-
-			// and water
-			result = backend.getChebiForChebiName("H2O");
-			assertNotNull(result);
-			assertTrue(result.getResource().contains("CHEBI:15377"));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testChebiNameToId4() throws Exception {
-		try {
-			// easy tests with some molecule
-			MiriamData result = backend.getChebiForChebiName("Ca2+");
-			assertEquals(new MiriamData(MiriamType.CHEBI, "CHEBI:29108"), result);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testChebiOntologyIds() throws Exception {
-		try {
-			// unknown molecule
-			List<MiriamData> res = backend.getOntologyChebiIdsForChebiName("blablasblasblsabsal");
-			assertNotNull(res);
-			assertEquals(0, res.size());
-
-			// and water
-			res = backend.getOntologyChebiIdsForChebiName("h2o");
-			assertNotNull(res);
-			assertTrue(res.size() > 1);
-			assertTrue(res.contains(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CHEBI, "CHEBI:24431")));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testChebiNameToId2() throws Exception {
-		try {
-			// and now tests more complicated (how to find hydron?)
-			MiriamData md = backend.getChebiForChebiName("hydron");
-			assertNotNull(md);
-			assertTrue(md.getResource().contains("CHEBI:15378"));
-			md = backend.getChebiForChebiName("H+");
-			assertNotNull(md);
-			assertTrue(md.getResource().contains("CHEBI:15378"));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testChebiNameToId3() throws Exception {
-		try {
-			// and the tricky one - I couldn't find it via chebi online search tool...
-			// But java API do the trick...
-			// assertEquals("CHEBI:456214",converter.chebiNameToId("NADP+"));
-			// however manual mapping done by chemist says different...:
-			MiriamData md = backend.getChebiForChebiName("NADP+");
-			assertNotNull(md);
-			assertTrue(md.getResource().contains("CHEBI:18009"));
-			md = backend.getChebiForChebiName("NADP(+)");
-			assertNotNull(md);
-			assertTrue(md.getResource().contains("CHEBI:18009"));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAnnotateChemical() throws Exception {
-		try {
-			SimpleMolecule simpleMolecule = new SimpleMolecule("id");
-			simpleMolecule.setName("water");
-
-			backend.annotateElement(simpleMolecule);
-
-			assertFalse(simpleMolecule.getFullName().equals(""));
-			assertFalse(simpleMolecule.getInChI().equals(""));
-			assertFalse(simpleMolecule.getInChIKey().equals(""));
-			assertFalse(simpleMolecule.getSmiles().equals(""));
-			assertFalse(simpleMolecule.getSynonyms().size() == 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAnnotateWhenConnectionFails() throws Exception {
-		try {
-			SimpleMolecule simpleMolecule = new SimpleMolecule("id");
-			simpleMolecule.setName("water");
-
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-
-			OntologyDataItem item = new OntologyDataItem();
-			item.setChebiId("CHEBI:18008");
-			item.setType("is a");
-
-			Entity entity = new Entity();
-			entity.getOntologyChildren().add(item);
-			entity.getOntologyParents().add(item);
-			when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenThrow(new ChebiWebServiceFault_Exception(null, null));
-
-			// we will use mock object as a connection to chebi server
-			backend.setClient(chebiWebServiceClient);
-
-			backend.setCache(null);
-			backend.annotateElement(simpleMolecule);
-
-			fail("Exceptione expected");
-		} catch (AnnotatorException e) {
-			assertTrue(e.getMessage().contains("Problem with getting information about chebi"));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			backend.setCache(cache);
-			backend.setClient(null);
-		}
-	}
-
-	@Test
-	public void testAnnotateChemicalWithInvalidName() throws Exception {
-		try {
-			SimpleMolecule simpleMolecule = new SimpleMolecule("id");
-			simpleMolecule.setName("blasdh");
-
-			backend.annotateElement(simpleMolecule);
-
-			assertEquals(1, getWarnings().size());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testUpdateChemicalFromDb() throws Exception {
-		try {
-			SimpleMolecule simpleMolecule = new SimpleMolecule("id");
-			simpleMolecule.addMiriamData(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CHEBI, "CHEBI:15377"));
-
-			backend.annotateElement(simpleMolecule);
-
-			assertFalse("".equals(simpleMolecule.getFullName()));
-			assertFalse(simpleMolecule.getInChI().equals(""));
-			assertFalse(simpleMolecule.getInChIKey().equals(""));
-			assertFalse(simpleMolecule.getSmiles().equals(""));
-			assertFalse(simpleMolecule.getSynonyms().size() == 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testUpdateChemicalFromDbWithDifferentData() throws Exception {
-		try {
-			SimpleMolecule simpleMolecule = new SimpleMolecule("id");
-			simpleMolecule.setName("water");
-			simpleMolecule.setFullName("xxx");
-			simpleMolecule.setInChI("x");
-			simpleMolecule.setInChIKey("x");
-			simpleMolecule.setSmiles("x");
-			simpleMolecule.addSynonym("x");
-			simpleMolecule.addMiriamData(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CHEBI, "CHEBI:15377"));
-
-			backend.annotateElement(simpleMolecule);
-
-			assertEquals(5, getWarnings().size());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testGetters() throws Exception {
-		try {
-			assertNotNull(backend.getCommonName());
-			assertNotNull(backend.getUrl());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testRefreshGetOntology() throws Exception {
-		cache = backend.getCache();
-		try {
-			// exclude first cached value
-			backend.setCache(null);
-
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-
-			OntologyDataItem item = new OntologyDataItem();
-			item.setChebiId("CHEBI:18008");
-			item.setType("is a");
-
-			Entity entity = new Entity();
-			entity.getOntologyChildren().add(item);
-			entity.getOntologyParents().add(item);
-			when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
-
-			// we will use mock object as a connection to chebi server
-			backend.setClient(chebiWebServiceClient);
-
-			String query = ChebiAnnotator.ONTOLOGY_PREFIX + "CHEBI:18009";
-			String result = backend.refreshCacheQuery(query);
-			assertNotNull(result);
-			assertTrue(result.contains("CHEBI:18008"));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			// restore cache for other tests
-			backend.setCache(cache);
-			// remove mock
-			backend.setClient(null);
-		}
-	}
-
-	@Test
-	public void testGetChebiForChebiNameInFormula() throws Exception {
-		cache = backend.getCache();
-		try {
-			String chebiId = "CHEBI:18008";
-			String name = "art_name";
-			DataItem matchedElement = new DataItem();
-			matchedElement.setData(name);
-			// exclude first cached value
-			backend.setCache(null);
-
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-
-			OntologyDataItem item = new OntologyDataItem();
-
-			Entity entity = new Entity();
-			entity.getOntologyChildren().add(item);
-			entity.getOntologyParents().add(item);
-			entity.setChebiAsciiName("");
-			entity.getFormulae().add(matchedElement);
-			entity.setChebiId(chebiId);
-
-			when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
-			LiteEntityList liteEntityList = new LiteEntityList();
-
-			LiteEntity liteEntity = new LiteEntity();
-			liteEntityList.getListElement().add(liteEntity);
-			when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenReturn(liteEntityList);
-
-			// we will use mock object as a connection to chebi server
-			backend.setClient(chebiWebServiceClient);
-
-			MiriamData result = backend.getChebiForChebiName(name);
-			assertNotNull(result);
-			assertEquals(chebiId, result.getResource());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			// restore cache for other tests
-			backend.setCache(cache);
-			// remove mock
-			backend.setClient(null);
-		}
-	}
-
-	@Test
-	public void testGetChebiForChebiNameInFormula2() throws Exception {
-		cache = backend.getCache();
-		try {
-			String chebiId = "CHEBI:18008";
-			String name = "art_name";
-			DataItem matchedElement = new DataItem();
-			matchedElement.setData(name);
-			// exclude first cached value
-			backend.setCache(null);
-
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-
-			OntologyDataItem item = new OntologyDataItem();
-
-			Entity entity = new Entity();
-			entity.getOntologyChildren().add(item);
-			entity.getOntologyParents().add(item);
-			entity.setChebiAsciiName("");
-			entity.getFormulae().add(matchedElement);
-			entity.setChebiId(chebiId);
-
-			when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
-			LiteEntityList liteEntityList = new LiteEntityList();
-
-			LiteEntity liteEntity = new LiteEntity();
-			liteEntityList.getListElement().add(liteEntity);
-			// when searching by name return empty list
-			when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenReturn(new LiteEntityList());
-			// when searchng by all return list with elements
-			when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.ALL), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenReturn(liteEntityList);
-
-			// we will use mock object as a connection to chebi server
-			backend.setClient(chebiWebServiceClient);
-
-			MiriamData result = backend.getChebiForChebiName(name);
-			assertNotNull(result);
-			assertEquals(chebiId, result.getResource());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			// restore cache for other tests
-			backend.setCache(cache);
-			// remove mock
-			backend.setClient(null);
-		}
-	}
-
-	@Test
-	public void testGetChebiForChebiNameInSynonym() throws Exception {
-		cache = backend.getCache();
-		try {
-			String chebiId = "CHEBI:18008";
-			String name = "art_name";
-			DataItem matchedElement = new DataItem();
-			matchedElement.setData(name);
-			// exclude first cached value
-			backend.setCache(null);
-
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-
-			OntologyDataItem item = new OntologyDataItem();
-
-			Entity entity = new Entity();
-			entity.getOntologyChildren().add(item);
-			entity.getOntologyParents().add(item);
-			entity.setChebiAsciiName("");
-			entity.getSynonyms().add(matchedElement);
-			entity.setChebiId(chebiId);
-
-			when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
-			LiteEntityList liteEntityList = new LiteEntityList();
-
-			LiteEntity liteEntity = new LiteEntity();
-			liteEntityList.getListElement().add(liteEntity);
-			when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenReturn(liteEntityList);
-
-			// we will use mock object as a connection to chebi server
-			backend.setClient(chebiWebServiceClient);
-
-			MiriamData result = backend.getChebiForChebiName(name);
-			assertNotNull(result);
-			assertEquals(chebiId, result.getResource());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			// restore cache for other tests
-			backend.setCache(cache);
-			// remove mock
-			backend.setClient(null);
-		}
-	}
-
-	@Test
-	public void testGetChebiForChebiNameInSynonym2() throws Exception {
-		cache = backend.getCache();
-		try {
-			String chebiId = "CHEBI:18008";
-			String name = "art_name";
-			DataItem matchedElement = new DataItem();
-			matchedElement.setData(name);
-			// exclude first cached value
-			backend.setCache(null);
-
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-
-			OntologyDataItem item = new OntologyDataItem();
-
-			Entity entity = new Entity();
-			entity.getOntologyChildren().add(item);
-			entity.getOntologyParents().add(item);
-			entity.setChebiAsciiName("");
-			entity.getSynonyms().add(matchedElement);
-			entity.setChebiId(chebiId);
-
-			when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
-			LiteEntityList liteEntityList = new LiteEntityList();
-
-			LiteEntity liteEntity = new LiteEntity();
-			liteEntityList.getListElement().add(liteEntity);
-			// when searching by name return empty list
-			when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenReturn(new LiteEntityList());
-			// when searchng by all return list with elements
-			when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.ALL), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenReturn(liteEntityList);
-
-			// we will use mock object as a connection to chebi server
-			backend.setClient(chebiWebServiceClient);
-
-			MiriamData result = backend.getChebiForChebiName(name);
-			assertNotNull(result);
-			assertEquals(chebiId, result.getResource());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			// restore cache for other tests
-			backend.setCache(cache);
-			// remove mock
-			backend.setClient(null);
-		}
-	}
-
-	@Test
-	public void testGetChebiForChebiNameWithConnectionProblems() throws Exception {
-		cache = backend.getCache();
-		try {
-			// exclude first cached value
-			backend.setCache(null);
-
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-
-			// when searching by name return empty list
-			when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenThrow(new ChebiWebServiceFault_Exception(null, null));
-
-			// we will use mock object as a connection to chebi server
-			backend.setClient(chebiWebServiceClient);
-
-			backend.getChebiForChebiName("bla");
-
-		} catch (ChebiSearchException e) {
-			assertTrue(e.getMessage().contains("Problem with chebi connection"));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			// restore cache for other tests
-			backend.setCache(cache);
-			// remove mock
-			backend.setClient(null);
-		}
-	}
-
-	@Test
-	public void testRefreshWhenProblemWithConnnector() throws Exception {
-		cache = backend.getCache();
-		try {
-			// exclude first cached value
-			backend.setCache(null);
-
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-
-			OntologyDataItem item = new OntologyDataItem();
-			item.setChebiId("CHEBI:18008");
-			item.setType("is a");
-
-			Entity entity = new Entity();
-			entity.getOntologyChildren().add(item);
-			entity.getOntologyParents().add(item);
-			when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenThrow(new ChebiWebServiceFault_Exception(null, null));
-
-			// we will use mock object as a connection to chebi server
-			backend.setClient(chebiWebServiceClient);
-
-			String query = ChebiAnnotator.ONTOLOGY_PREFIX + "CHEBI:18009";
-			backend.refreshCacheQuery(query);
-			fail("Exception expected");
-
-		} catch (SourceNotAvailable e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			// restore cache for other tests
-			backend.setCache(cache);
-			// remove mock
-			backend.setClient(null);
-		}
-	}
-
-	@Test
-	public void testRefreshInvalidQuery() throws Exception {
-		try {
-			backend.refreshCacheQuery("invalid string");
-
-			fail("Exception expected");
-		} catch (InvalidArgumentException e) {
-			assertTrue(e.getMessage().contains("Don't know what to do"));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testRefreshInvalidQuery2() throws Exception {
-		try {
-			backend.refreshCacheQuery(new Object());
-
-			fail("Exception expected");
-		} catch (InvalidArgumentException e) {
-			assertTrue(e.getMessage().contains("Don't know what to do"));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testStatus() throws Exception {
-		try {
-			assertEquals(ExternalServiceStatusType.OK, backend.getServiceStatus().getStatus());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testSimulateDownStatus() throws Exception {
-		backend.setCache(null);
-		try {
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-			when(chebiWebServiceClient.getLiteEntity(any(), any(), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenThrow(new ChebiWebServiceFault_Exception(null, null));
-			backend.setClient(chebiWebServiceClient);
-			assertEquals(ExternalServiceStatusType.DOWN, backend.getServiceStatus().getStatus());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			backend.setCache(cache);
-			backend.setClient(null);
-		}
-	}
-
-	@Test
-	public void testSimulateChangedStatus() throws Exception {
-		backend.setCache(null);
-		try {
-			ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
-			backend.setClient(chebiWebServiceClient);
-
-			String chebiId = "CHEBI:18008";
-			String name = "art";
-			DataItem matchedElement = new DataItem();
-			matchedElement.setData(name);
-			// exclude first cached value
-			backend.setCache(null);
-
-			OntologyDataItem item = new OntologyDataItem();
-
-			Entity entity = new Entity();
-			entity.getOntologyChildren().add(item);
-			entity.getOntologyParents().add(item);
-			entity.setChebiAsciiName("");
-			entity.getSynonyms().add(matchedElement);
-			entity.setChebiId(chebiId);
-
-			when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
-			LiteEntityList liteEntityList = new LiteEntityList();
-
-			LiteEntity liteEntity = new LiteEntity();
-			liteEntityList.getListElement().add(liteEntity);
-			when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenReturn(liteEntityList);
-			when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.ALL), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
-					.thenReturn(liteEntityList);
-
-			assertEquals(ExternalServiceStatusType.CHANGED, backend.getServiceStatus().getStatus());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			backend.setCache(cache);
-			backend.setClient(null);
-		}
-	}
+  static Logger logger = Logger.getLogger(ChebiAnnotatorTest.class);
+
+  @Autowired
+  ChebiAnnotator backend;
+
+  @Autowired
+  private GeneralCacheInterface cache;
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testGetIdByName() throws Exception {
+    try {
+      MiriamData id = backend.getChebiForChebiName("adenine");
+      assertEquals(new MiriamData(MiriamType.CHEBI, "CHEBI:16708"), id);
+      id = backend.getChebiForChebiName("asdf bvclcx lcxj vxlcvkj");
+      assertNull(id);
+      assertNull(backend.getChebiForChebiName(null));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testNameById() throws Exception {
+    try {
+      String name = backend.getChebiNameForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:16708"));
+      assertEquals("adenine", name);
+      name = backend.getChebiNameForChebiId(new MiriamData(MiriamType.CHEBI, "16708"));
+      assertEquals("adenine", name);
+      name = backend.getChebiNameForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:16708a"));
+      assertNull(name);
+      name = backend.getChebiNameForChebiId(null);
+      assertNull(name);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testChebiById() throws Exception {
+    try {
+      Chebi chebi = backend.getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:16708"));
+      assertNotNull(chebi);
+      assertEquals("adenine", chebi.getName());
+      assertEquals("Nc1ncnc2[nH]cnc12", chebi.getSmiles());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testChebiByIdWhenConnectionFails() throws Exception {
+    try {
+      cache = backend.getCache();
+      // exclude first cached value
+      backend.setCache(null);
+
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+
+      OntologyDataItem item = new OntologyDataItem();
+      item.setChebiId("CHEBI:18008");
+      item.setType("is a");
+
+      Entity entity = new Entity();
+      entity.getOntologyChildren().add(item);
+      entity.getOntologyParents().add(item);
+      when(chebiWebServiceClient.getLiteEntity(any(), any(), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API),
+          any())).thenThrow(new ChebiWebServiceFault_Exception(null, null));
+
+      // we will use mock object as a connection to chebi server
+      backend.setClient(chebiWebServiceClient);
+
+      backend.getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:16708"));
+      fail("Exception expected");
+
+    } catch (ChebiSearchException e) {
+      assertTrue(e.getMessage().contains("Problem with chebi"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      // restore cache for other tests
+      backend.setCache(cache);
+      // remove mock
+      backend.setClient(null);
+    }
+  }
+
+  @Test
+  public void testChebiByInvalidId() throws Exception {
+    try {
+      backend.getChebiElementForChebiId(new MiriamData(MiriamType.WIKIPEDIA, "water"));
+      fail("Exception expected");
+    } catch (InvalidArgumentException e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testChebi() throws Exception {
+    try {
+
+      Chebi chebi = backend.getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:16708"));
+      assertNotNull(chebi);
+      assertEquals("adenine", chebi.getName());
+      assertEquals("Nc1ncnc2[nH]cnc12", chebi.getSmiles());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testChebiOntologyForWater() throws Exception {
+    try {
+
+      Chebi chebi = backend.getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:15377"));
+      assertNotNull(chebi);
+      assertTrue(chebi.getIncomingChebi().size() > 0);
+      assertTrue(chebi.getOutgoingChebi().size() > 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test(timeout = 15000)
+  public void testCachableInterfaceById() throws Exception {
+    String query = "id: CHEBI:28423";
+    String newRes = "hello";
+    try {
+      waitForRefreshCacheQueueToEmpty();
+
+      cache.setCachedQuery(query, backend.getCacheType(), newRes);
+      cache.invalidateByQuery(query, backend.getCacheType());
+
+      waitForRefreshCacheQueueToEmpty();
+
+      String res = cache.getStringByQuery(query, backend.getCacheType());
+
+      assertNotNull(res);
+
+      assertFalse("Value wasn't refreshed from db", newRes.equals(res));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test(timeout = 15000)
+  public void testCachableInterfaceByName() throws Exception {
+    String query = "name: water";
+    String newRes = "hello";
+    try {
+      waitForRefreshCacheQueueToEmpty();
+
+      cache.setCachedQuery(query, backend.getCacheType(), newRes);
+      cache.invalidateByQuery(query, backend.getCacheType());
+
+      waitForRefreshCacheQueueToEmpty();
+
+      String res = cache.getStringByQuery(query, backend.getCacheType());
+
+      assertNotNull(res);
+
+      assertFalse("Value wasn't refreshed from db", newRes.equals(res));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testChebiNameToId1() throws Exception {
+    try {
+      // easy tests with some molecule
+      MiriamData result = backend.getChebiForChebiName("L-glutamate(2-)");
+      assertNotNull(result);
+      assertTrue(result.getResource().contains("CHEBI:29988"));
+      // unknown molecule
+      MiriamData string = backend.getChebiForChebiName("blablasblasblsabsal");
+      assertNull(string);
+
+      // and water
+      result = backend.getChebiForChebiName("H2O");
+      assertNotNull(result);
+      assertTrue(result.getResource().contains("CHEBI:15377"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testChebiNameToId4() throws Exception {
+    try {
+      // easy tests with some molecule
+      MiriamData result = backend.getChebiForChebiName("Ca2+");
+      assertEquals(new MiriamData(MiriamType.CHEBI, "CHEBI:29108"), result);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testChebiOntologyIds() throws Exception {
+    try {
+      // unknown molecule
+      List<MiriamData> res = backend.getOntologyChebiIdsForChebiName("blablasblasblsabsal");
+      assertNotNull(res);
+      assertEquals(0, res.size());
+
+      // and water
+      res = backend.getOntologyChebiIdsForChebiName("h2o");
+      assertNotNull(res);
+      assertTrue(res.size() > 1);
+      assertTrue(
+          res.contains(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CHEBI, "CHEBI:24431")));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testChebiNameToId2() throws Exception {
+    try {
+      // and now tests more complicated (how to find hydron?)
+      MiriamData md = backend.getChebiForChebiName("hydron");
+      assertNotNull(md);
+      assertTrue(md.getResource().contains("CHEBI:15378"));
+      md = backend.getChebiForChebiName("H+");
+      assertNotNull(md);
+      assertTrue(md.getResource().contains("CHEBI:15378"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testChebiNameToId3() throws Exception {
+    try {
+      // and the tricky one - I couldn't find it via chebi online search tool...
+      // But java API do the trick...
+      // assertEquals("CHEBI:456214",converter.chebiNameToId("NADP+"));
+      // however manual mapping done by chemist says different...:
+      MiriamData md = backend.getChebiForChebiName("NADP+");
+      assertNotNull(md);
+      assertTrue(md.getResource().contains("CHEBI:18009"));
+      md = backend.getChebiForChebiName("NADP(+)");
+      assertNotNull(md);
+      assertTrue(md.getResource().contains("CHEBI:18009"));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAnnotateChemical() throws Exception {
+    try {
+      SimpleMolecule simpleMolecule = new SimpleMolecule("id");
+      simpleMolecule.setName("water");
+
+      backend.annotateElement(simpleMolecule);
+
+      assertFalse(simpleMolecule.getFullName().equals(""));
+      assertFalse(simpleMolecule.getInChI().equals(""));
+      assertFalse(simpleMolecule.getInChIKey().equals(""));
+      assertFalse(simpleMolecule.getSmiles().equals(""));
+      assertFalse(simpleMolecule.getSynonyms().size() == 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAnnotateWhenConnectionFails() throws Exception {
+    try {
+      SimpleMolecule simpleMolecule = new SimpleMolecule("id");
+      simpleMolecule.setName("water");
+
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+
+      OntologyDataItem item = new OntologyDataItem();
+      item.setChebiId("CHEBI:18008");
+      item.setType("is a");
+
+      Entity entity = new Entity();
+      entity.getOntologyChildren().add(item);
+      entity.getOntologyParents().add(item);
+      when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME),
+          eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
+              .thenThrow(new ChebiWebServiceFault_Exception(null, null));
+
+      // we will use mock object as a connection to chebi server
+      backend.setClient(chebiWebServiceClient);
+
+      backend.setCache(null);
+      backend.annotateElement(simpleMolecule);
+
+      fail("Exceptione expected");
+    } catch (AnnotatorException e) {
+      assertTrue(e.getMessage().contains("Problem with getting information about chebi"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      backend.setCache(cache);
+      backend.setClient(null);
+    }
+  }
+
+  @Test
+  public void testAnnotateChemicalWithInvalidName() throws Exception {
+    try {
+      SimpleMolecule simpleMolecule = new SimpleMolecule("id");
+      simpleMolecule.setName("blasdh");
+
+      backend.annotateElement(simpleMolecule);
+
+      assertEquals(1, getWarnings().size());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testUpdateChemicalFromDb() throws Exception {
+    try {
+      SimpleMolecule simpleMolecule = new SimpleMolecule("id");
+      simpleMolecule
+          .addMiriamData(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CHEBI, "CHEBI:15377"));
+
+      backend.annotateElement(simpleMolecule);
+
+      assertFalse("".equals(simpleMolecule.getFullName()));
+      assertFalse(simpleMolecule.getInChI().equals(""));
+      assertFalse(simpleMolecule.getInChIKey().equals(""));
+      assertFalse(simpleMolecule.getSmiles().equals(""));
+      assertFalse(simpleMolecule.getSynonyms().size() == 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testUpdateChemicalFromDbWithDifferentData() throws Exception {
+    try {
+      SimpleMolecule simpleMolecule = new SimpleMolecule("id");
+      simpleMolecule.setName("water");
+      simpleMolecule.setFullName("xxx");
+      simpleMolecule.setInChI("x");
+      simpleMolecule.setInChIKey("x");
+      simpleMolecule.setSmiles("x");
+      simpleMolecule.addSynonym("x");
+      simpleMolecule
+          .addMiriamData(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CHEBI, "CHEBI:15377"));
+
+      backend.annotateElement(simpleMolecule);
+
+      assertEquals(5, getWarnings().size());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testGetters() throws Exception {
+    try {
+      assertNotNull(backend.getCommonName());
+      assertNotNull(backend.getUrl());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testRefreshGetOntology() throws Exception {
+    cache = backend.getCache();
+    try {
+      // exclude first cached value
+      backend.setCache(null);
+
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+
+      OntologyDataItem item = new OntologyDataItem();
+      item.setChebiId("CHEBI:18008");
+      item.setType("is a");
+
+      Entity entity = new Entity();
+      entity.getOntologyChildren().add(item);
+      entity.getOntologyParents().add(item);
+      when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
+
+      // we will use mock object as a connection to chebi server
+      backend.setClient(chebiWebServiceClient);
+
+      String query = ChebiAnnotator.ONTOLOGY_PREFIX + "CHEBI:18009";
+      String result = backend.refreshCacheQuery(query);
+      assertNotNull(result);
+      assertTrue(result.contains("CHEBI:18008"));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      // restore cache for other tests
+      backend.setCache(cache);
+      // remove mock
+      backend.setClient(null);
+    }
+  }
+
+  @Test
+  public void testGetChebiForChebiNameInFormula() throws Exception {
+    cache = backend.getCache();
+    try {
+      String chebiId = "CHEBI:18008";
+      String name = "art_name";
+      DataItem matchedElement = new DataItem();
+      matchedElement.setData(name);
+      // exclude first cached value
+      backend.setCache(null);
+
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+
+      OntologyDataItem item = new OntologyDataItem();
+
+      Entity entity = new Entity();
+      entity.getOntologyChildren().add(item);
+      entity.getOntologyParents().add(item);
+      entity.setChebiAsciiName("");
+      entity.getFormulae().add(matchedElement);
+      entity.setChebiId(chebiId);
+
+      when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
+      LiteEntityList liteEntityList = new LiteEntityList();
+
+      LiteEntity liteEntity = new LiteEntity();
+      liteEntityList.getListElement().add(liteEntity);
+      when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME),
+          eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any())).thenReturn(liteEntityList);
+
+      // we will use mock object as a connection to chebi server
+      backend.setClient(chebiWebServiceClient);
+
+      MiriamData result = backend.getChebiForChebiName(name);
+      assertNotNull(result);
+      assertEquals(chebiId, result.getResource());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      // restore cache for other tests
+      backend.setCache(cache);
+      // remove mock
+      backend.setClient(null);
+    }
+  }
+
+  @Test
+  public void testGetChebiForChebiNameInFormula2() throws Exception {
+    cache = backend.getCache();
+    try {
+      String chebiId = "CHEBI:18008";
+      String name = "art_name";
+      DataItem matchedElement = new DataItem();
+      matchedElement.setData(name);
+      // exclude first cached value
+      backend.setCache(null);
+
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+
+      OntologyDataItem item = new OntologyDataItem();
+
+      Entity entity = new Entity();
+      entity.getOntologyChildren().add(item);
+      entity.getOntologyParents().add(item);
+      entity.setChebiAsciiName("");
+      entity.getFormulae().add(matchedElement);
+      entity.setChebiId(chebiId);
+
+      when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
+      LiteEntityList liteEntityList = new LiteEntityList();
+
+      LiteEntity liteEntity = new LiteEntity();
+      liteEntityList.getListElement().add(liteEntity);
+      // when searching by name return empty list
+      when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME),
+          eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any())).thenReturn(new LiteEntityList());
+      // when searchng by all return list with elements
+      when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.ALL),
+          eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any())).thenReturn(liteEntityList);
+
+      // we will use mock object as a connection to chebi server
+      backend.setClient(chebiWebServiceClient);
+
+      MiriamData result = backend.getChebiForChebiName(name);
+      assertNotNull(result);
+      assertEquals(chebiId, result.getResource());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      // restore cache for other tests
+      backend.setCache(cache);
+      // remove mock
+      backend.setClient(null);
+    }
+  }
+
+  @Test
+  public void testGetChebiForChebiNameInSynonym() throws Exception {
+    cache = backend.getCache();
+    try {
+      String chebiId = "CHEBI:18008";
+      String name = "art_name";
+      DataItem matchedElement = new DataItem();
+      matchedElement.setData(name);
+      // exclude first cached value
+      backend.setCache(null);
+
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+
+      OntologyDataItem item = new OntologyDataItem();
+
+      Entity entity = new Entity();
+      entity.getOntologyChildren().add(item);
+      entity.getOntologyParents().add(item);
+      entity.setChebiAsciiName("");
+      entity.getSynonyms().add(matchedElement);
+      entity.setChebiId(chebiId);
+
+      when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
+      LiteEntityList liteEntityList = new LiteEntityList();
+
+      LiteEntity liteEntity = new LiteEntity();
+      liteEntityList.getListElement().add(liteEntity);
+      when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME),
+          eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any())).thenReturn(liteEntityList);
+
+      // we will use mock object as a connection to chebi server
+      backend.setClient(chebiWebServiceClient);
+
+      MiriamData result = backend.getChebiForChebiName(name);
+      assertNotNull(result);
+      assertEquals(chebiId, result.getResource());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      // restore cache for other tests
+      backend.setCache(cache);
+      // remove mock
+      backend.setClient(null);
+    }
+  }
+
+  @Test
+  public void testGetChebiForChebiNameInSynonym2() throws Exception {
+    cache = backend.getCache();
+    try {
+      String chebiId = "CHEBI:18008";
+      String name = "art_name";
+      DataItem matchedElement = new DataItem();
+      matchedElement.setData(name);
+      // exclude first cached value
+      backend.setCache(null);
+
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+
+      OntologyDataItem item = new OntologyDataItem();
+
+      Entity entity = new Entity();
+      entity.getOntologyChildren().add(item);
+      entity.getOntologyParents().add(item);
+      entity.setChebiAsciiName("");
+      entity.getSynonyms().add(matchedElement);
+      entity.setChebiId(chebiId);
+
+      when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
+      LiteEntityList liteEntityList = new LiteEntityList();
+
+      LiteEntity liteEntity = new LiteEntity();
+      liteEntityList.getListElement().add(liteEntity);
+      // when searching by name return empty list
+      when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME),
+          eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any())).thenReturn(new LiteEntityList());
+      // when searchng by all return list with elements
+      when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.ALL),
+          eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any())).thenReturn(liteEntityList);
+
+      // we will use mock object as a connection to chebi server
+      backend.setClient(chebiWebServiceClient);
+
+      MiriamData result = backend.getChebiForChebiName(name);
+      assertNotNull(result);
+      assertEquals(chebiId, result.getResource());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      // restore cache for other tests
+      backend.setCache(cache);
+      // remove mock
+      backend.setClient(null);
+    }
+  }
+
+  @Test
+  public void testGetChebiForChebiNameWithConnectionProblems() throws Exception {
+    cache = backend.getCache();
+    try {
+      // exclude first cached value
+      backend.setCache(null);
+
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+
+      // when searching by name return empty list
+      when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME),
+          eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any()))
+              .thenThrow(new ChebiWebServiceFault_Exception(null, null));
+
+      // we will use mock object as a connection to chebi server
+      backend.setClient(chebiWebServiceClient);
+
+      backend.getChebiForChebiName("bla");
+
+    } catch (ChebiSearchException e) {
+      assertTrue(e.getMessage().contains("Problem with chebi connection"));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      // restore cache for other tests
+      backend.setCache(cache);
+      // remove mock
+      backend.setClient(null);
+    }
+  }
+
+  @Test
+  public void testRefreshWhenProblemWithConnnector() throws Exception {
+    cache = backend.getCache();
+    try {
+      // exclude first cached value
+      backend.setCache(null);
+
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+
+      OntologyDataItem item = new OntologyDataItem();
+      item.setChebiId("CHEBI:18008");
+      item.setType("is a");
+
+      Entity entity = new Entity();
+      entity.getOntologyChildren().add(item);
+      entity.getOntologyParents().add(item);
+      when(chebiWebServiceClient.getCompleteEntity(any(String.class)))
+          .thenThrow(new ChebiWebServiceFault_Exception(null, null));
+
+      // we will use mock object as a connection to chebi server
+      backend.setClient(chebiWebServiceClient);
+
+      String query = ChebiAnnotator.ONTOLOGY_PREFIX + "CHEBI:18009";
+      backend.refreshCacheQuery(query);
+      fail("Exception expected");
+
+    } catch (SourceNotAvailable e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      // restore cache for other tests
+      backend.setCache(cache);
+      // remove mock
+      backend.setClient(null);
+    }
+  }
+
+  @Test
+  public void testRefreshInvalidQuery() throws Exception {
+    try {
+      backend.refreshCacheQuery("invalid string");
+
+      fail("Exception expected");
+    } catch (InvalidArgumentException e) {
+      assertTrue(e.getMessage().contains("Don't know what to do"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testRefreshInvalidQuery2() throws Exception {
+    try {
+      backend.refreshCacheQuery(new Object());
+
+      fail("Exception expected");
+    } catch (InvalidArgumentException e) {
+      assertTrue(e.getMessage().contains("Don't know what to do"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testStatus() throws Exception {
+    try {
+      assertEquals(ExternalServiceStatusType.OK, backend.getServiceStatus().getStatus());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testSimulateDownStatus() throws Exception {
+    backend.setCache(null);
+    try {
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+      when(chebiWebServiceClient.getLiteEntity(any(), any(), eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API),
+          any())).thenThrow(new ChebiWebServiceFault_Exception(null, null));
+      backend.setClient(chebiWebServiceClient);
+      assertEquals(ExternalServiceStatusType.DOWN, backend.getServiceStatus().getStatus());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      backend.setCache(cache);
+      backend.setClient(null);
+    }
+  }
+
+  @Test
+  public void testSimulateChangedStatus() throws Exception {
+    backend.setCache(null);
+    try {
+      ChebiWebServiceClient chebiWebServiceClient = Mockito.mock(ChebiWebServiceClient.class);
+      backend.setClient(chebiWebServiceClient);
+
+      String chebiId = "CHEBI:18008";
+      String name = "art";
+      DataItem matchedElement = new DataItem();
+      matchedElement.setData(name);
+      // exclude first cached value
+      backend.setCache(null);
+
+      OntologyDataItem item = new OntologyDataItem();
+
+      Entity entity = new Entity();
+      entity.getOntologyChildren().add(item);
+      entity.getOntologyParents().add(item);
+      entity.setChebiAsciiName("");
+      entity.getSynonyms().add(matchedElement);
+      entity.setChebiId(chebiId);
+
+      when(chebiWebServiceClient.getCompleteEntity(any(String.class))).thenReturn(entity);
+      LiteEntityList liteEntityList = new LiteEntityList();
+
+      LiteEntity liteEntity = new LiteEntity();
+      liteEntityList.getListElement().add(liteEntity);
+      when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.CHEBI_NAME),
+          eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any())).thenReturn(liteEntityList);
+      when(chebiWebServiceClient.getLiteEntity(any(), eq(SearchCategory.ALL),
+          eq(ChebiAnnotator.MAX_SEARCH_RESULTS_FROM_CHEBI_API), any())).thenReturn(liteEntityList);
+
+      assertEquals(ExternalServiceStatusType.CHANGED, backend.getServiceStatus().getStatus());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      backend.setCache(cache);
+      backend.setClient(null);
+    }
+  }
 
 }
diff --git a/pom.xml b/pom.xml
index c4ae7d49e1981914751eb1164fe8e0733c5f00b6..6da6fa5d7c9371f53a610c110362519bd0d1d82c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,7 +58,7 @@
 		
 		<gson.version>2.2.2</gson.version>
 		
-		<chebi-ws.version>2.2.2</chebi-ws.version>
+		<chebi-ws.version>2.3.2</chebi-ws.version>
 
 		<miriam-lib.version>1.1.5</miriam-lib.version>