 pour chaque particule
        ListIterator<Particle> iterator = particles.listIterator ();
        while (iterator.hasNext ()) {
            // particule courante
            Particle particle = iterator.next ();
            // appliquer la gravite
            particle.setVelocity (particle.getVelocity ().plus (gravity.times (deltaT)));
            // si l'utilisateur est en train de cliquer
            if (mousePosition!= null) {            	
                // appliquer la force de la souris
                Vector mouseForce = getMouseForce (particle, mousePosition, previousMousePosition, deltaT);
                particle.setVelocity (particle.getVelocity ().plus (mouseForce));
            }
        }
    }
    
    /**
     * Retourne le vecteur de la force que la souris applique sur une particule.
     * 
     * @param particle Particule pour laquelle on veut le vecteur force.
     * @param mousePosition Position de la souris, non-nulle.
     * @return Force appliquee sur particle.
     */
    private Vector getMouseForce (Particle particle, Point2D.Double mousePosition, Point2D.Double previousMousePosition, double deltaT) {
        Vector m = new Vector (mousePosition);
        Vector m2 = previousMousePosition == null? m : new Vector (previousMousePosition);
        Vector d = m.minus (particle.getPositionVector ());
        Vector vm = m.minus (m2);
        if (d.getMagnitude () < MOUSE_PULL_DISTANCE) {
            return d.times(MOUSE_PULL_FACTOR).plus (vm.times (1)).minus(gravity.times(deltaT));
        }
        return Vector.NIL;
    }
    
    /**
     * Applique la viscosite sur toutes les particules pour que les particules s'attirent un peu 
     * entre elles. Donne une certaine consistence au liquide.
     * 
     * @param deltaT Intervalle de temps.
     */
    private void applyViscosity (double deltaT) {
        // pour chaque particule
        ListIterator<Particle> iterator = particles.listIterator ();
        while (iterator.hasNext ()) {
            // particule courante, son indice et sa position
            Particle particle = iterator.next ();
            // trouver les voisins de cette particule
            LinkedList<Particle> neighborList = neighborLists.get (particle);
            // appliquer la viscosite
            particle.setViscosityForce(Vector.NIL);
            ViscositySolver.applyViscosity (particle, deltaT, neighborList, viscosity, 
                    radius);
        }
    }
    
    /**
     * Deplace les particules d'apres leur velocite.
     * 
     * @param deltaT Intervalle de temps.
     */
    private void advanceParticles (double deltaT) {
        // pour chaque particule
        ListIterator<Particle> iterator = particles.listIterator ();
        while (iterator.hasNext ()) {
            // particule courante
            Particle particle = iterator.next ();
            // avancer la particule
            particle.advance (deltaT);
        }
    }
    
    /**
     * Met a jour les listes des voisins pour chaque particule.
     */
    private void updateNeighbors () {
        // mettre a jour la position de chaque particule dans la grille
    	grid.update ();
    	// pour chaque particule
    	ListIterator<Particle> iterator = particles.listIterator ();
    	while (iterator.hasNext ()) {
    	    // particule et son indice
    	    Particle particle = iterator.next ();
    	    // mettre a jour la liste des voisins
            LinkedList<Particle> neighbors = grid.neighborsOf (particle);
            neighborLists.put (particle, neighbors);
    	}
    }
    
    /**
     * Ajuste la position des particules selon les particules voisines, pour que la densite tende
     * vers une valeur precise.
     * 
     * @param deltaT Intervalle de temps.
     */
    private void doubleDensityRelaxation (double deltaT) {
        // pour chaque particule
        ListIterator<Particle> iterator = particles.listIterator ();
        while(iterator.hasNext()) {
        	Particle particle = iterator.next();
        	particle.setStiffnessForce(Vector.NIL);
        }
        iterator = particles.listIterator();
        while (iterator.hasNext ()) {
            // position, indice et particule courante
            Particle particle = iterator.next ();
            LinkedList<Particle> neighborList = neighborLists.get (particle);
            // appliquer l'ajustement de la densite
            DensitySolver.doubleDensityRelaxation (particle, deltaT, neighborList, stiffness, nearbyStiffness,
                    restDensity, radius);
        }
    }
    
    /**
     * Resout les collisions entre les murs et les particules.
     */
    private void resolveCollisions (double deltaT) {
        // pour chauqe particule
        ListIterator<Particle> iterator = particles.listIterator ();
        while (iterator.hasNext ()) {
            // particule courante
            Particle particle = iterator.next ();
            // resoudre les collisions
            CollisionSolver.resolveCollisions (particle, bounds, COLLISION_SOFTNESS, deltaT);
        }
    }
    
    /**
     * Met a jour la velocite des particules.
     * 
     * @param deltaT Intervalle de temps.
     */
    private void updateVelocity (double deltaT) {
        // pour chaque particule
        ListIterator<Particle> iterator = particles.listIterator ();
        while (iterator.hasNext ()) {
            // particule courante
            Particle particle = iterator.next ();
            // affecter comme velocite le deplacement divise par l'intervalle de temps
            Vector velocity = particle.getPositionVector ()
                   .minus (particle.getPreviousPositionVector ())
                   .times (1 / deltaT);
            particle.setVelocity (velocity);
        }
    }
    
    /**
     * Retourne un iterateur pour la liste des particules de la simulation.
     * 
     * @return Iterateur pour les particules.
     */
    public Iterator<Particle> getParticleIterator () {
        return particles.iterator ();
    }
    
    public Polygon[] getWalls() {
    	return bounds.getWalls();
    }

    /**
     * Retourne le vecteur gravite.
     * 
     * @return Vecteur gravite.
     */
    public Vector getGravity () {
        return gravity;
    }

    /**
     * Affecte la valeur de la gravite.
     * 
     * @param gravity Nouvelle gravite.
     */
    public void setGravity (Vector gravity) {
        this.gravity = gravity;
    }

    /**
     * Retourne le rayon des interactions entre les particules.
     * 
     * @return Rayon des interactions entre les particules.
     */
    public double getRadius () {
        return radius;
    }

    /**
     * Retourne la rigidite du fluide. La rigidite permet la conservation du volume dans le fluide.
     * 
     * @return Rigidite du fluide.
     */
    public double getStiffness () {
        return stiffness;
    }

    /**
     * Affecte la valeur de la rigidite du fluide.
     * 
     * @param stiffness Nouvelle rigidite.
     */
    public void setStiffness (double stiffness) {
        this.stiffness = stiffness;
    }

    /**
     * Retourne la rigidite proche. Empeche que les particules du fluide se collent
     * les unes aux autres et creent de minis "globules".
     * 
     * @return Rigidite proche.
     */
    public double getNearbyStiffness () {
        return nearbyStiffness;
    }

    /**
     * Affecte la valeur de la rigidite proche du fluide.
     * 
     * @param nearbyStiffness Nouvelle rigidite proche.
     */
    public void setNearbyStiffness (double nearbyStiffness) {
        