/**
         * Given a job, executes its computation. The computation of a
         * Job consist in the assignment of the job to a JobExecutor
         * which has the purpose of execute the file tranfer according
         * to a specific protocol.
         * Returns the ExecutableThread on which the job is beeing managed.
         */
        public ExecutableThread scheduleJob(SendingJob job)
        {
            // Pushes the job in the list of in-service jobs
            JobsList.Sending.push(job);

            // Schedules a thread to send the packet
            JobExecutor sender = new JobExecutor(job);

            // When the transmissione ends
            sender.OnTrasmissionEnd += () => {
                // Removes the job from the active jobs list
                JobsList.Sending.remove(job.Id);
            };

            // When a connection error occours
            sender.ConnectionError += (Job j) => {
                ConnectionError?.Invoke(j);
            };


            // When a file error occours
            sender.FileError += (Exception e, Job j) => {
                FileError?.Invoke(e, j);
            };
            // Run the sender
            sender.run();

            return(sender);
        }
        /**
         * Constructor
         */
        public JobExecutor(SendingJob job)
        {
            this.job = job;

            this.job.PropertyChanged += (object sender, PropertyChangedEventArgs args) => {
                if (args.PropertyName == "Status" && this.job.Status == Job.JobStatus.StoppedByLocal)
                {
                    StopThread();
                }
            };
        }