private Set<Service> checkBackwardMessages(final FCompositionMessage fCompositionMessage, final Set<ServiceDistance> successors) {

		logger.trace("Peer " + peer.getPeerID() + " checking received backward messages for search " + fCompositionMessage.getSearchID());
		final Set<MessageTree> completeTrees = bCompositionData.getCompleteTrees(fCompositionMessage.getSearchID(), fCompositionMessage.getSourceService());

		final Set<Service> exploredSuccessors = new HashSet<Service>();

		if (!completeTrees.isEmpty()) {

			logger.trace("Peer " + peer.getPeerID() + " found complete trees for search " + fCompositionMessage.getSearchID());

			final Map<Service, Set<ServiceDistance>> distanceBetweenServices = new HashMap<Service, Set<ServiceDistance>>();

			final Set<Service> backwardCompositionDirectSuccessors = new HashSet<Service>();

			for (final MessageTree completeTree : completeTrees) {
				// obtain which successors have been explored by the backward
				// search
				exploredSuccessors.addAll(completeTree.getSuccessors());

				// add backward service distances
				final Map<Service, Set<ServiceDistance>> serviceDistances = completeTree.getAncestorDistances();

				Util.addServiceDistances(distanceBetweenServices, serviceDistances);

				final Set<Service> directSuccessors = getSuccessors(completeTree.getServices(), fCompositionMessage.getSourceService());
				backwardCompositionDirectSuccessors.addAll(directSuccessors);
			}

			// add forward composition removing those services which are not
			// direct successors (according to the backward composition) of the
			// current service
			for (final Service service : fCompositionMessage.getComposition())
				if (backwardCompositionDirectSuccessors.contains(service))
					exploredSuccessors.add(service);

			Util.addServiceDistances(distanceBetweenServices, fCompositionMessage.getSuccessorDistances());

			for (final Iterator<ServiceDistance> it = distanceBetweenServices.get(fCompositionMessage.getSourceService()).iterator(); it.hasNext();) {
				final ServiceDistance sDistance = it.next();
				if (!backwardCompositionDirectSuccessors.contains(sDistance.getService()))
					it.remove();
			}

			// composition is only notified if some successor participates in
			// composition as direct successors of current service
			final Set<Service> directSuccessors = getSuccessors(Util.getAllServices(distanceBetweenServices), fCompositionMessage.getSourceService());

			boolean notify = false;
			for (final ServiceDistance sDistance : successors)
				if (directSuccessors.contains(sDistance.getService())) {
					notify = true;
					break;
				}

			if (notify) {
				final SearchID searchID = fCompositionMessage.getSearchID();
				((BidirectionalSearch) commonCompositionSearch).notifyComposition(searchID, distanceBetweenServices, peer.getPeerID(), gCreator.getPSearch().getDisseminationLayer().getTaxonomy());
			}
		} else
			logger.trace("Peer " + peer.getPeerID() + " complete trees NOT found for search " + fCompositionMessage.getSearchID());

		return exploredSuccessors;
	}