/// <summary>
        /// Application entry point Main
        /// </summary>
        /// <param name="args">ID SERVICE-URL $ENTRY-URL</param>
        ///
        public static void Main(string[] args)
        {
            Uri serviceUri = new Uri(args[1]);

            int tcpPort = serviceUri.Port;

            int id = int.Parse(args[0]);

            String[] segments         = args[1].Split('/');
            String   remoteObjectName = segments[segments.Length - 1];

            //Create Service on this work
            BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();

            IDictionary props = new Hashtable();

            props["port"]    = tcpPort;
            props["timeout"] = 6000; // in milliseconds
            TcpChannel channel = new TcpChannel(props, null, provider);

            ChannelServices.RegisterChannel(channel, true);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(WorkerServices), remoteObjectName, WellKnownObjectMode.Singleton);

            try {
                IWorker newWorkerObj = (IWorker)Activator.GetObject(typeof(IWorker), serviceUri.ToString());

                // Register new worker in itself passing the ID and the URI
                newWorkerObj.RegisterOwnWorker(id, serviceUri.ToString());
            } catch (SocketException e) {
                System.Console.WriteLine("[WORKER_ERROR1:MAIN] Could not locate server");
                System.Console.WriteLine(e.StackTrace);
            } catch (Exception e) {
                System.Console.WriteLine("[WORKER_ERROR2:MAIN] Could not locate server");
                System.Console.WriteLine(e.StackTrace);
            }

            // If outer jobtracker exists
            if (args.Length >= 3)
            {
                try {
                    String  jobTrackerUri = args[2];
                    IWorker jobTrackerObj = (IWorker)Activator.GetObject(typeof(IWorker), jobTrackerUri);
                    // Broadcast to the network the new worker
                    jobTrackerObj.BroadcastNewWorker(id, serviceUri.ToString());
                } catch (SocketException e) {
                    System.Console.WriteLine("[WORKER_ERROR3:MAIN] Could not locate server");
                    System.Console.WriteLine(e.StackTrace);
                } catch (Exception e) {
                    System.Console.WriteLine("WORKER_ERROR4:MAIN] Could not locate server");
                    System.Console.WriteLine(e.StackTrace);
                }
            }

            System.Console.WriteLine("Press <enter> to terminate server...");
            System.Console.ReadLine();
        }
        /// <summary>
        /// Alerts the network that this node is alive
        /// </summary>
        public void WorkerIsAliveAsync()
        {
            while (true)
            {
                TestFrozenW();

                Thread.Sleep(2000);

                //Can we connect to a jobTracker
                bool jobTrackerAvailable = false;

                //Is Worker Working
                if (myWorkerStatus.getStatus() != WorkStatus.Status.Idle)
                {
                    //Ask the jobTracker if he is alive
                    IWorker jobTrackerObject = (IWorker)Activator.GetObject(typeof(IWorker), currentJobTracker);

                    try {
                        bool isJobTracker = jobTrackerObject.IsJobTrackerAlive(ownId, ownUrl, myWorkerStatus.getStatus() != WorkStatus.Status.Idle);

                        jobTrackerAvailable = isJobTracker; //Worker connected but his he the jobTracker
                    } catch (Exception) {                   //Cannot connect to job Tracker - 1st try
                        //Try again
                        try {
                            bool isJobTracker = jobTrackerObject.IsJobTrackerAlive(ownId, ownUrl, myWorkerStatus.getStatus() != WorkStatus.Status.Idle);

                            jobTrackerAvailable = isJobTracker; //Worker connected but his he the jobTracker
                        } catch (Exception) {                   //Cannot connect to job Tracker 2nd try
                            Console.WriteLine("Cannot connect to primary jobTracker:" + currentJobTracker);
                        }
                    }


                    if (!jobTrackerAvailable)   //Job Tracker not available

                    {
                        Console.WriteLine("Cannot connect to primary jobtracker on: " + currentJobTracker + "! Testing second jobtracker");

                        int    id  = int.MaxValue;
                        string url = "";

                        //Get the first non-jobtracker on the last view
                        workersIDUrlMutex.WaitOne();
                        foreach (KeyValuePair <int, string> workerPair in workersIDUrl)
                        {
                            if (workerPair.Value != currentJobTracker && workerPair.Key < id)
                            {
                                id  = workerPair.Key;
                                url = workerPair.Value;
                            }
                        }
                        workersIDUrlMutex.ReleaseMutex();

                        Console.WriteLine(">>>" + url);

                        if (id == ownId && url == ownUrl)
                        {
                            Console.WriteLine("I'm new jobtracker");

                            // Create Queue with workers
                            availableWorkerToJob = new ArrayList();

                            foreach (KeyValuePair <int, string> worker in workersIDUrl)
                            {
                                availableWorkerToJob.Add(worker.Value);
                            }

                            queueWorkersSemaphore = new Semaphore(workersIDUrl.Count(), workersIDUrl.Count());

                            currentJobTracker = url;

                            jobsAssigmentMutex.WaitOne();
                            foreach (WorkStatus ws in jobsAssigment)
                            {
                                if (ws.isWorkerAssigned() && !ws.isWorkCompleted())
                                {
                                    ws.removeWorker();
                                }
                            }
                            jobsAssigmentMutex.ReleaseMutex();

                            //Launch thread to isAlive
                            Thread isAliveThread = new Thread(() => IsAliveAsync());
                            isAliveThread.Start();


                            //Launch Thread to distribute works
                            Thread distributeWorkAsyncThread = new Thread(() => DistributeWorkAsync(className, dllCode, clientUrl));
                            distributeWorkAsyncThread.Start();
                        }
                        else
                        {
                            Console.WriteLine("New jobtracker on: " + url);

                            currentJobTracker   = url;
                            jobTrackerAvailable = true;

                            /*
                             * //Ask the secondJobTracker if he is alive
                             * IWorker secondJobTrackerObject = (IWorker)Activator.GetObject(typeof(IWorker), url);
                             *
                             * try {
                             *
                             *  bool isSecondJobTracker = secondJobTrackerObject.IsJobTrackerAlive(ownId, ownUrl, myWorkerStatus.getStatus() != WorkStatus.Status.Idle);
                             *
                             *  if (isSecondJobTracker) {//Second jobTracker is alive but is he jobtracker?
                             *
                             *      currentJobTracker = url;
                             *      jobTrackerAvailable = true;
                             *
                             *  }
                             *
                             * } catch (Exception) { //Cannot connect to second job Tracker 2nd try
                             *
                             *  //Nothing to do
                             * }*/
                        }
                    }
                }

                if (!jobTrackerAvailable)   //When none of the jobTrackers are alive


                {
                    foreach (KeyValuePair <int, string> node in workersIDUrl)
                    {
                        try{
                            IWorker nodeObj = (IWorker)Activator.GetObject(typeof(IWorker), node.Value);

                            //Am I in the network?
                            if (!nodeObj.IsNodeInNetwork(node))
                            {
                                nodeObj.BroadcastNewWorker(ownId, ownUrl);
                            }

                            //When it is in the network
                            break;
                        }catch (Exception e) {
                            //Can't connect to this one, try another one
                            continue;
                        }
                    } // if no worker connects it means that the network doesn't exist
                }
            }
        }