Index: branches/supervisor/src/main/java/omq/server/InvocationThread.java
===================================================================
--- branches/supervisor/src/main/java/omq/server/InvocationThread.java	(revision 96)
+++ branches/supervisor/src/main/java/omq/server/InvocationThread.java	(revision 100)
@@ -37,4 +37,8 @@
 	private String UID;
 	private Properties env;
+	private boolean idle;
+	private long lastExec;
+
+	private RemoteThreadPool pool; // TODO posar això bé
 
 	// Broker
@@ -54,4 +58,6 @@
 		this.broker = broker;
 		this.serializer = broker.getSerializer();
+		this.lastExec = 0;
+		this.idle = true;
 	}
 
@@ -73,4 +79,8 @@
 				// Get the delivery
 				Delivery delivery = consumer.nextDelivery();
+
+				// This thread gets busy
+				pool.getBusy().incrementAndGet();
+				idle = false;
 
 				String serializerType = delivery.getProperties().getType();
@@ -112,4 +122,10 @@
 
 				channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
+
+				// The thread is now idle
+				lastExec = System.currentTimeMillis();
+				idle = true;
+				pool.getBusy().decrementAndGet();
+
 			} catch (InterruptedException i) {
 				logger.error(i);
@@ -231,3 +247,11 @@
 	}
 
+	public long getLastExecution() {
+		return lastExec;
+	}
+
+	public boolean isIdle() {
+		return idle;
+	}
+
 }
Index: branches/supervisor/src/main/java/omq/server/RemoteObject.java
===================================================================
--- branches/supervisor/src/main/java/omq/server/RemoteObject.java	(revision 96)
+++ branches/supervisor/src/main/java/omq/server/RemoteObject.java	(revision 100)
@@ -33,4 +33,5 @@
 	private Properties env;
 	private transient Broker broker;
+	private transient RemoteThreadPool pool;
 	private transient Map<String, List<Class<?>>> params;
 	private transient List<InvocationThread> invocationList;
Index: branches/supervisor/src/main/java/omq/server/RemoteThreadPool.java
===================================================================
--- branches/supervisor/src/main/java/omq/server/RemoteThreadPool.java	(revision 100)
+++ branches/supervisor/src/main/java/omq/server/RemoteThreadPool.java	(revision 100)
@@ -0,0 +1,148 @@
+package omq.server;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import omq.common.broker.Broker;
+
+import com.rabbitmq.client.AMQP.Queue.DeclareOk;
+import com.rabbitmq.client.Channel;
+
+public class RemoteThreadPool extends Thread {
+	private List<InvocationThread> workers;
+	private AtomicInteger busy;
+	private int minPoolThreads;
+	private int maxPoolThreads;
+	private long refresh;
+	private long keepAliveTime;
+	private int maxMessagesPerThread;
+
+	private RemoteObject obj;
+	private Broker broker;
+	private boolean killed = false;
+
+	public RemoteThreadPool(int minPoolThreads, int maxPoolThreads, long refresh, long keepAliveTime, int maxMessagesPerThread, RemoteObject obj, Broker broker) {
+		this.minPoolThreads = minPoolThreads;
+		this.maxPoolThreads = maxPoolThreads;
+		this.refresh = refresh;
+		this.keepAliveTime = keepAliveTime;
+		this.maxMessagesPerThread = maxMessagesPerThread;
+		this.obj = obj;
+		this.broker = broker;
+
+		workers = new ArrayList<InvocationThread>(minPoolThreads);
+		busy = new AtomicInteger();
+	}
+
+	@Override
+	public void run() {
+
+		// Crear aquí tots els fils?
+
+		while (!killed) {
+
+			try {
+				Channel channel = broker.getChannel();
+				DeclareOk dok = channel.queueDeclarePassive(obj.getRef());
+
+				int numConsumers = dok.getConsumerCount();
+				int numMessages = dok.getMessageCount();
+				int division = numMessages / numConsumers;
+				int numWorkers = workers.size();
+
+				if (numWorkers < maxPoolThreads && division >= maxMessagesPerThread) {
+					// Create a new thread
+					InvocationThread worker = new InvocationThread(obj, broker);
+					workers.add(worker);
+					worker.start();
+				} else if (numWorkers > minPoolThreads && busy.get() < numWorkers) {
+					// Kill idle threads
+					stopIdleThreads();
+				}
+
+				Thread.sleep(refresh);
+
+			} catch (Exception e) {
+
+			}
+		}
+
+	}
+
+	private void stopIdleThreads() {
+		long now = System.currentTimeMillis();
+
+		for (InvocationThread worker : workers) {
+			long lastExec = worker.getLastExecution();
+			if (worker.isIdle() && (lastExec - now) > keepAliveTime) {
+				// Kill thread
+				try {
+					worker.kill();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+
+			}
+		}
+	}
+
+	public List<InvocationThread> getWorkers() {
+		return workers;
+	}
+
+	public void setWorkers(List<InvocationThread> workers) {
+		this.workers = workers;
+	}
+
+	public AtomicInteger getBusy() {
+		return busy;
+	}
+
+	public void setBusy(AtomicInteger busy) {
+		this.busy = busy;
+	}
+
+	public int getMinPoolThreads() {
+		return minPoolThreads;
+	}
+
+	public void setMinPoolThreads(int minPoolThreads) {
+		this.minPoolThreads = minPoolThreads;
+	}
+
+	public int getMaxPoolThreads() {
+		return maxPoolThreads;
+	}
+
+	public void setMaxPoolThreads(int maxPoolThreads) {
+		this.maxPoolThreads = maxPoolThreads;
+	}
+
+	public long getRefresh() {
+		return refresh;
+	}
+
+	public void setRefresh(long refresh) {
+		this.refresh = refresh;
+	}
+
+	public long getKeepAliveTime() {
+		return keepAliveTime;
+	}
+
+	public void setKeepAliveTime(long keepAliveTime) {
+		this.keepAliveTime = keepAliveTime;
+	}
+
+	public int getMaxMessagesPerThread() {
+		return maxMessagesPerThread;
+	}
+
+	public void setMaxMessagesPerThread(int maxMessagesPerThread) {
+		this.maxMessagesPerThread = maxMessagesPerThread;
+	}
+
+}
