public void move(int x, int y, Entity entity) {

		/*
		 * At some point we have to lock on the entity in order to give it an
		 * update as to its current location (and direction). If a collision is
		 * going to occur at this point, we can't have our cake and eat it too:
		 * it won't be possible to getLocation() of the other entity to detect
		 * the collision if it's being locked. Board has to keep track of the
		 * locations to which the Entities are requesting to move, so that it
		 * can detect a collision.
		 */

		// Should be safe to ask the entity for its location, considering
		// that it's not going to move while it's moving.
		int[] currLoc = entity.getLocation();
		// if it's trying to go out of bounds, make its
		// destination == its current location.
		// This should be fine with the below code,
		// since the locks are reentrant.
		boolean wallCollision = false;
		ReentrantLock currentTile;
		ReentrantLock goalTile;
		boolean startedOutOfBounds = false;

		// catch things that have been created out of bounds.
		if (isOOB(currLoc[0], currLoc[1])) {
			currentTile = getTile(0, 0);
			startedOutOfBounds = true;
		} else {
			currentTile = getTile(currLoc[0], currLoc[1]);
		}

		if (isOOB(x, y)) {// going out of bounds
			wallCollision = true;
			if (startedOutOfBounds)// started out and going out, there's no hope
									// for you. Cancel.
				return;
			goalTile = getTile(currLoc[0], currLoc[1]);// started out but going
														// in.
		} else {
			goalTile = getTile(x, y);

		}

		// lock current tile and goal tile-- this will
		// prevent whoever is in the goal tile from moving away
		currentTile.lock();
		goalTile.lock();

		// okay, move where you wanted to move,
		// and unlock the space you no longer occupy.
		entity.updateLocation(x, y);
		currentTile.unlock();

		ArrayList<Entity> collisions = new ArrayList<Entity>();
		// find and resolve collections
		synchronized (entities) {
			for (Entity other : entities) {
				// yes, compare by reference, can't
				// collide with oneself.
				if (other != entity) {
					if (entity.getBoundingBox()
							.overlaps(other.getBoundingBox())) {
						// resolve collisions for current occupants of the tile,
						// but wait until the end to handle them for the moving
						// entity to make the rare occasional chain reaction a
						// little simpler.
						// this won't be *perfect* for things like tiny bullets,
						// but it'll be
						// acceptably close.
						if (entity.getType() != other.getType()) // just
																	// suppress
																	// some
																	// useless
																	// messages
							System.out.println(entity + " collided with "
									+ other);
						other.collidesWith(entity.getType());
						collisions.add(other);
					}
				}
			}
		}

		// We can unlock the goal tile now because the entity has now moved into
		// that space and we know what it collided with. It's important to unlock
		// this tile first to avoid deadlock scenarios caused by possibly complicated
		// collision resolution involving more than two entities.
		goalTile.unlock();

		// now resolve all the collisions for the moved entity
		for (Entity collision : collisions) {
			entity.collidesWith(collision.getType());
		}

		if (wallCollision) {
			System.out.println(entity + " collided with the wall");
			entity.collidesWith(EntityTypes.MUSHROOM);
		}
	}