public void processStep() throws FroshProjectException {
        // Increment the day number
        //
        day++;

        // Log a message
        //
        FroshProject.getLogger().log(Level.FINE, "Processing day " + day);

        // Get the new weather state
        //
        processWeatherChange();

        // Initialize a boolean to determine if the simulation is over
        //
        Boolean isSimulationOver = true;

        // Create a clone of the map
        //
        WorldMap oldWorldMap = (WorldMap) worldMap.clone();

        // Get the two dimensions of the matrix
        //
        int matrixX = worldMap.getWidth();
        int matrixY = worldMap.getHeight();

        // Iterate on all the elements
        //
        Element currentElement, newState;
        Neighbourhood currentNeighbourhood;
        for (int currentX = 0; currentX < matrixX; currentX++) {
            for (int currentY = 0; currentY < matrixY; currentY++) {
                // Get the current Element
                //
                currentElement = oldWorldMap.getElementAtLocation(currentX,
                        currentY);
                
                // Control if an Element is present
                //
                if (currentElement != null) {
                    // Log a message
                    //
                    FroshProject.getLogger().log(Level.FINE,
                            "Processing Element " + currentElement);

                    // Check if its status is dead or healthy, this will
                    // determine if the simulation is over or not
                    //
                    isSimulationOver &= currentElement.isSimulationOver();

                    // Get its neighbourhood
                    //
                    currentNeighbourhood = oldWorldMap.getNeighbourhood(
                            currentX, currentY, weatherContagionRate,
                            weatherInfectionRate);

                    // Call the process method of the Element
                    //
                    newState = currentElement.processStep(currentNeighbourhood);

                    // Log a message
                    //
                    FroshProject.getLogger().log(Level.FINE,
                            "New state for the last Element : " + newState);

                    // Check for possible new infections
                    //
                    for (Element newInfectedElement : currentNeighbourhood
                            .getInfectedElements()) {
                        worldMap.replaceElement(newInfectedElement);
                        // Log a message
                        //
                        FroshProject.getLogger().log(
                                Level.FINE,
                                "An Element fron the neighbourhood was affected:"
                                        + newInfectedElement);

                    }

                    // Put the Element in the new matrix
                    //
                    worldMap.replaceElement(newState, currentX, currentY);
                }
            }
        }

        // Give the new state to the controller, or null if the simulation is
        // over
        //
        setChanged();
        notifyObservers(isSimulationOver ? null : getState());
    }