private void createCssNode(final IndividualCtxEntity cssOwnerEnt, final INetworkNode cssNodeId)
      throws CtxBootLoaderException {

    if (cssOwnerEnt == null) throw new NullPointerException("cssOwnerEnt can't be null");
    if (cssNodeId == null) throw new NullPointerException("cssNodeId can't be null");

    try {
      LOG.info("Checking if CSS node context entity " + cssNodeId + " exists...");
      final List<CtxEntityIdentifier> cssNodeEntIds =
          this.userCtxDBMgr.lookupEntities(
              CtxEntityTypes.CSS_NODE,
              CtxAttributeTypes.ID,
              cssNodeId.toString(),
              cssNodeId.toString());
      if (!cssNodeEntIds.isEmpty()) {
        LOG.info("Found CSS node context entity " + cssNodeEntIds.get(0));
        return;
      }

      final CtxAssociation ownsCssNodesAssoc;
      if (cssOwnerEnt.getAssociations(CtxAssociationTypes.OWNS_CSS_NODES).isEmpty())
        ownsCssNodesAssoc = this.userCtxDBMgr.createAssociation(CtxAssociationTypes.OWNS_CSS_NODES);
      else
        ownsCssNodesAssoc =
            (CtxAssociation)
                this.userCtxDBMgr.retrieve(
                    cssOwnerEnt
                        .getAssociations(CtxAssociationTypes.OWNS_CSS_NODES)
                        .iterator()
                        .next());
      ownsCssNodesAssoc.setParentEntity(cssOwnerEnt.getId());
      final CtxEntity cssNodeEnt = this.userCtxDBMgr.createEntity(CtxEntityTypes.CSS_NODE);
      ownsCssNodesAssoc.addChildEntity(cssNodeEnt.getId());
      this.userCtxDBMgr.update(ownsCssNodesAssoc);
      final CtxAttribute cssNodeIdAttr =
          this.userCtxDBMgr.createAttribute(cssNodeEnt.getId(), CtxAttributeTypes.ID);
      cssNodeIdAttr.setStringValue(cssNodeId.toString());
      this.userCtxDBMgr.update(cssNodeIdAttr);
      LOG.info("Created CSS node context entity " + cssNodeEnt.getId());

    } catch (Exception e) {
      throw new CtxBootLoaderException(
          "Could not create CSS node context entity " + cssNodeId + ": " + e.getLocalizedMessage(),
          e);
    }
  }
  @Autowired(required = true)
  CtxBootLoader(ICommManager commMgr, IUserCtxDBMgr userCtxDBMgr, ICtxEventMgr ctxEventMgr)
      throws Exception {

    if (LOG.isInfoEnabled()) LOG.info(this.getClass() + " instantiated");

    this.commMgr = commMgr;
    this.userCtxDBMgr = userCtxDBMgr;
    this.ctxEventMgr = ctxEventMgr;

    final INetworkNode localCssNodeId = commMgr.getIdManager().getThisNetworkNode();
    LOG.info("Found local CSS node ID " + localCssNodeId);
    final IIdentity localCssId = commMgr.getIdManager().fromJid(localCssNodeId.getBareJid());
    LOG.info("Found local CSS ID " + localCssId);

    final IndividualCtxEntity cssOwnerEnt =
        createIndividualEntity(
            localCssId, CtxEntityTypes.PERSON); // TODO don't hardcode the cssOwner type
    this.createCssNode(cssOwnerEnt, localCssNodeId);
  }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.societies.api.internal.servicelifecycle.IServiceDiscovery#getServices
   * (org.societies.api.comm.xmpp.datatypes.Identity)
   */
  @Override
  @Async
  public Future<List<Service>> getServices(IIdentity node) throws ServiceDiscoveryException {
    List<Service> serviceList = new ArrayList<Service>();

    if (logger.isDebugEnabled())
      logger.debug("getServices(Identity node) for node: " + node.getJid());

    boolean myNode;
    boolean myCIS = false;
    INetworkNode currentNode = commMngr.getIdManager().getThisNetworkNode();
    if (!currentNode.getJid().contentEquals(node.getJid())) myNode = false;
    else myNode = true;

    try {
      // Is it our node? If so, local search
      if (myNode) {
        if (logger.isDebugEnabled()) logger.debug("We're dealing with our own node!");
        serviceList = getServiceReg().retrieveServicesSharedByCSS(node.getJid());
      } else {
        // Is it one of my CIS? If so, local search
        ICisOwned localCis = getCisManager().getOwnedCis(node.getJid());
        if (localCis != null) {
          if (logger.isDebugEnabled()) logger.debug("We're dealing with our CIS! Local search!");
          serviceList = getServiceReg().retrieveServicesSharedByCIS(node.getJid());
          myCIS = true;
        }
      }
      /*
      switch (node.getType())
      {
      case CSS:
      case CSS_RICH:
      case CSS_LIGHT:
      	serviceList = getServiceReg().retrieveServicesSharedByCSS(node.getJid());
      	break;
      case CIS:
      	if(logger.isDebugEnabled()) logger.debug("Retrieving services of a CIS");
      	ICisOwned myCis = getCisManager().getOwnedCis(node.getJid());
      	if(myCis != null){
      		if(logger.isDebugEnabled()) logger.debug("We're dealing with our CIS! Local search!");
      		serviceList = getServiceReg().retrieveServicesSharedByCIS(node.getJid());
      	}
      	break;
      default:
      	logger.warn("Unknown node!");
      	break;
      }
      */
    } catch (ServiceRetrieveException e) {

      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (Exception e) {

      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    if (serviceList == null || serviceList.isEmpty()) {
      if (logger.isDebugEnabled()) logger.debug("No services retrieved from local node...");

      // IIdentity currentNode = commMngr.getIdManager().getThisNetworkNode();

      if (!myNode && !myCIS) {

        if (logger.isDebugEnabled())
          logger.debug("Attempting to retrieve services from remote node: " + node.getJid());

        ServiceDiscoveryRemoteClient callback = new ServiceDiscoveryRemoteClient();
        getServiceDiscoveryRemote().getServices(node, callback);
        serviceList = callback.getResultList();
      }
    }

    // Quick log message
    if (logger.isDebugEnabled()) {

      if (serviceList.isEmpty()) logger.debug("getServices: no services found!");
      else {
        Iterator<Service> it = serviceList.iterator();
        String logStuff = "getServices: ";

        while (it.hasNext()) {
          logStuff += it.next().getServiceName() + "; \n";
        }

        logger.debug(logStuff);
      }
    }

    return new AsyncResult<List<Service>>(serviceList);
  }