public void run() {
        int lastArrival = 0;

        Statistics.console.log("Simulation Starts ....");
        while (true) {
            int nextArrival = arrivalRand.nextInt();
            while (EventsQueue.peekTime() < lastArrival + nextArrival) {
                EventsQueue.executeEvent();
            }
            SimulationClk.clock += nextArrival;
            if (SimulationClk.clock > MAX_TIME)
                break;
            lastArrival = SimulationClk.clock;
            int group = getCustomerNum();
            Statistics.console.log("[" + SimulationClk.clock + "] arrival of "
                    + group + " Customers");
            Statistics.trace.log("[" + SimulationClk.clock + "][Arrival]"
                    + group);
            Statistics.CustomersEnteredSystem(group);
            for (int i = 0; i < group; i++) {
                final Customer cust = new Customer();
                int route = getRoute();
                cust.setType(route);
                switch (route) {
                case Const.CUST_HOTFOOD:
                    Statistics.console.log("Customer " + cust.getId()
                            + " going to hot food");
                    Statistics.UpdateQueueLength(hotfoodSys.getQueueLength(),
                            Const.HOTFOOD_SERVER);
                    // Statistics.CustomerEnteredQueue(cust,
                    // Const.HOTFOOD_SERVER);
                    hotfoodSys.enqueue(cust, new Event() {

                        @Override
                        public void execute() {
                            Statistics.console.log("Customer " + cust.getId()
                                    + " finished hot food and going to drinks");
                            Statistics.UpdateQueueLength(
                                    hotfoodSys.getQueueLength(),
                                    Const.HOTFOOD_SERVER);
                            // Statistics.CustomerQuitQueue(cust,
                            // Const.HOTFOOD_SERVER);
                            // Statistics.CustomerEnteredQueue(cust,
                            // Const.DRINKS_SERVER);
                            drinkSys.enqueue(cust, new JoiningCashierEvent(
                                    cashiers, cust));
                        }

                        @Override
                        public String getDescription() {
                            return "hot food service event";
                        }
                    });
                    break;
                case Const.CUST_SANDWICHES:
                    Statistics.console.log("Customer " + cust.getId()
                            + " going to sandwiches");
                    Statistics.UpdateQueueLength(
                            sandwichesSys.getQueueLength(),
                            Const.SANDWICH_SERVER);
                    // Statistics.CustomerEnteredQueue(cust,
                    // Const.SANDWICH_SERVER);
                    sandwichesSys.enqueue(cust, new Event() {

                        @Override
                        public void execute() {
                            Statistics.console.log("Customer "
                                    + cust.getId()
                                    + " finished sandwiches and going to drinks");
                            Statistics.UpdateQueueLength(
                                    sandwichesSys.getQueueLength(),
                                    Const.SANDWICH_SERVER);
                            // Statistics.CustomerQuitQueue(cust,
                            // Const.SANDWICH_SERVER);
                            // Statistics.CustomerEnteredQueue(cust,
                            // Const.DRINKS_SERVER);
                            drinkSys.enqueue(cust, new JoiningCashierEvent(
                                    cashiers, cust));
                        }

                        @Override
                        public String getDescription() {
                            return "sandwiches service event";
                        }
                    });
                    break;
                case Const.CUST_DRINKS:
                    Statistics.console.log("Customer " + cust.getId()
                            + " going to drinks only");
                    // Statistics.CustomerEnteredQueue(cust,
                    // Const.DRINKS_SERVER);
                    drinkSys.enqueue(cust, new JoiningCashierEvent(cashiers,
                            cust));
                    break;
                default:
                    break;
                }
            }
        }
        while (EventsQueue.getSize() > 0) {
            EventsQueue.executeEvent();
        }
        Statistics.console.log("Simulation Finished ....");
        // average delays in queue for hotfood, sandwiches and cashiers
        Statistics.console.log("Average Delay in Hot Food Server= "
                + Statistics.getAvgDelayInQueue(Const.HOTFOOD_SERVER));

        Statistics.console.log("Average Delay in Sandwiches Server= "
                + Statistics.getAvgDelayInQueue(Const.SANDWICH_SERVER));

        Statistics.console.log("Average Delay in Drinks Server= "
                + Statistics.getAvgDelayInQueue(Const.DRINKS_SERVER));

        Statistics.console.log("Average Delay in Cashiers= "
                + Statistics.getAvgDelayInQueue(Const.CASHIER_SERVER));
        
        Statistics.console.log("-------------------------------");
        // maximum delays in queue for hotfood, sandwiches and cashiers
        Statistics.console.log("Max Delay in Hot Food Server= "
                + Statistics.getMaxDelayInQueue(Const.HOTFOOD_SERVER));

        Statistics.console.log("Max Delay in Sandwiches Server= "
                + Statistics.getMaxDelayInQueue(Const.SANDWICH_SERVER));

        Statistics.console.log("Max Delay in Drinks Server= "
                + Statistics.getMaxDelayInQueue(Const.DRINKS_SERVER));

        Statistics.console.log("Max Delay in Cashiers= "
                + Statistics.getMaxDelayInQueue(Const.CASHIER_SERVER));

        Statistics.console.log("-------------------------------");
        // time average number in queue for hotfood, sandwiches and cashiers
        Statistics.console
                .log("Time average number in queue in Hot Food Server= "
                        + Statistics.getTimeAvgNumInQueue(Const.HOTFOOD_SERVER));

        Statistics.console
                .log("Time average number in queue in Sandwiches Server= "
                        + Statistics
                                .getTimeAvgNumInQueue(Const.SANDWICH_SERVER));

        Statistics.console.log("Time average number in queue in Cashiers= "
                + Statistics.getTimeAvgNumInQueue(Const.CASHIER_SERVER));

        Statistics.console.log("-------------------------------");
        // max number in queue for hotfood, sandwiches and cashiers
        Statistics.console.log("Max number in queue in Hot Food Server= "
                + Statistics.getMaxNumInQueue(Const.HOTFOOD_SERVER));

        Statistics.console.log("max number in queue in Sandwiches Server= "
                + Statistics.getMaxNumInQueue(Const.SANDWICH_SERVER));

        Statistics.console.log("max number in queue in Cashiers= "
                + Statistics.getMaxNumInQueue(Const.CASHIER_SERVER));

        Statistics.console.log("-------------------------------");
        // average total delay in all queue for each type f customers
        Statistics.console
                .log("Average delay in all queues for hotfood server Customers= "
                        + Statistics.getAvgDelayForCust(Const.CUST_HOTFOOD));

        Statistics.console
                .log("Average delay in all queues for sandwiches server Customers= "
                        + Statistics.getAvgDelayForCust(Const.CUST_SANDWICHES));

        Statistics.console
                .log("Average delay in all queues for drinks server Customers= "
                        + Statistics.getAvgDelayForCust(Const.CUST_DRINKS));

        Statistics.console.log("-------------------------------");
        // max total delay in all queue for each type f customers
        Statistics.console
                .log("Max delay in all queues for hotfood server Customers= "
                        + Statistics.getMaxDelayForCust(Const.CUST_HOTFOOD));

        Statistics.console
                .log("Max delay in all queues for sandwiches server Customers= "
                        + Statistics.getMaxDelayForCust(Const.CUST_SANDWICHES));

        Statistics.console
                .log("Max delay in all queues for drinks server Customers= "
                        + Statistics.getMaxDelayForCust(Const.CUST_DRINKS));

        Statistics.console.log("-------------------------------");
        // overall average delay in all queue for all customers
        Statistics.console
                .log("Overall average delay in queues for all Customers= "
                        + Statistics.getOverallAvgDelay());

        Statistics.console
                .log("Overall average delay in queues for all Customers wieghted by their prob= "
                        + (0.8
                                * Statistics
                                        .getMaxDelayForCust(Const.CUST_HOTFOOD)
                                + 0.15
                                * Statistics
                                        .getMaxDelayForCust(Const.CUST_SANDWICHES) + 0.05 * Statistics
                                .getMaxDelayForCust(Const.CUST_DRINKS)));

        Statistics.console.log("-------------------------------");
        // timeavg total number in system
        Statistics.console.log("Time average number in system = "
                + Statistics.getTimeAvgNumInSystem());
        Statistics.console.log("-------------------------------");
        // max number in system
        Statistics.console.log("max number in system = "
                + Statistics.getMaxNumInSystem());

        Statistics.console
                .log("-----------------------------------------------------");
        Statistics.console.close();
        Statistics.trace.close();
        // Statistics.drawQueueLen();
    }