gt: 		if (y < this.getY() && blockUp)
context: import java.awt.Graphics;
  import java.io.IOException;
  import java.util.Timer;
  import java.util.TimerTask;
  
  /**
   * Class representing a character like Marine LePen or Donald Trump
   *
   */
  //TODO move to model package
  public class Character extends MobileSprite implements CollisionEventListener {
  
  	public final static String BODY_FILE = "img/characters/Body.png";
  	public final static int BODY_WIDTH = 138;
  	public final static int BODY_HEIGHT = 200;
  	public final static int CHARACTER_WIDTH = 55;
  	public final static int CHARACTER_HEIGHT = 80;
  	public final static int HP_MAX = 100;
  
  	public final int ENSURE_GRAVITY_PERIOD = 1000;
  	public final double JUMP_SPEED = 2.5;
  	public final double GO_SPEED = 1;
  
  	private BaseVisual head;
  	private Weapon specialWeapon;
  	private Timer ensureGravityTimer;
  	private SoundFile jumpSound;
  	private int hp;
  	private double lastX, lastY;
  	private boolean blockLeft, blockRight, blockUp, blockDown;
  
  	//TODO use functional interface
  	private class EnsureGravityTask extends TimerTask {
  
  		@Override
  		public void run() {
  			if (blockDown) {
  				blockDown = false;
  				Character.this.setVelocityY(-GO_SPEED);
  			}
  		}
  
  	};
  
  	/**
  	 * Create Character with a head of specific size at specific position.
  	 * 
  	 * @param headPath
  	 * @param x
  	 *            Head's relative x-coordinate to body in Space reference.
  	 * @param y
  	 *            Head's relative y-coordinate to body in Space reference.
  	 * @param w
  	 *            Head's width in Space reference.
  	 * @param h
  	 *            Head's height in Space reference.
  	 * @throws IOException
  	 */
  	public Character(String headPath, String jumpPath, int x, int y, int w, int h, Weapon specialWeapon)
  			throws IOException {
  		super(BODY_FILE, BODY_WIDTH, BODY_HEIGHT);
  		this.addCollisionEventListener(this);
  		jumpSound = new SoundFile(jumpPath);
  		head = new BaseVisual(headPath, w, h);
  		head.setX(x);
  		head.setY(y);
  		Graphics g = img_orig.getGraphics();
  		g.drawImage(head.getImage(), head.getIntX(), head.getIntY(), head.getWidth(), head.getHeight(), null);
  		g.dispose();
  		this.hp = HP_MAX;
  		this.width = CHARACTER_WIDTH;
  		this.height = CHARACTER_HEIGHT;
  		this.specialWeapon = specialWeapon;
  	}
  
  	@Override
  	public void startCollision(CollisionEvent e) {
  		if (e.getTarget() instanceof Grenade)
  			return;
  		this.setX(lastX);
  		this.setY(lastY);
  		switch (e.getDirection()) {
  		case BOTTOM:
  			blockDown = true;
  			break;
  		case LEFT:
  			blockLeft = true;
  			break;
  		case RIGHT:
  			blockRight = true;
  			break;
  		case TOP:
  			blockUp = true;
  			break;
  		default:
  			break;
  		}
  	}
  
  	@Override
  	public void endCollision(CollisionEvent e) {
  		switch (e.getDirection()) {
  		case BOTTOM:
  			blockDown = false;
  			break;
  		case LEFT:
  			blockLeft = false;
  			break;
  		case RIGHT:
  			blockRight = false;
  			break;
  		case TOP:
  			blockUp = false;
  			break;
  		default:
  			break;
  		}
  	}
  
  	//TODO make physics more realistic
  	private void startEnsureGravity() {
  		if (ensureGravityTimer == null) {
  			ensureGravityTimer = new Timer();
  			ensureGravityTimer.schedule(new EnsureGravityTask(), 0, ENSURE_GRAVITY_PERIOD);
  		}
  	}
  
  	/**
  	 * Start continuous move of character to the left
  	 */
  	public void goLeft() {
  		this.setVelocityX(this.getVelocityX() - GO_SPEED);
  		startEnsureGravity();
  	}
  
  	/**
  	 * Start continuous move of character to the right
  	 */
  	public void goRight() {
  		this.setVelocityX(this.getVelocityX() + GO_SPEED);
  		startEnsureGravity();
  	}
  
  	/**
  	 * Stop continuous move of character to the left or right
  	 */
  	public void stop() {
  		this.setVelocityX(0);
  		if (ensureGravityTimer != null)
  			ensureGravityTimer.cancel();
  		ensureGravityTimer = null;
  	}
  
  	/**
  	 * Make character jump. Does not ensure that jump is misused for flying
  	 */
  	public void jump() {
  		if (!blockDown)
  			return;
  		unblock();
  		this.setVelocityY(-JUMP_SPEED);
  		jumpSound.play();
  	}
  
  	/**
  	 * Unblock Character in case of non detected end of collision, e.g when Map
  	 * changes
  	 */
  	public void unblock() {
  		blockDown = false;
  		blockLeft = false;
  		blockRight = false;
  		blockUp = false;
  		ContextService.getSpace().purgeCollisionEvents(this);
  	}
  
  	/**
  	 * Freeze position when Character hit something. Useful to prevent sliding
  	 * on Map.
  	 */
  	public void stopOnHit() {
  		this.addCollisionEventListener(new CollisionEventListener() {
  
  			@Override
  			public void startCollision(CollisionEvent e) {
  				MobileSprite m = e.getSource();
  				m.setVelocityX(0);
  				m.removeCollisionEventListener(this);
  			}
  
  			@Override
  			public void endCollision(CollisionEvent e) {
  			}
  
  		});
  	}
  
  	@Override
  	public void setX(double x) {
  		lastX = this.getX();
  		if (x > this.getX() && blockRight)
  			return;
  		if (x < this.getX() && blockLeft)
  			return;
  		super.setX(x);
  	}
  
  	@Override
  	public void setY(double y) {
  		lastY = this.getY();
  		if (y > this.getY() && blockDown)
  			return;
  