public override void AwakeFromNib ()
		{
			base.AwakeFromNib ();

			this.BtnClose.Activated += (object sender, EventArgs e) => {
				this.Close ();
				NSApplication.SharedApplication.StopModalWithCode (0);
			};
			this.BtnAdd.Activated += OnClickAddGroupButton;

			foreach(NSTableColumn column in GroupsTableView.TableColumns())
			{
				GroupsTableView.RemoveColumn (column);
			}
			GroupsTableView.Delegate = new TableDelegate ();
			var groupInfo = new GroupMembershipDto (){ Groups = new List<GroupDto> () };
			ActionHelper.Execute (delegate() {
				var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ServerDto.ServerName);
				groupInfo = SnapInContext.Instance.ServiceGateway.Tenant.Search (ServerDto, TenantName, DomainName, MemberType.GROUP, SearchType.NAME, auth.Token);
			});
				
			var listView = new GroupsDataSource { Entries = groupInfo.Groups };
			var columnNames = new List<ColumnOptions> {
				new ColumnOptions{ Id = "Name", DisplayName = "Group Name", DisplayOrder = 1, Width = 500 },
				};
			var columns = ListViewHelper.ToNSTableColumns (columnNames);
			foreach (var column in columns) {
				GroupsTableView.AddColumn (column);
			}
			GroupsTableView.DataSource = listView;
			GroupsTableView.ReloadData ();
		}
		void SetGroupDataSource (GroupMembershipDto members)
		{
			foreach(NSTableColumn column in GroupMembersTableView.TableColumns())
			{
				GroupMembersTableView.RemoveColumn (column);
			}
			var listView = new GroupMembershipDataSource {
				Groups = members.Groups,
				Users = members.Users,
				SolutionUsers = members.SolutionUsers
			};
			var columnNames = new List<ColumnOptions> {
				new ColumnOptions {
					Id = "Name",
					DisplayName = "Member",
					DisplayOrder = 1,
					Width = 180
				}
			};
			var columns = ListViewHelper.ToNSTableColumns (columnNames);
			foreach (var column in columns) {
				GroupMembersTableView.AddColumn (column);
			}
			GroupMembersTableView.DataSource = listView;
			GroupMembersTableView.ReloadData ();
		}
            public override void SelectionDidChange (NSNotification notification)
			{
				ActionHelper.Execute (delegate() {
					var row = (int)ob.splitViewController.MainTableView.SelectedRow;
					AppKit.NSViewController controller = null;
					if (row >= 0) {
						ActionHelper.Execute (delegate() {
							if (ob.CurrentSelectedNode is UsersNode) {
								var node = ob.CurrentSelectedNode as UsersNode;
								var tenant = node.GetTenant ();
								var user = ((UsersDataSource)ob.splitViewController.MainTableView.DataSource).Entries [row];
								var groups = new List<GroupDto>();
								try
								{
									var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ob._serverDto.ServerName);
									groups = SnapInContext.Instance.ServiceGateway.User.GetUserGroups (ob._serverDto, tenant, user, auth.Token);
									user.ActAsUsers = groups != null && groups.Exists (x => x.GroupName == "ActAsUsers" && x.GroupDomain == user.Domain);
									user.IsIdpAdmin = groups != null && groups.Exists (x => x.GroupName == "IdpProvisioningAdmin" && x.GroupDomain == user.Domain);
									var isAdmin = groups != null && groups.Exists (x => x.GroupName == "Administrators" && x.GroupDomain == user.Domain);
									var isUser = groups != null && groups.Exists (x => x.GroupName == "Users" && x.GroupDomain == user.Domain);
									user.Role = isAdmin ? UserRole.Administrator : isUser ? UserRole.RegularUser : UserRole.GuestUser;
								}
								catch(Exception exc)
								{
									user.ActAsUsers = false;
									user.IsIdpAdmin = false;
									user.Role = UserRole.GuestUser;
								}
								controller = new UserDetailsViewController () {
									UserDtoOriginal = user,
									GroupsOriginal = groups,
									ServerDto = ob._serverDto,
									TenantName = tenant,
									IsSystemDomain = node.IsSystemDomain
								};

							} else if (ob.CurrentSelectedNode is SolutionUsersNode) {
								var node = ob.CurrentSelectedNode as SolutionUsersNode;
								var tenant = node.GetTenant ();
								var user = ((SolutionUsersDataSource)ob.splitViewController.MainTableView.DataSource).Entries [row];
								controller = new SolutionUserDetailsViewController () {
									SolutionUserDtoOriginal = user,
									ServerDto = ob._serverDto,
									TenantName = tenant,
									IsSystemDomain = node.IsSystemDomain
								};
							} else if (ob.CurrentSelectedNode is GroupsNode) {
								var node = ob.CurrentSelectedNode as GroupsNode;
								var tenant = node.GetTenant ();
								var user = ((GroupsDataSource)ob.splitViewController.MainTableView.DataSource).Entries [row];
								var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ob._serverDto.ServerName);
								//var groupMembership = SnapInContext.Instance.ServiceGateway.Group.GetMembers (ob._serverDto, tenant, user, Vmware.Tools.RestSsoAdminSnapIn.Service.Group.GroupMemberType.ALL, auth.Token);
								var memberInfo = new GroupMembershipDto ();
								var userInfo = SnapInContext.Instance.ServiceGateway.Group.GetMembers (ob._serverDto, tenant, user, GroupMemberType.USER, auth.Token);
								memberInfo.Users = userInfo.Users == null ? new List<UserDto> () : new List<UserDto> (userInfo.Users);
								if (node.IsSystemDomain) {
									userInfo = SnapInContext.Instance.ServiceGateway.Group.GetMembers (ob._serverDto, tenant, user, GroupMemberType.SOLUTIONUSER, auth.Token);
									memberInfo.SolutionUsers = userInfo.SolutionUsers == null ? new List<SolutionUserDto> () : new List<SolutionUserDto> (userInfo.SolutionUsers);
								}
								userInfo = SnapInContext.Instance.ServiceGateway.Group.GetMembers (ob._serverDto, tenant, user, GroupMemberType.GROUP, auth.Token);
								memberInfo.Groups = userInfo.Groups == null ? new List<GroupDto> () : new List<GroupDto> (userInfo.Groups);

								controller = new GroupDetailsViewController () {
									GroupDtoOriginal = user,
									GroupsMembershipDtoOriginal = memberInfo,
									ServerDto = ob._serverDto,
									TenantName = tenant,
									IsSystemDomain = node.IsSystemDomain
								};
							} else if (ob.CurrentSelectedNode is TrustedCertificateNode) {
								var certificate = ((TrustedCertificatesDataSource)ob.splitViewController.MainTableView.DataSource).Entries [row];
								controller = new CertificateDetailsViewController () {
									CertificateDto = certificate
								};
							} else if (ob.CurrentSelectedNode is RelyingPartyNode) {
								var node = ob.CurrentSelectedNode as RelyingPartyNode;
								var tenant = node.GetTenant ();
								var rp = ((RelyingPartyDataSource)ob.splitViewController.MainTableView.DataSource).Entries [row];
								controller = new RelyingPartyDetailsViewController () { 
									RelyingPartyDtoOriginal = rp, 
									ServerDto = ob._serverDto,
									TenantName = tenant
								};
							} else if (ob.CurrentSelectedNode is OidcClientNode) {
								var node = ob.CurrentSelectedNode as OidcClientNode;
								var rp = ((OidcClientDataSource)ob.splitViewController.MainTableView.DataSource).Entries [row];
								var tenant = node.GetTenant ();
								controller = new OidcClientDetailsViewController () {
									OidcClientDtoOriginal = rp,
									ServerDto = ob._serverDto,
									TenantName = tenant
								};
							} else if (ob.CurrentSelectedNode is IdentityProvidersNode) {
								var node = ob.CurrentSelectedNode as IdentityProvidersNode;
								var rp = ((IdentityProvidersDataSource)ob.splitViewController.MainTableView.DataSource).Entries [row];
								var rpLatest = node.GetIdentityProvider (rp);
								controller = new ExtenalIdpDetailsViewController () {
									ExternalIdentityProviderDto = rpLatest
								};
							} else {
								controller = new DefaultViewController ();
							}
						});
						if (controller == null)
							controller = new DefaultViewController ();

						AppKit.NSView oldView = null;
						if (ob.DetailedCustomView.Subviews.Count () > 0) {
							oldView = ob.DetailedCustomView.Subviews [0];
						}
						if (oldView != null)
							ob.DetailedCustomView.ReplaceSubviewWith (oldView, controller.View);
						else
							ob.DetailedCustomView.AddSubview (controller.View);
					
					}
				});
			}
		private void UpdateGroupMembership(GroupMembershipDto left, GroupMembershipDto right)
		{
			if (left.Groups == null && right.Groups != null) {
				var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ServerDto.ServerName);
				SnapInContext.Instance.ServiceGateway.Group.AddGroups (ServerDto, TenantName, GroupDto, right.Groups, auth.Token);
			} else if (left.Groups != null && right.Groups != null) {
				var groups = new List<GroupDto> ();
				foreach (var group in left.Groups) {
					var fullName = group.GroupName + "@" + group.GroupDomain;
					if (right.Groups.FirstOrDefault (x => (x.GroupName + "@" + x.GroupDomain) == fullName) == null) {
						groups.Add (group);
					}
					if(groups.Count() > 0)
					{
						// remove
						var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ServerDto.ServerName);
						SnapInContext.Instance.ServiceGateway.Group.RemoveGroups (ServerDto, TenantName, GroupDto,groups, auth.Token);
					}
				}
				groups = new List<GroupDto> ();
				foreach (var group in right.Groups) {
					var fullName = group.GroupName + "@" + group.GroupDomain;
					if (left.Groups.FirstOrDefault (x => (x.GroupName + "@" + x.GroupDomain) == fullName) == null) {
						groups.Add (group);
					}

					if(groups.Count() > 0)
					{
						// remove
						var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ServerDto.ServerName);
						SnapInContext.Instance.ServiceGateway.Group.AddGroups (ServerDto, TenantName, GroupDto,groups, auth.Token);
					}
				}
			}

			if (left.Users == null && right.Users != null) {
				var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ServerDto.ServerName);
				SnapInContext.Instance.ServiceGateway.Group.AddUsers (ServerDto, TenantName, GroupDto, right.Users, auth.Token);
			} else if (left.Users != null && right.Users != null) {
				var users = new List<UserDto> ();
				foreach (var user in left.Users) {
					var fullName = user.Name + "@" + user.Domain;
					if (right.Users.FirstOrDefault (x => (x.Name + "@" + x.Domain) == fullName) == null) {
						users.Add (user);
					}
					if(users.Count() > 0)
					{
						// remove
						var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ServerDto.ServerName);
						SnapInContext.Instance.ServiceGateway.Group.RemoveUsers (ServerDto, TenantName, GroupDto,users, auth.Token);
					}
				}
				users = new List<UserDto> ();
				foreach (var user in right.Users) {
					var fullName = user.Name + "@" + user.Domain;
					if (left.Users.FirstOrDefault (x => (x.Name + "@" + x.Domain) == fullName) == null) {
						users.Add (user);
					}

					if(users.Count() > 0)
					{
						// remove
						var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ServerDto.ServerName);
						SnapInContext.Instance.ServiceGateway.Group.AddUsers (ServerDto, TenantName, GroupDto,users, auth.Token);
					}
				}
			}

			if (left.SolutionUsers == null && right.SolutionUsers != null) {
				var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ServerDto.ServerName);
				SnapInContext.Instance.ServiceGateway.Group.AddSolutionUsers (ServerDto, TenantName, GroupDto, right.SolutionUsers, auth.Token);
			} else if (left.SolutionUsers != null && right.SolutionUsers != null) {
				var users = new List<SolutionUserDto> ();
				foreach (var user in left.SolutionUsers) {
					var fullName = user.Name + "@" + user.Domain;
					if (right.SolutionUsers.FirstOrDefault (x => (x.Name + "@" + x.Domain) == fullName) == null) {
						users.Add (user);
					}
					if(users.Count() > 0)
					{
						// remove
						var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ServerDto.ServerName);
						SnapInContext.Instance.ServiceGateway.Group.RemoveSolutionUsers (ServerDto, TenantName, GroupDto,users, auth.Token);
					}
				}
				users = new List<SolutionUserDto> ();
				foreach (var user in right.SolutionUsers) {
					var fullName = user.Name + "@" + user.Domain;
					if (left.SolutionUsers.FirstOrDefault (x => (x.Name + "@" + x.Domain) == fullName) == null) {
						users.Add (user);
					}

					if(users.Count() > 0)
					{
						// remove
						var auth = SnapInContext.Instance.AuthTokenManager.GetAuthToken (ServerDto.ServerName);
						SnapInContext.Instance.ServiceGateway.Group.AddSolutionUsers (ServerDto, TenantName, GroupDto,users, auth.Token);
					}
				}
			}
		}
		public override void AwakeFromNib ()
		{
			base.AwakeFromNib ();
			GroupDto = new GroupDto {
				GroupName = GroupDtoOriginal.GroupName,
				GroupDomain = GroupDtoOriginal.GroupDomain,
				GroupDetails = new GroupDetailsDto { Description = GroupDtoOriginal.GroupDetails.Description }
			};
			TxtGroupName.StringValue = GroupDto.GroupName == null ? string.Empty : GroupDto.GroupName;
			TxtGroupDescription.StringValue = GroupDto.GroupDetails.Description == null ? string.Empty : GroupDto.GroupDetails.Description;
			GroupMembersTableView.Delegate = new TableDelegate ();
			GroupMembershipDto = new GroupMembershipDto {
				Users = (GroupsMembershipDtoOriginal.Users == null ? new List<UserDto> () : new List<UserDto> (GroupsMembershipDtoOriginal.Users)),
				SolutionUsers = (GroupsMembershipDtoOriginal.SolutionUsers == null ? new List<SolutionUserDto> () : new List<SolutionUserDto> (GroupsMembershipDtoOriginal.SolutionUsers)),
				Groups = (GroupsMembershipDtoOriginal.Groups == null ? new List<GroupDto> () : new List<GroupDto> (GroupsMembershipDtoOriginal.Groups))
			};
			SetGroupDataSource (GroupMembershipDto);

			BtnSave.Hidden = !IsSystemDomain;

			this.BtnSave.Activated += OnClickSaveButton;
			this.BtnAddMember.Activated += OnClickAddMember;
			this.BtnRemoveMember.Activated += OnClickRemoveMember;
			BtnAddMember.Enabled = IsSystemDomain;
			BtnRemoveMember.Enabled = IsSystemDomain;
		}