public Vec2 getMaximumPossibleMovement(MovingObject mo){
        maximumMovement = mo.getCurrentDirection();
        Vec2 tempMaximumMovement = new Vec2(maximumMovement);
        Vec2 currentPosition = mo.getCurrentCenterPosition();
        Vec2 predictedPosition = mo.getPredictedCenterPosition();
        Vec2 min = currentPosition.min(predictedPosition);//upper-left position of collision area
        Vec2 max = currentPosition.max(predictedPosition);//lower-right position of collision area
        
        min.addTo(mo.getAabb().getHalfExtent().getNegation());
        min.addTo(new Vec2(1,1));
        max.addTo(mo.getAabb().getHalfExtent());
        max.addTo(new Vec2(-1,-1));
        
        //get tiles in collision area
        int firstTileX = Math.max(map.worldCoordToTileX(min.getX()), 0);
        int firstTileY = Math.max(map.worldCoordToTileY(min.getY()), 0);
        
        int lastTileX = Math.min(map.worldCoordToTileX(max.getX()), map.getColumnsInMap() - 1);
        int lastTileY = Math.min(map.worldCoordToTileY(max.getY()), map.getRowsInMap() - 1);        
        
        //for all tiles in collision area
        for(int row = firstTileY; row <= lastTileY; row++){
            for(int column = firstTileX; column <= lastTileX; column++){
                if(map.getTileType(row, column) == TileType.BLOCKING){
                    Vec2 center = new Vec2(map.tileCoordToWorldX(column),map.tileCoordToWorldY(row));
                    Vec2 halfExtent = new Vec2(map.getTileWidth() / 2, map.getTileHeight() / 2);
                    CollisionTile collisionTile = new CollisionTile(center, halfExtent);
                    CollisionParams collisionParams = willCollide(mo, collisionTile);
 
                    if(collisionParams.collided){
                        if(Math.abs(collisionParams.getMaximumMovement().getX()) < Math.abs(tempMaximumMovement.getX()))
                            tempMaximumMovement.setX(collisionParams.getMaximumMovement().getX());
                        if(Math.abs(collisionParams.getMaximumMovement().getY()) < Math.abs(tempMaximumMovement.getY()))
                            tempMaximumMovement.setY(collisionParams.getMaximumMovement().getY());
                    }
                    verticalInnerCollide = false;
                }
            }
        }
//        return maximumMovement;
        return tempMaximumMovement;
    }