/// <summary>
        /// method adds new user to local database
        /// </summary>
        /// <param name="name">name of new user</param>
        /// <param name="token">token of new user</param>
        public void saveUserToLocalDatabase(String name, String token)
        {
            List<User> users;

            lock (LocalDBContext.Lock)
            {
                using (LocalDBContext context = new LocalDBContext())
                {
                    users = context.user.ToList();
                    User user = new User();

                    if (users.Count > 0)
                    {
                        user = users.First();
                        user.username = name;
                        user.token = token;
                        context.SaveChanges();
                    }
                    else
                    {
                        user.id = 1;
                        user.username = name;
                        user.token = token;
                        context.user.Add(user);
                        context.SaveChanges();
                    }

                    ChangeService.userToken = user.token;
                }
            }
        }
        /// <summary>
        /// method shows window that informs user about current situation of his synchronization process
        /// </summary>
        /// <param name="repository">EA repository</param>
        public void showCorrectWindow(EA.Repository repository)
        {
            User user = getLoggedUser();
            if (user == null)
            {
                MessageBox.Show("First you must log in and join your colleague to team.");
                return;
            }
            using (WebClient webClient = new WebClient())
            {
                this.user = user;
                string result = "", result2 = "", result3 = "";
                ModelInformation synchronizationData = new ModelInformation();
                synchronizationData.token = user.token;
                EA.Package package = (EA.Package)repository.GetPackageByID(1);
                synchronizationData.modelGUID = package.PackageGUID;
                string data = user.token;

                try
                {
                    webClient.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
                    data = EncodeNonAsciiCharacters(synchronizationData.serialize());
                    result = webClient.UploadString(Utils.serviceAddress + "/synchronization", data);
                    BPAddIn.syncProgressWindow = new SynchronizationProgressWindow(repository);
                    BPAddIn.syncProgressWindow.ShowDialog();
                }
                catch (WebException e)
                {
                    var response = e.Response as HttpWebResponse;
                    int code = (int)response.StatusCode;
                    if (code == 401)
                    {
                        MessageBox.Show("Please, log in once again.");
                    }
                    else if (code == 400)
                    {
                        MessageBox.Show("Currently, you are not a member of any team. First, join your colleague to team.");
                    }
                    else if (code == 405)
                    {
                        MessageBox.Show("Synchronization of this model in your team is not allowed.");
                    }
                    else if (code == 403)
                    {
                        MessageBox.Show("Your colleague in team has not sent data about model yet.");
                    }
                    else if (code == 404)
                    {
                        DialogResult resultWindow = MessageBox.Show("Do you want to synchronise currently opened model? Change of synchronized model in team project is not possible.", "Choice of model for synchronization", MessageBoxButtons.YesNo);
                        if (resultWindow == DialogResult.Yes)
                        {
                            SendingDataWindow sendingDataWindow = new SendingDataWindow(repository);
                            sendingDataWindow.ShowDialog();
                        }
                    }
                    else if (code == 406)
                    {
                        MessageBox.Show("Your colleague has not joined your team yet.");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Unexpected error has occured.");
                }
            }
        }
        /// <summary>
        /// method sends all data about model
        /// </summary>
        /// <param name="sendingDataWindow">window for data sending</param>
        /// <param name="repository">EA repository</param>
        public void sendDataAboutModel(SendingDataWindow sendingDataWindow, EA.Repository repository)
        {
            try
            {
                using (WebClient webClient = new WebClient())
                {
                    using (var stream = webClient.OpenRead(Utils.serviceAddress))
                    {
                        stream.Close();
                        this.sendingDataWindow = sendingDataWindow;
                        ChangeService.newEvent.Set();
                        changeModelGUID(repository);
                        modelTraverse.sendDataAboutModel(repository);

                        ScenarioChange propertyChange = new ScenarioChange();
                        propertyChange.modelGUID = repository.GetPackageByID(1).PackageGUID;
                        propertyChange.elementType = 777;
                        modelTraverse.saveCreate(propertyChange, repository);

                        user = getLoggedUser();
                        modelInformation = new ModelInformation();
                        modelInformation.modelGUID = repository.GetPackageByID(1).PackageGUID;
                        modelInformation.token = user.token;

                        timer = new System.Timers.Timer();
                        timer.Elapsed += new System.Timers.ElapsedEventHandler(checkLastCreate);
                        timer.Interval = 5000;
                        timer.Start();
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Server is unavailable. Check your internet connection.");
            }
        }
        /// <summary>
        /// method gets currently logged user
        /// </summary>
        /// <returns>instance of logged user</returns>
        public User getLoggedUser()
        {
            List<User> users;

            lock (LocalDBContext.Lock)
            {
                using (LocalDBContext context = new LocalDBContext())
                {
                    users = context.user.ToList();
                    User user = null;

                    if (users.Count > 0)
                    {
                        user = users.First();
                        return user;
                    }
                    else
                    {
                        return null;
                    }
                }
            }
        }
        /// <summary>
        /// method executes synchronization process
        /// </summary>
        /// <param name="repository">EA repository</param>
        public void executeSynchronization(EA.Repository repository)
        {
            User user = getLoggedUser();
            using (WebClient webClient = new WebClient())
            {
                this.user = user;
                string result = "", result2 = "", result3 = "";
                ModelInformation synchronizationData = new ModelInformation();
                synchronizationData.token = user.token;
                EA.Package package = (EA.Package)repository.GetPackageByID(1);
                synchronizationData.modelGUID = package.PackageGUID;
                string data = user.token;

                BPAddIn.changesAllowed = false;
                webClient.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
                result = webClient.UploadString(Utils.serviceAddress + "/synchronization/getNumber", user.token);
                int number = Convert.ToInt32(result);
                if (BPAddIn.synchronizationWindow == null)
                {
                    BPAddIn.synchronizationWindow = repository.AddWindow("Synchronization", "BPAddIn.SynchronizationPackage.SynchronizationWindow") as SynchronizationWindow;
                }
                repository.ShowAddinWindow("Synchronization");
                BPAddIn.synchronizationWindow.removeList();

                DateTime localDate = DateTime.Now;
                var culture = new CultureInfo("de-DE");
                BPAddIn.synchronizationWindow.addToList(localDate.ToString(culture));

                if (number == 0)
                {
                    BPAddIn.synchronizationWindow.addToList("No modifications.");
                    BPAddIn.changesAllowed = true;
                    return;
                }

                while (true)
                {
                    try
                    {
                        data = user.token;
                        webClient.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
                        result2 = webClient.UploadString(Utils.serviceAddress + "/synchronization/changes", data);

                        ModelChange modelChange = JsonConvert.DeserializeObject<ModelChange>(result2, new JsonItemConverter());
                        if (modelChange == null)
                        {
                            data = user.token;
                            continue;
                        }
                        if (modelChange is PropertyChange)
                        {
                            PropertyChange propertyChange = (PropertyChange)modelChange;
                            if (propertyChange.timestamp == "-1")
                            {
                                repository.ShowAddinWindow("Synchronization");
                                repository.RefreshModelView(1);
                                break;
                            }
                        }

                        if (modelChange is ItemCreation)
                        {
                            ItemCreation itemCreation = (ItemCreation)modelChange;                                  //addition

                            NewCorrespondenceNode newCorrNode = new NewCorrespondenceNode();
                            newCorrNode.firstUsername = user.username;
                            newCorrNode.firstItemGUID = synchronization.handleSynchronizationAdditions(itemCreation, repository);
                            newCorrNode.secondUsername = itemCreation.userName;
                            newCorrNode.secondItemGUID = itemCreation.itemGUID;

                            data = EncodeNonAsciiCharacters(newCorrNode.serialize());
                            webClient.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
                            result3 = webClient.UploadString(Utils.serviceAddress + "/corrModel/createNode", data);
                        }
                        else if (modelChange is PropertyChange)
                        {
                            PropertyChange propertyChange = (PropertyChange)modelChange;
                            if (propertyChange.elementDeleted == 0)
                            {
                                synchronization.handleSynchronizationChanges(propertyChange, repository);       //change
                            }
                            else
                            {
                                synchronization.handleSynchronizationDeletions(propertyChange, repository);             //deletion
                            }
                        }
                        else if (modelChange is StepChange)                    //scenarios
                        {
                            StepChange scenarioChange = (StepChange)modelChange;

                            if (scenarioChange.status == 1)                            //addition
                            {
                                NewCorrespondenceNode newCorrNode = new NewCorrespondenceNode();
                                newCorrNode.firstUsername = user.username;
                                newCorrNode.firstItemGUID = synchronization.handleScenarioAddition(scenarioChange, repository);
                                newCorrNode.secondUsername = scenarioChange.userName;
                                newCorrNode.secondItemGUID = scenarioChange.scenarioGUID;
                                data = EncodeNonAsciiCharacters(newCorrNode.serialize());
                                webClient.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
                                result3 = webClient.UploadString(Utils.serviceAddress + "/corrModel/createNode", data);
                            }
                            else if (scenarioChange.status == 2 || scenarioChange.status == 0)         //change or deletion
                            {
                                synchronization.handleScenarioChange(scenarioChange, repository);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        continue;
                    }
                }
            }
        }