@Override
	public void callback(DiscreteEventSimulator DES) throws SimulatorException {
		boolean isNative = context.getContextID() == target.getCoreID();
		
		if (isNative){
			Context oldContext = target.switchNativeContext(context);
			context.endStall();
			
			// give predictor feedback
			switch (type){
			case CoreMiss:
				target.getPredictor().feedback(context.getRunLength());
				break;
			case Eviction:
				target.getPredictor().feedback(context.getRunLength());
				break;
			case Overflow:
				target.getPredictor().overflow();
				break;
			case Underflow:
				target.getPredictor().underflow();
				break;
			default:
				throw new SimulatorException("weird message type during migration event");
			}
			
			// reset run length
			context.resetRunLength();
			
			// freeze run length
			context.freezeRunLength();
			
			if (null != oldContext){
				throw new SimulatorException("Migration home somehow evicted a context from the native core!");
			}
		} else {
			int max0 = 16;
			int max1 = 4;
			int cur0 = stack0depth;
			int cur1 = stack1depth;
			
			Context oldContext = target.switchGuestContext(context, max0, cur0, max1, cur1);
			context.endStall();
			
			if (0 != context.getRunLength()){
				context.freezeRunLength();
			} else {
				context.resetRunLength();
			}
			
			if (null != oldContext){
				// Cause a migration of oldContext home.
				CoreModel homeCore = target.getMachine().getNativeCore(oldContext);
				
				// reschedule somehow if the core is stalled
				// TODO: induce memory fence!
				// TODO: this is really wrong!!
				
				target.migrate(target, homeCore, new MigrationEvent(oldContext, target, homeCore, MessageType.Eviction, -1, -1));
			}
		}
	}