static List<Command> deliver(Simulation sim) {

    List<Command> commands = new ArrayList<>();

    List<Order> orderedSorted = new ArrayList<>(sim.orders.values());
    Collections.sort(orderedSorted, (o1, o2) -> o1.totalWeight - o2.totalWeight);

    mainLbl:
    for (Order order : orderedSorted) {

      for (int p : order.products) {
        System.out.println("Product Id :" + p);
        wareHouseLbl:
        for (Warehouse w : sim.warehouses.values()) {
          //                        System.out.println("Warehouse : products : "+
          // Arrays.toString(w.products));
          if (w.products[p] > 0) {

            Random random = new Random();
            // drone le plus proche du warehouse courant
            Drone d = closestDrone(w, sim.drones.values());
            //                            Drone d = sim.drones.get(0);
            //                            Drone d =
            // sim.drones.get(random.nextInt(sim.drones.size()));

            //                            int nbProducts = Math.min((sim.maxpayload /
            // sim.products.get(p).weight));
            int nbProducts = 1;
            System.out.println(nbProducts);

            long delta = (distance(new int[] {d.row, d.col}, new int[] {w.row, w.col}) + 1);
            sim.turns -= delta;
            if (sim.turns < 0) {
              System.out.println("Turns over :(");
              break mainLbl;
            }
            commands.add(new LoadCommand(d.id, w.id, order.id, p, nbProducts));
            w.products[p] -= nbProducts;
            d.row = w.row;
            d.col = w.col;

            delta = (distance(new int[] {d.row, d.col}, new int[] {order.row, order.col}) + 1);
            sim.turns -= delta;
            if (sim.turns < 0) {
              System.out.println("Turns over :(");
              break mainLbl;
            }
            commands.add(new DeliverCommand(d.id, order.id, p, nbProducts));
            d.row = order.row;
            d.col = order.col;
            break wareHouseLbl;
          }
        }
      }
    }

    return commands;
  }
  Main init() {

    // Create a chart to monitor the infection progress rate
    final XYLineChart chart =
        new XYLineChart("Infection Rate", 5.0, "Infected Nodes (%)", "time(s)");
    chart.setYRange(false, 0, 100);
    chart.setSeriesLinesAndShapes("s0", true, true);

    Gui.setFrameRectangle("MainFrame", 0, 0, 480, 480);
    Gui.setFrameRectangle("Infection Rate", 484, 0, 480, 480);

    // Create the simulation nodes
    for (int i = 0; i < TOTAL_NODES; i++) new Node();

    // Initialize the simulation nodes
    for (Node i : NodeDB.nodes()) i.init();

    NodeDB.randomNode().infect();

    // Sets up a periodic task that, at one second intervals, computes and shows the percentage of
    // infected nodes in the system
    // Stops the simulation when it detects that every node is infected...
    new PeriodicTask(1.0) {
      public void run() {
        double T = 0, N = 0;
        for (Node n : NodeDB.nodes()) {
          if (n.infected) T++;
          N++;
        }
        chart.getSeries("s0").add(Simulation.currentTime(), 100.0 * T / N);
        if (N == T) stop();
      };
    };

    // From time to time, select a random node to go fail and go offline...
    new Task(0) {
      public void run() {
        NodeDB.randomNode().crash();
        reSchedule(0.5 + 0.5 * rg.nextDouble()); // schedules a new execution of this task...
      }
    };

    // From time to time, create a new node. If the rate of births and deaths is the same,
    // the size of the system should stay constant on average.
    new Task(0) {
      public void run() {
        new Node().init();
        reSchedule(0.5 + 0.5 * rg.nextDouble()); // schedules a new execution of this task...
      }
    };

    super.setSimulationMaxTimeWarp(2.0);

    return this;
  }