private void OnSaveChangesButtonClick(object sender, RoutedEventArgs e)
        {
            if (AccessGroupViewListBox.SelectedItem == null)
            {
                return;
            }

            if (string.IsNullOrEmpty(AccessGroupNameTextBox.Text))
            {
                return;
            }

            var moduleAccess = AccessGroupAvailablesItemsControl.ItemsSource as DataView;

            if (moduleAccess == null)
            {
                return;
            }

            var accessGroupName = AccessGroupNameTextBox.Text;
            var accessGroupId   = Convert.ToInt32(AccessGroupViewListBox.SelectedValue);

            var groups =
                _admc.AccessGroupsTable.Select(string.Format("AccessGroupName = '{0}' AND AccessGroupID <> {1}",
                                                             accessGroupName, accessGroupId));

            if (groups.Length != 0)
            {
                MetroMessageBox.Show("Группа с таким названием уже существует!", "Предупреждение",
                                     MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            // Get all workers in access group
            var workers = (from structure in
                           _admc.AccessGroupStructureTable.AsEnumerable()
                           .Where(s => s.Field <Int64>("AccessGroupID") == accessGroupId)
                           select structure.Field <Int64>("WorkerID")).Distinct();

            // Get base available modules for access group
            var availableModules =
                _admc.AvailableModulesTable.AsEnumerable().Where(r => r.Field <Int64>("AccessGroupID") == accessGroupId);

            var workersList = workers as IList <long> ?? workers.ToList();

            if (availableModules.Any())
            {
                foreach (var row in availableModules.CopyToDataTable().AsEnumerable())
                {
                    var moduleId = Convert.ToInt32(row["ModuleID"]);

                    // Delete all non access modules
                    if (moduleAccess.Table.AsEnumerable()
                        .Any(r => !r.Field <bool>("Access") && r.Field <Int64>("ModuleID") == moduleId))
                    {
                        _admc.DeleteAvailableModule(accessGroupId, moduleId);

                        // Delete available for workers in access group
                        foreach (var worker in workersList)
                        {
                            _admc.DeleteWorkerAccess((int)worker, moduleId);
                        }
                    }
                    else
                    {
                        if (moduleAccess.Table.AsEnumerable().All(r => r.Field <Int64>("ModuleID") != moduleId))
                        {
                            continue;
                        }

                        var baseFullAccess = Convert.ToBoolean(row["FullAccess"]);
                        var fullAccess     =
                            moduleAccess.Table.AsEnumerable()
                            .First(r => r.Field <Int64>("ModuleID") == moduleId)
                            .Field <bool>("FullAccess");

                        // Set full access if old and new values are different
                        if (baseFullAccess != fullAccess)
                        {
                            _admc.SetModuleFullAccessForAccessGroup(accessGroupId, moduleId, fullAccess);
                            // Set full access for workers in access group
                            foreach (var worker in workersList)
                            {
                                _admc.SetFullAccessForWorker((int)worker, moduleId, fullAccess);
                            }
                        }
                    }
                }
            }

            // Add all new available modules
            foreach (var row in moduleAccess.Table.AsEnumerable()
                     .Where(r =>
                            r.Field <bool>("Access") &&
                            availableModules.AsEnumerable().All(a => a.Field <Int64>("ModuleID") != r.Field <Int64>("ModuleID"))))
            {
                var moduleId   = Convert.ToInt32(row["ModuleID"]);
                var fullAccess = Convert.ToBoolean(row["FullAccess"]);
                _admc.AddNewAvailableModule(accessGroupId, moduleId, fullAccess);

                // Add available for workers in access group
                foreach (var worker in workersList)
                {
                    _admc.AddWorkerAccess((int)worker, moduleId, fullAccess);
                }
            }

            _admc.RefillAvailableModules();
            _admc.RefillWorkerAccess();

            var checkSum = CalculateCheckSum();

            _admc.SetCheckSum(accessGroupId, checkSum);
            _admc.ChangeAccessGroupName(accessGroupId, accessGroupName);

            AdministrationClass.AddNewAction(102);
            OnCancelAddAccessGroupButtonClick(null, null);
        }