public Message CloseMeetingProposal(String meetingTopic, string username)
        {
            IClient ic   = findClient(username);
            User    user = ic.getUser();

            foreach (MeetingProposal mp in meetingProposals)
            {
                if (mp.getMPTopic() == meetingTopic)
                {
                    Monitor.Enter(mp);
                    if (mp.getCoordinator().getName().Equals(user.getName()))
                    {
                        if (mp.getStatus() == MeetingProposal.Status.Open)
                        {
                            Console.WriteLine("User " + user.getName() + " prompts to close meeting " + meetingTopic);
                            user.removeMyMP(mp);
                            Console.WriteLine("---Meeting removed from user's myMP list.");
                            Tuple <Boolean, String> dm = DecideMeeting(mp);
                            if (dm.Item1)
                            {
                                mp.setStatus(MeetingProposal.Status.Closed);
                                Console.WriteLine("---Meeting closed successfully.");
                                ic.setUser(user);
                                updateBackupProposals();
                                Monitor.Pulse(mp);
                                Monitor.Exit(mp);
                                return(new Message(true, dm.Item2, "Meeting closed successfully."));
                            }
                            else
                            {
                                mp.setStatus(MeetingProposal.Status.Cancelled);
                                Console.WriteLine("---Meeting cancelled.");
                                ic.setUser(user);
                                Monitor.Pulse(mp);
                                Monitor.Exit(mp);
                                return(new Message(true, null, "Meeting cancelled."));
                            }
                        }
                        else if (mp.getStatus() == MeetingProposal.Status.Closed)
                        {
                            Monitor.Pulse(mp);
                            Monitor.Exit(mp);

                            return(new Message(true, null, "Meeting already closed."));
                        }
                        else
                        {
                            Monitor.Pulse(mp);
                            Monitor.Exit(mp);
                            return(new Message(true, null, "Meeting cancelled."));
                        }
                    }
                    else
                    {
                        Monitor.Pulse(mp);
                        Monitor.Exit(mp);
                        return(new Message(true, null, "User not allowed to close meeting."));
                    }
                }
            }
            ic.setUser(user);

            return(new Message(true, null, "Meeting to close not found."));
        }
        public Message sequence(string url, string topic, string username)
        {
            Message mess = null;

            if (!closes.ContainsValue(url + " " + topic + " " + username))
            {
                seq++;
                closes.Add(seq, url + " " + topic + " " + username);

                Monitor.Enter(server); //lock
                try
                {
                    closes.TryGetValue(request, out string str);
                    string[] data = str.Split(' ');


                    if (!data[0].Equals(server.getURL()))
                    {
                        ServerCli      serv = (ServerCli)Activator.GetObject(typeof(ServerCli), data[0]);
                        Task <Message> task = Task <Message> .Factory.StartNew(() => serv.CloseMeetingProposal(data[1], data[2]));

                        bool done = task.Wait(timeout);

                        if (done)
                        {
                            mess = task.Result;
                        }
                        else
                        {
                            mess = new Message(false, null, "Server to close timed out abort operation");
                        }
                    }
                    else
                    {
                        Task <Message> task = Task <Message> .Factory.StartNew(() => CloseMeetingProposal(data[1], data[2]));

                        bool done = task.Wait(timeout);

                        if (done)
                        {
                            mess = task.Result;
                        }
                        else
                        {
                            mess = new Message(false, null, "Server to close timed out abort operation");
                        }
                    }

                    request++;
                }
                finally
                {
                    Monitor.Pulse(server);
                    Monitor.Exit(server);
                }
            }
            else
            {
                mess = new Message(false, null, "Duplicated request");
            }

            return(mess);
        }