public void put(Tuple tuple, String key, Provider provider)
      throws TupleSpaceException, TupleSpaceSecurityException {

    switch (provider) {
      case INFRA:
        if (infraDomain != null && findServerConnection()) {
          System.out.println("***Put INFRA");
          infraDomain.put(tuple, key);
        }
        break;
      case ALL:
        System.out.println("***Put ALL");
        if (localDomain != null) {
          System.out.println("***Put LOCAL");
          localDomain.put(tuple, key);
        }
        if (infraDomain != null && findServerConnection()) {
          System.out.println("***Put INFRA");
          infraDomain.put(tuple, key);
        }
        break;
      default:
        if (localDomain != null) {
          System.out.println("***Put LOCAL");
          localDomain.put(tuple, key);
        }
        break;
    }
  }
  public Tuple takeOne(Pattern pattern, String restriction, String key, Provider provider)
      throws TupleSpaceException, TupleSpaceSecurityException {

    if (provider == Provider.INFRA) return infraDomain.takeOne(pattern, restriction, key);

    // Default Provider. It's not permitted take tuple from ad hoc providers.
    return localDomain.takeOne(pattern, restriction, key);
  }
  @Override
  public void unsubscribe(Object reactionId, String key)
      throws TupleSpaceException, TupleSpaceSecurityException {

    localDomain.unsubscribe(reactionId, key);
    infraDomain.unsubscribe(reactionId, key);
    adhocDomain.unsubscribe(reactionId, key);
  }
  public List<Tuple> takeSync(
      Pattern pattern, String restriction, String key, long timeout, Provider provider)
      throws TupleSpaceException, TupleSpaceSecurityException {

    if (provider == Provider.INFRA) return infraDomain.takeSync(pattern, restriction, key, timeout);

    // Default Provider. It's not permitted take tuple from ad hoc providers.
    return localDomain.takeSync(pattern, restriction, key, timeout);
  }
  public List<Tuple> readSync(
      Pattern pattern, String restriction, String key, long timeout, Provider provider)
      throws TupleSpaceException, TupleSpaceSecurityException {

    List<Tuple> tuples = new ArrayList<Tuple>();

    switch (provider) {
      case LOCAL:
        tuples = localDomain.readSync(pattern, restriction, key, timeout);
        break;
      case INFRA:
        tuples = infraDomain.readSync(pattern, restriction, key, timeout);
        break;
      case ADHOC:
        tuples = adhocDomain.readSync(pattern, restriction, key, timeout);
        break;
      case ALL:
        tuples = localDomain.readSync(pattern, restriction, key, timeout);
        tuples.addAll(infraDomain.readSync(pattern, restriction, key, timeout));
        tuples.addAll(adhocDomain.readSync(pattern, restriction, key, timeout));
        break;
      default: // ANY provider
        tuples = localDomain.readSync(pattern, restriction, key, timeout);

        if (tuples == null || tuples.size() == 0) {
          tuples = infraDomain.readSync(pattern, restriction, key, timeout);

          if (tuples == null || tuples.size() == 0) {
            tuples = adhocDomain.readSync(pattern, restriction, key, timeout);
          }
        }
        break;
    }
    return tuples;
  }
  public Object subscribe(IReaction reaction, String event, String key, Provider provider)
      throws TupleSpaceException, TupleSpaceSecurityException {

    Object obj = null;

    switch (provider) {
      case LOCAL:
        obj = localDomain.subscribe(reaction, event, key);
        break;

      case INFRA:
        obj = infraDomain.subscribe(reaction, event, key);
        break;

      case ADHOC:
        obj = adhocDomain.subscribe(reaction, event, key);
        break;
      default: // ALL providers
        List<Object> objList = new ArrayList<Object>();
        objList.add(localDomain.subscribe(reaction, event, key));
        objList.add(infraDomain.subscribe(reaction, event, key));
        objList.add(adhocDomain.subscribe(reaction, event, key));

        obj = objList;

        break;
    }

    return obj;
  }
  public Tuple readOneSync(
      Pattern pattern, String restriction, String key, long timeout, Scope scope, Provider provider)
      throws TupleSpaceException, TupleSpaceSecurityException {

    Tuple tuple = null;

    switch (provider) {
      case LOCAL:
        tuple = localDomain.readOneSync(pattern, restriction, key, timeout, scope);
        break;
      case INFRA:
        tuple = infraDomain.readOneSync(pattern, restriction, key, timeout, scope);
        break;
      case ADHOC:
        tuple = adhocDomain.readOneSync(pattern, restriction, key, timeout, scope);
        break;
      default: // ANY provider
        tuple = localDomain.readOneSync(pattern, restriction, key, timeout, scope);

        if (tuple == null || tuple.size() == 0) {
          tuple = infraDomain.readOneSync(pattern, restriction, key, timeout, scope);

          if (tuple == null || tuple.size() == 0) {
            tuple = adhocDomain.readOneSync(pattern, restriction, key, timeout, scope);
          }
        }
        break;
    }
    return tuple;
  }
  public List<Tuple> read(
      Pattern pattern, String restriction, String key, Scope scope, Provider provider)
      throws TupleSpaceException, TupleSpaceSecurityException {

    List<Tuple> tuples = new ArrayList<Tuple>();

    if (scope == null) {
      scope = new Scope();
    }

    switch (provider) {
      case LOCAL:
        if (localDomain != null) {
          System.out.println("***Buscando LOCAL");
          tuples = localDomain.read(pattern, restriction, key, scope);
        }
        break;
      case INFRA:
        if (findServerConnection() && infraDomain != null) {
          System.out.println("***Buscando INFRA");
          tuples = infraDomain.read(pattern, restriction, key, scope);
        }
        break;
      case ADHOC:
        if (adhocDomain != null) {
          System.out.println("***Buscando ADHOC");
          tuples = adhocDomain.read(pattern, restriction, key, scope);
        }
        break;
      case ALL:
        System.out.println("***Buscando ALL");
        if (localDomain != null) {
          System.out.println("***Buscando LOCAL");
          tuples = localDomain.read(pattern, restriction, key, scope);
        }
        if (infraDomain != null && findServerConnection()) {
          System.out.println("***Buscando INFRA");
          tuples.addAll(infraDomain.read(pattern, restriction, key, scope));
        }
        if (adhocDomain != null) {
          System.out.println("***Buscando ADHOC");
          tuples.addAll(adhocDomain.read(pattern, restriction, key, scope));
        }
        break;
      default: // ANY provider
        System.out.println("***Buscando ANY");
        if (localDomain != null) {
          System.out.println("***Buscando LOCAL");
          tuples = localDomain.read(pattern, restriction, key, scope);
        }
        if ((tuples == null || tuples.size() == 0)) {
          System.out.println("***Buscando INFRA");
          if (infraDomain != null && findServerConnection()) {
            tuples = infraDomain.read(pattern, restriction, key, scope);
          }
          if ((tuples == null || tuples.size() == 0) && adhocDomain != null) {
            System.out.println("***Buscando ADHOC");
            tuples = adhocDomain.read(pattern, restriction, key, scope);
          }
        }
        break;
    }
    return tuples;
  }