code: public int freeSlot(AllocationID allocationId, Throwable cause) throws SlotNotFoundException {
  		checkInit();
  
  		TaskSlot taskSlot = getTaskSlot(allocationId);
  
  		if (taskSlot != null) {
  			if (LOG.isDebugEnabled()) {
  				LOG.debug("Free slot {}.", taskSlot, cause);
  			} else {
  				LOG.info("Free slot {}.", taskSlot);
  			}
  
  			final JobID jobId = taskSlot.getJobId();
  
  			if (taskSlot.markFree()) {
  				// remove the allocation id to task slot mapping
  				allocationIDTaskSlotMap.remove(allocationId);
  
  				// unregister a potential timeout
  				timerService.unregisterTimeout(allocationId);
  
  				Set<AllocationID> slots = slotsPerJob.get(jobId);
  
  				if (slots == null) {
  					throw new IllegalStateException("There are no more slots allocated for the job " + jobId +
  						". This indicates a programming bug.");
  				}
  
  				slots.remove(allocationId);
  
  				if (slots.isEmpty()) {
  					slotsPerJob.remove(jobId);
  				}
  
  				return taskSlot.getIndex();
  			} else {
  				// we couldn't free the task slot because it still contains task, fail the tasks
  				// and set the slot state to releasing so that it gets eventually freed
  				taskSlot.markReleasing();
  
  				Iterator<Task> taskIterator = taskSlot.getTasks();
  
  				while (taskIterator.hasNext()) {
  					taskIterator.next().failExternally(cause);
  				}
  
  				return -1;
  			}
  		} else {
  			throw new SlotNotFoundException(allocationId);
  		}
  	}
docs: Tries to free the slot. If the slot is empty it will set the state of the task slot to free
  and return its index. If the slot is not empty, then it will set the state of the task slot
  to releasing, fail all tasks and return -1.
  
  @param allocationId identifying the task slot to be freed
  @param cause to fail the tasks with if slot is not empty
  @throws SlotNotFoundException if there is not task slot for the given allocation id
  @return The freed TaskSlot. If the TaskSlot cannot be freed then null.