arrayIndexOutOfBounds for stateManager.getProblemState()

Hi
I have a simple state manager that records which route a task is assigned to. I do also add initial routes to the problem but Im pretty sure that informInsertStarts to add those jobs to the state manager is called before the solution search begins.

During the iterations I sometimes get an arrayIndexOutOfBounds exception. clearly this should not happen and I cant click on to why it is.

Any help would be appreciated.

Here is the state manager code (it has constraint code in same file)

 public class SM_KeepJobsTogether_EXP implements StateUpdater,JobInsertedListener,InsertionStartsListener, SoftActivityConstraint, HardActivityConstraint  {
StateManager stateManager;

public SM_KeepJobsTogether_EXP(StateManager stateManager) {
			Utils.LOGGER.log(Level.INFO, "Initialising Rule: KeepJobsTogether" );
	this.stateManager = stateManager;
}

@Override
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
	stateManager.putProblemState(stateManager.createStateId(extractId(job2insert.getId())), VehicleRoute.class, inRoute);
}

private String extractId(String id) {
	StringTokenizer st1 = new StringTokenizer(id);
	String newId = st1.nextToken("_");
	return newId;
}
@Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
	for(VehicleRoute r : vehicleRoutes){
		for(Job j : r.getTourActivities().getJobs()){
			informJobInserted(j,r,0.,0.);
		}
	}
}

@Override
public ConstraintsStatus fulfilled(JobInsertionContext insertionContext, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
	VehicleRoute routeVisitingLocation  = null;
	if(newAct instanceof TourActivity.JobActivity) {
			String jobId = extractId(insertionContext.getJob().getId());

			routeVisitingLocation = stateManager.getProblemState(stateManager.createStateId(jobId), VehicleRoute.class);
			if (routeVisitingLocation == null) {
				return ConstraintsStatus.FULFILLED;
			} else {
				return routeVisitingLocation == insertionContext.getRoute() ? ConstraintsStatus.FULFILLED : ConstraintsStatus.NOT_FULFILLED_BREAK;
			}
	}else {
		Utils.LOGGER.log(Level.INFO, "jobId " + extractId(insertionContext.getJob().getId())+ " is type: " + newAct.getName() );
	}
	return ConstraintsStatus.NOT_FULFILLED;
}

@Override
public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct,
		double prevActDepTime) {
	VehicleRoute routeVisitingLocation  = null;
	if(newAct instanceof TourActivity.JobActivity) {
		try{
			routeVisitingLocation = stateManager.getProblemState(stateManager.createStateId(extractId(iFacts.getJob().getId())), VehicleRoute.class);
			if (routeVisitingLocation == null) {
				return Constants.KEEP_JOBS_TOGETHER_BAD;
			} else {
				return routeVisitingLocation == iFacts.getRoute() ? Constants.KEEP_JOBS_TOGETHER_GOOD : Constants.KEEP_JOBS_TOGETHER_BAD;
			}
		} catch (ArrayIndexOutOfBoundsException e) {
			if(routeVisitingLocation == null) {
				Utils.LOGGER.log(Level.SEVERE, "routeVisitingLocation is null for jobId " + extractId(iFacts.getJob().getId()) );
			} else {
				Utils.LOGGER.log(Level.SEVERE, "jobId " + extractId(iFacts.getJob().getId())+ "is on route " +  routeVisitingLocation.getVehicle().getId() );
			}
		}
	}
	return 0;
}

}