System.out.println("updating position of " + tm); final HashMap newMapTiles = new HashMap(); final HashMap oldMapTiles = new HashMap(); final HashMap currentMapTiles = new HashMap(); final HashMap undoList = new HashMap();
    private void updateTrainPosition(TrainModel tm) {	System.out.println("updating position of " + tm);	final HashMap newMapTiles = new HashMap();	final HashMap oldMapTiles = new HashMap();	final HashMap currentMapTiles = new HashMap();	final HashMap undoList = new HashMap();	final PathLength pl = new PathLength();	GameTime now = (GameTime) world.get(ITEM.TIME, Player.AUTHORITATIVE);	TrainMotionModel tmm = tm.getTrainMotionModel();	if (tmm.isBlocked() &&		! acquireAllLocks(tm))	    return;	/* work out where we should be */	/* speed in tiles per BigTick */	float speed = ((float) ((EngineType) world.get(KEY.ENGINE_TYPES,		    tm.getEngineType(), Player.AUTHORITATIVE)).getMaxSpeed()) /			EngineType.TILE_HOURS_PER_MILE_BIGTICKS;	/* speed in deltas per tick */	speed *= TrackTile.DELTAS_PER_TILE / GameTime.TICKS_PER_BIG_TICK;	int ticksSinceLastSync = now.getTime() -	    tmm.getTimeOfLastSync().getTime();	pl.setLength(tmm.getPathToDestination().getActualLength());	pl.add(tmm.getPathTraversedSinceLastSync().getActualLength());	int distanceToTarget = (int) (pl.getLength() - speed *	    ticksSinceLastSync);	System.out.println ("distanceToTarget = " + distanceToTarget +	       	", pathToDestination = " +		tmm.getPathToDestination().getLength() + 		", pathTraversed = " +		tmm.getPathTraversedSinceLastSync().getLength());	if (distanceToTarget < 0)	    distanceToTarget = 0;	/* can happen due to rounding */	if (distanceToTarget > tmm.getPathToDestination().getLength())	    return;	assert distanceToTarget <= tmm.getPathToDestination().getLength();	TrainPath tp =	    tmm.getPathToDestination().truncateTail(distanceToTarget);	System.out.println ("pathToAdd = " + tp.toString() + ", remainder = "		+ tmm.getPathToDestination());	/* check to see if we have crossed a tile boundary */	newMapTiles.clear();	oldMapTiles.clear();	currentMapTiles.clear();	undoList.clear();	tm.getPosition().getMapCoordsAndDirections(currentMapTiles);	Iterator i = currentMapTiles.entrySet().iterator();	while (i.hasNext()) {	    Entry e = (Entry) i.next();	    TrackTile tt = world.getTile((Point)		    e.getKey()).getTrackTile();	    tt.releaseLock(((Byte) e.getValue()).byteValue());	}	TrainPath pos = tm.getPosition();	TrainPath removed = pos.moveHeadTo(tp);	pos.getMapCoordsAndDirections(newMapTiles);	System.out.println("removed " + removed);	i = newMapTiles.entrySet().iterator();	boolean undoNeeded = false;	while (i.hasNext()) {	    byte extraLocks;	    Entry e = (Entry) i.next();	    TrackTile tt = world.getTile((Point)		    e.getKey()).getTrackTile();	    extraLocks = ((Byte) e.getValue()).byteValue();	    if (! tt.getLock(extraLocks)) {		undoNeeded = true;		break;	    }	    undoList.put(e.getKey(), new Byte(extraLocks));	}	if (undoNeeded) {	    /* undo all locks, restore the pathToDestination and bail out */	    i = undoList.entrySet().iterator();	    while (i.hasNext()) {		Entry e = (Entry) i.next();		world.getTile((Point) e.getKey()).		    getTrackTile().releaseLock		    (((Byte) e.getValue()).byteValue());	    }	    tmm.getPathToDestination().append(tp);	    pos.moveTailTo(removed);	    assert false;	    return;	}	/* increment the pathTraversedSinceLastSync */	tmm.getPathTraversedSinceLastSync().prepend(removed);    }