7095663 A GUI needed for User Management s11u1_15
authorStephen Talley <stephen.talley@oracle.com>
Fri, 27 Apr 2012 00:52:26 -0400
changeset 847 a8e124b894b8
parent 846 0a2af4721353
child 848 d7c7737126e9
7095663 A GUI needed for User Management 7158462 modify RAD usermgr module to support user/role cmds functionality
usr/src/apis/usermgr.xml
usr/src/cmd/rad/mod/usermgr/Makefile
usr/src/cmd/rad/mod/usermgr/mod_usermgr.c
usr/src/java/vpanels/app/usermgr/build.xml
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/ActionString.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AddUserAction.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AdvancedSettings.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AdvancedSettingsDialog.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Arranger.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AttrObj.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrCompare.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrMgmt.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrModelEntry.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrObj.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthsPanel.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthsSettings.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Compare.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Constraints.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DblTreeNode.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DeleteUserAction.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTrees.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTreesConstraints.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTreesLayout.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/ExtAttrObj.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/FilterUserAction.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/GroupsPanel.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/GroupsSettings.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/HintTextPropertySynchronizer.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/MainControl.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/QuickVector.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RightsPanel.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RightsSettings.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RolesPanel.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RolesSettings.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/SelPanel.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Sort.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/TableMap.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/TableSorter.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserManagedObject.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrAdvancedControl.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrAdvancedPanel.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicControl.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicPanel.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrControl.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrEmptyPanel.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrPanelDescriptor.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrUtils.java
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/DOCS
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/DOCS.TAB
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/OFFSETS
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/POSITIONS
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/SCHEMA
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/TMAP
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/app.hs
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/docinfo.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/index.xml
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/map.jhm
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/target.xml
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/toc.xml
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/umolh.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admauths.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admgrp.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admrights.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-advtab.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-assumerole.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-chgcred.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-createuser.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-deluser.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-mainpanel.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-moduser.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-namesvcscope.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usrmgr-admrole.html
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/add.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/add_all.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-16.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-22.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-24.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-32.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-16.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-22.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-24.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-32.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/group-16.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/group-24.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/move_dn.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/move_up.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/remove.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/remove_all.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/rights-16.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/rights-24.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/role-24.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/roles-16.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/roles-24.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/user-24.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-16.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-24.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-32.png
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/warning.gif
usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/resources/Resources.properties
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-16.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-24.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-32.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-16.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-24.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-32.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-16.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-24.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-32.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-16.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-24.png
usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-32.png
usr/src/pkg/manifests/system-management-rad-module-rad-usermgr.p5m
usr/src/pkg/manifests/system-management-visual-panels-panel-usermgr.p5m
usr/src/pkg/manifests_dev/system-management-visual-panels-panel-usermgr.p5m
--- a/usr/src/apis/usermgr.xml	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/apis/usermgr.xml	Fri Apr 27 00:52:26 2012 -0400
@@ -23,26 +23,204 @@
 -->
 
 <interface xmlns="http://xmlns.oracle.com/radadr" 
-  name="com.oracle.solaris.vp.panels.usermgr">
+  name="com.oracle.solaris.rad.usermgr">
 
 	<struct name="Group">
-		<field type="string" name="groupName"/>
-		<field type="uinteger" name="groupID"/>
+		<summary>
+			describes a Solaris group
+		</summary>
+		<doc>
+			Fully describes a Solaris group, contains
+			group name, group id, group members.
+		</doc>
+		<field type="string" name="groupName">
+			<summary> Specifies the group name.</summary>
+		</field>
+		<field type="uinteger" name="groupID">
+			<summary> Specifies the Gid of the group.</summary>
+		</field>
 		<field name="groupMembers">
+			<summary> Specifies the members of the group.</summary>
 			<list type="string"/>
 		</field>
 	</struct>
 
 	<struct name="User">
-		<field type="string" name="username" nullable="false"/>
-		<field type="uinteger" name="userID" />
-		<field type="uinteger" name="groupID" />
-		<field type="string" name="description" nullable="true"/>
-		<field type="string" name="homeDirectory" nullable="true"/>
-		<field type="string" name="defaultShell" nullable="true"/>
+		<summary>
+			describes a Solaris user
+		</summary>
+		<doc>
+			Fully describes a Solaris user, contains
+			account, home directory and security attributes
+			associated with a user. See man passwd(4),
+			shadow(4), userattr(4) for more info on fields.
+		</doc>
+		<field type="string" name="username" nullable="false">
+			<summary> username for the account. </summary>
+		</field>
+		<field type="uinteger" name="userID">
+			<summary> UID for the account. </summary>
+		</field>
+		<field type="uinteger" name="groupID">
+			<summary> GID for the account. </summary>
+		</field>
+		<field type="string" name="description" nullable="true">
+			<summary> gecos info for the account. </summary>
+		</field>
+		<field type="string" name="homeDirectory" nullable="true">
+			<summary> homedirectory location for the account. </summary>
+		</field>
+		<field type="string" name="defaultShell" nullable="true">
+			<summary> default shell for the account. </summary>
+		</field>
+		<field type="integer" name="inactive">
+			<summary> Number of inactivity days allowed for the account.
+			</summary>
+		</field>
+		<field type="integer" name="min">
+			<summary> Minimum number of days between password changes
+				 for the account.
+			</summary>
+		</field>
+		<field type="integer" name="max"> 
+			<summary> Maximum cemunber of days the password is valid for
+				 the account.
+			</summary>
+		</field>
+		<field type="integer" name="warn">
+			<summary> Number of days before password expires the user 
+				 is warned.
+			</summary>
+		</field>
+		<field type="string" name="expire" nullable="true">
+			<summary> The date after which login will not be allowed for
+				 the account. The date format is %y-%m-%d %H:%M:%S.
+			</summary>
+		</field>
+		<field type="string" name="lockAfterRetries" nullable="true">
+			<summary> Specifies whether the account is locked
+				 after failed logins execeeds the allowable
+				 limit.
+			</summary>
+		</field>
+		<field type="string" name="alwaysAuditFlags" nullable="true">
+			<summary> Specifies per-user always audit pre-selection 
+				flags.
+			</summary>
+		</field>
+		<field type="string" name="neverAuditFlags" nullable="true">
+			<summary> Specifies per-user never-audit
+				 pre-selection flags.
+			</summary>
+		</field>
+		<field type="string" name="type" nullable="true">
+			<summary> specifies whether account is role or user. </summary>
+		</field>
+		<field type="string" name="defaultProj" nullable="true">
+			<summary> specifies the default project for the account. </summary>
+		</field>
+		<field type="string" name="clearance" nullable="true">
+			<summary> Specifies the max label at which the user can
+				 operate.
+		 	</summary>
+		</field>
+		<field type="string" name="minLabel" nullable="true">
+			<summary> Specifies the min labelthat the user can login .</summary>
+		</field>
+		<field type="string" name="roleAuth" nullable="true">
+			<summary> Specifies whether the account user role or user
+				 password for role authentication.
+			</summary>
+		</field>
+		<field type="string" name="idleCmd" nullable="true">
+			<summary> Specifies when the desktop session for the user gets
+				locked.
+			 </summary>
+		</field>
+		<field type="string" name="idleTime" nullable="true">
+			<summary> Specifies the idle time before the idlecmd is 
+				 executed.
+			</summary>
+		</field>
+		<field type="string" name="accountStatus" nullable="true">
+			<summary> Specifies the status of the account.</summary>
+		</field>
+		<field name="roles" nullable="true">
+			<summary> Specifies the roles that have been assigned to the
+				 account.
+			</summary>
+			<list type="string"/>
+		</field>
+		<field name="profiles" nullable="true">
+			<summary> Specifies the profiles that have been assigned to the
+				 account.
+			</summary>
+			<list type="string"/>
+		</field>
+		<field name="auths" nullable="true">
+			<summary> Specifies the authorizations that have been assigned
+				 to the account.
+			</summary>
+			<list type="string"/>
+		</field>
+		<field name="defaultPriv" nullable="true">
+			<summary> Specifies the default set of privileges assigned to
+				 user at login.
+			</summary>
+			<list type="string"/>
+		</field>
+		<field name="limitPriv" nullable="true">
+			<summary> Specifies the maximum  set of privileges the user or
+				 process started by the user can obtain.
+			</summary>
+			<list type="string"/>
+		</field>
+		<field name="groups" nullable="true">
+			<summary> Specifies the supplemental groups that have been
+				 assigned to the account.
+			</summary>
+			<list type="string"/>
+		</field>
+	</struct>
+
+	<struct name="UserChangeFields">
+		<summary>
+			Keeps track of all the fields that have been
+			changed in the user object.
+		</summary>
+		<doc>
+			Keeps track of all the fields that have been
+			changed in the user object. For every field
+			that has been changed in the User object the
+			respective changeField will be set to true.
+		</doc>
+		<field type="boolean" name="gidChanged"/>
+		<field type="boolean" name="descChanged"/>
+		<field type="boolean" name="homedirChanged"/>
+		<field type="boolean" name="defShellChanged"/>
+		<field type="boolean" name="profilesChanged"/>
+		<field type="boolean" name="rolesChanged"/>
+		<field type="boolean" name="authsChanged"/>
+		<field type="boolean" name="limitPrivChanged"/>
+		<field type="boolean" name="groupsChanged"/>
+		<field type="boolean" name="lockAfterRetriesChanged"/>
+		<field type="boolean" name="alwaysAuditChanged"/>
+		<field type="boolean" name="neverAuditChanged"/>
+		<field type="boolean" name="typeChanged"/>
+		<field type="boolean" name="defaultProjChanged"/>
+		<field type="boolean" name="minLabelChanged"/>
+		<field type="boolean" name="roleAuthChanged"/>
+		<field type="boolean" name="idleCmdChanged"/>
+		<field type="boolean" name="idleTimeChanged"/>
+		<field type="boolean" name="expireChanged"/>
+		<field type="boolean" name="minChanged"/>
+		<field type="boolean" name="maxChanged"/>
+		<field type="boolean" name="warnChanged"/>
+		<field type="boolean" name="uidChanged"/>
 	</struct>
 
 	<enum name="UserMgrErrorType">
+		<summary>User Manager api error types</summary>
 		<value name="INVALIDDATA"/>
 		<value name="USEREXISTS"/>
 		<value name="PERMDENIED"/>
@@ -52,6 +230,12 @@
 		<value name="PASSERROR"/>
 	</enum>
 
+	<enum name="ScopeType">
+		<summary>Name service scope types</summary>
+		<value name="FILES"/>
+		<value name="LDAP"/>
+	</enum>
+
 	<struct name="UserMgrError">
 		<field typeref="UserMgrErrorType" name="errorCode"/>
 	</struct>
@@ -62,63 +246,488 @@
 	</enum>
 
 	<api name="UserMgr">
-		<version major="1" minor="0" stability="private"/>
+		<summary>
+			Set of operations that can be performed on
+			users and roles.
+		</summary>
+		<version major="0" minor="1" stability="private"/>
 
 		<property name="users" access="ro">
+			<summary>
+				Lists users.
+			</summary>
+			<doc>
+				Lists the users present in the selected
+				scope based on the filter options.
+			</doc>
 			<list typeref="User"/>
-			<error typeref="UserMgrError"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user after
+             				</item> 
+				    </list>
+				</doc>
+			</error>
 		</property>
 
 		<property name="groups" access="ro">
+			<summary>
+				Lists groups.
+			</summary>
+			<doc>
+				Lists the groups present in the selected
+				scope.
+			</doc>
 			<list typeref="Group"/>
-			<error typeref="UserMgrError"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read the groups database.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
 		</property>
 
 		<property name="shells" access="ro">
+			<summary>
+				Lists shells.
+			</summary>
+			<doc>
+				Lists the set of available shells
+				that can be set as default shell for users.
+			</doc>
 			<list type="string"/>
-			<error typeref="UserMgrError"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read the default shells.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
 		</property>
 
 		<property name="defaultUser" typeref="User" access="ro">
-			<error typeref="UserMgrError"/>
+			<summary>
+				Lists user defaults.
+			</summary>
+			<doc>
+				Lists the default values for groups, basedir,
+				project, shell, skel, inactive, expire,
+				auths, profiles, roles, limitPriv,
+				defaultPriv, lockAfterRetries used  for
+				creation of users and roles.
+			</doc>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read default user properties.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+		</property>
+
+		<property name="scopes" access="ro">
+			<summary>
+				Lists scopes.
+			</summary>
+			<doc>
+				Lists the set of name service repositories
+				that can be administered.
+			</doc>
+			<list type="string"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read the name services that can be managed.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+		</property>
+
+
+		<property name="roles" access="ro">
+			<summary>
+				Lists assigned roles.
+			</summary>
+			<doc>
+				Lists the roles assigned to a user.
+			</doc>
+			<list type="string"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user roles
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+		</property>
+
+		<property name="profiles" access="ro">
+			<summary>
+				Lists assigned profiles.
+			</summary>
+			<doc>
+				Lists the profiles assigned to a user.
+			</doc>
+			<list type="string"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user profiles.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+		</property>
+
+		<property name="auths" access="ro">
+			<summary>
+				Lists assigned authorizations.
+			</summary>
+			<doc>
+				Lists the authorizations assigned to a user.
+			</doc>
+			<list type="string"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user authorizations.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
 		</property>
 
+		<property name="defaultPrivs" access="ro">
+			<summary>
+				Lists default privileges.
+			</summary>
+			<doc>
+				Lists the default privileges assigned to a user.
+			</doc>
+			<list type="string"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user's default privileges.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+		</property>
+
+		<property name="limitPrivs" access="ro">
+			<summary>
+				Lists limit privileges.
+			</summary>
+			<doc>
+				Lists the limit privileges assigned to a user.
+			</doc>
+			<list type="string"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user's limit privileges.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+		</property>
+
+		<property name="supplGroups" access="ro">
+			<summary>
+				Lists supplemental groups.
+			</summary>
+			<doc>
+				Lists the supplemental groups that the user
+				is a member of.
+			</doc>
+			<list type="string"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user's supplemental groups.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+		</property>
+
+		<property name="auditClasses" access="ro">
+			<summary>
+				Lists Assigned Audit Classes.
+			</summary>
+			<doc>
+				Lists the audit classes that are assigned to 
+				the user.
+			</doc>
+			<list type="string"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user's assigned audit classes.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+		</property>
+
+		<property name="pamUserConfFiles" access="ro">
+			<summary>
+				Lists users PAM configuration files.
+			</summary>
+			<doc>
+				Lists the per-user PAM configuration files.
+			</doc>
+			<list type="string"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user specific PAM configuration files.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+		</property>
+
+		<method name="getUser">
+			<summary>
+				gets User information for a given username.
+			</summary>
+			<doc>
+				Gets the user information for a given username from 
+				the name service repository based on the filter
+				options.
+			</doc>
+			<result typeref="User"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+			<argument type="string" name="username">
+				<summary> Specifies the username for which the
+					account information is to be retrieved.
+				</summary>
+			</argument>	
+		</method>
+
 		<method name="addUser">
+			<summary>
+				Add user or role.
+			</summary>
+			<doc>
+				Adds a user or role to the selected name
+				service repository based on the filter
+				options. Applies the properties set in 
+				the user object as the account, password,
+				security attributes.
+				Sets INVALIDDATA error when arguments are not valid.
+				Sets PASSERROR error when password update fails.
+				Sets READERROR error when unable to read user after
+				successful addition of new user.
+				Sets USEREXISTS error user already exists with same
+				username.
+			</doc>
 			<result typeref="User"/>
-			<error typeref="UserMgrError"/>
-			<argument typeref="User" name="user"/>
-			<argument type="secret" name="password"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>INVALIDDATA</code>  - when arguments are not valid.
+             				</item> 
+					<item>
+					    <code>INVALIDDATA</code>  - when arguments are not valid.
+             				</item> 
+					<item>
+					    <code>READERROR</code>  - when unable to read user after adding new user.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+			<argument typeref="User" name="user">
+				<summary> user object which contains attributes of new
+					user account to be created.
+				</summary>
+			</argument>	
+			<argument type="secret" name="password">
+				<summary> password to be set for the new user account.
+				</summary>
+			</argument>
 		</method>
 
 		<method name="modifyUser">
+			<summary>
+				Modify user or role.
+			</summary>
+			<doc>
+				Modifies users or roles present in the selected
+				scope based on the filter options.
+				Applies the changed fields in the user object
+				to the user or role attributes.	
+				Sets INVALIDDATA error when arguments are not valid.
+				Sets PASSERROR error when password update fails.
+				Sets READERROR error when unable to read user after
+				successful modification of user.
+			</doc>
 			<result typeref="User"/>
-			<error typeref="UserMgrError"/>
-			<argument typeref="User" name="user"/>
-			<argument type="secret" name="password"
-			    nullable="true"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>INVALIDDATA</code>  - when arguments are not valid.
+             				</item> 
+					<item>
+					    <code>INVALIDDATA</code>  - when arguments are not valid.
+             				</item> 
+					<item>
+					    <code>READERROR</code>  - when unable to read user after adding new user.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+			<argument typeref="User" name="user">
+				<summary> user object which contains user attributes
+					to be modified.
+				</summary>
+			</argument>
+			<argument type="secret" name="password" nullable="true">
+				<summary> password to be set for the new user account.
+				</summary>
+			</argument>
+			<argument typeref="UserChangeFields" name="changeFields">
+				<summary> Indicates which fields have been modified
+					in the user object by the client.
+				</summary>
+			</argument>
 		</method>
 
 		<method name="deleteUser">
-			<error typeref="UserMgrError"/>
-			<argument type="string" name="username"/>
+			<summary>
+				Delete user.
+			</summary>
+			<doc>
+				Deletes user or role based on username 
+				present in the selected scope based on the
+				filter options.
+				Sets READERROR error on failure.
+			</doc>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when unable to read user
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+			<argument type="string" name="username">
+				<summary> username of account that needs to be deleted.					</summary>
+			</argument>
+		</method>
+
+		<method name="setScope">
+			<summary>
+				sets the name-service repository scope.
+			</summary>
+			<doc>
+				Sets the name-service repository scope.
+				All subsequent operations will use the specified				scope.
+			</doc>
+			<argument name="scope" typeref="ScopeType">
+				<summary> Specifies the name-service scope to
+					be used for managing users.
+				</summary>
+			</argument>
 		</method>
 
-		<method name="isAdministrator">
-			<result type="boolean"/>
-			<error typeref="UserMgrError"/>
-			<argument type="string" name="username"/>
+		<method name="setFilter">
+			<summary>
+				Sets the filter options.
+			</summary>
+			<doc>
+				Sets the filter options which are used for
+				all the subsequent operations. The options
+				are user or role and search string.
+			</doc>
+			<argument name="usertype" typeref="UserType">
+				<summary> Specifies if users or roles 
+					will be managed.
+				</summary>
+			</argument>
+			<argument name="searchstring" type="string">
+				<summary> Specifies the string to match
+					 against user or role names to be managed.
+				</summary>
+			</argument>
 		</method>
 
-		<method name="setAdministrator">
-			<error typeref="UserMgrError"/>
-			<argument type="string" name="username"/>
-			<argument type="boolean" name="admin"/>
+		<method name="isSystemLabeled">
+			<summary>Checks if System is Labeled.
+			</summary>
+			<doc>
+				Checks if the Trusted Extensions feature is
+				enabled on the system.
+				Returns true if successful and sets
+				Sets READERROR error on failure.
+			</doc>
+			<result type="boolean" />
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when checking if Trusted Extensions is enabled fails.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
 		</method>
 
 		<method name="getUserType">
+			<summary>Gets the user type.
+			</summary>
+			<doc>
+				Checks if the user is role or normal user.
+				Returns UserType set to role or normal user.
+				Sets READERROR error on failure.
+			</doc>
 			<result typeref="UserType"/>
-			<error typeref="UserMgrError"/>
-			<argument name="username" type="string"/>
+			<error typeref="UserMgrError">
+				<doc>
+			            <list>
+					<item>
+					    <code>READERROR</code>  - when checking if Trusted Extensions is enabled fails.
+             				</item> 
+				    </list>
+				</doc>
+			</error>
+			<argument name="username" type="string">
+				<summary> Specifies user name to check for user or role.
+				</summary>
+			</argument>
 		</method>
 	</api>
 </interface>
--- a/usr/src/cmd/rad/mod/usermgr/Makefile	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/cmd/rad/mod/usermgr/Makefile	Fri Apr 27 00:52:26 2012 -0400
@@ -20,12 +20,12 @@
 #
 
 #
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 
 include ../Makefile.env
 
-LDLIBS += -lpam
+LDLIBS += -lpam  $(PROTO_LIB)/liboamuser.a -lsldap -ltsnet -ltsol -lproject -lnsl
 
 MOD_APIS=usermgr
 MOD_OBJS=mod_usermgr.o
--- a/usr/src/cmd/rad/mod/usermgr/mod_usermgr.c	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/cmd/rad/mod/usermgr/mod_usermgr.c	Fri Apr 27 00:52:26 2012 -0400
@@ -40,13 +40,18 @@
 #include <assert.h>
 #include <pthread.h>
 #include <userdefs.h>
+#include <shadow.h>
 
 #include <rad/rad_modapi.h>
 #include "api_usermgr.h"
+#include "nssec.h"
 
 #define	USERADD "/usr/sbin/useradd"
 #define	USERMOD "/usr/sbin/usermod"
 #define	USERDEL "/usr/sbin/userdel"
+#define	ROLEADD "/usr/sbin/roleadd"
+#define	ROLEMOD "/usr/sbin/rolemod"
+#define	ROLEDEL "/usr/sbin/roledel"
 
 #define	PWD_FILE "/etc/passwd"
 #define	GRP_FILE "/etc/group"
@@ -72,38 +77,109 @@
 /* uid for nobody4 */
 #define	UID_NOBODY4 65534
 
+#define	DEF_ATTEMPTS 3
+#define	MAX_INT_LEN 11
+#define	GROUPS	"groups"
+#define	DFLT_PROJ_FLD	"defaultProj"
+#define	LIMIT_PRIV_FLD	"limitPriv"
+#define	DFLT_PRIV_FLD	"defaultPriv"
+#define	MIN_LABEL_FLD	"minLabel"
+#define	IDLE_CMD_FLD	"idleCmd"
+#define	IDLE_TIME_FLD	"idleTime"
+#define	LOCK_AFTER_RETRIES_FLD	"lockAfterRetries"
+#define	ALWAYS_AUDIT_FLAGS_FLD	"alwaysAuditFlags"
+#define	NEVER_AUDIT_FLAGS_FLD	"neverAuditFlags"
+#define	ROLE_AUTH_FLD		"roleAuth"
+
+#define	check_rep(x)	(x == NULL || (x->type != SEC_REP_FILES && \
+			    x-> type != SEC_REP_LDAP) || x->rops == NULL) \
+				? -1 : 0
+typedef struct ua_mod
+{
+	char *ua_key;
+	char *ua_fldname;
+} ua_mod_t;
+
+static ua_mod_t ua_mods[] = {
+	USERATTR_AUTHS_KW,	NULL,
+	USERATTR_PROFILES_KW,   NULL,
+	USERATTR_ROLES_KW,	NULL,
+	USERATTR_TYPE_KW,	NULL,
+	USERATTR_DEFAULTPROJ_KW, DFLT_PROJ_FLD,
+	USERATTR_LIMPRIV_KW,	LIMIT_PRIV_FLD,
+	USERATTR_DFLTPRIV_KW,	DFLT_PRIV_FLD,
+	USERATTR_CLEARANCE,	NULL,
+	USERATTR_MINLABEL,	MIN_LABEL_FLD,
+	USERATTR_LOCK_AFTER_RETRIES_KW,	LOCK_AFTER_RETRIES_FLD,
+	USERATTR_IDLECMD_KW,	IDLE_CMD_FLD,
+	USERATTR_IDLETIME_KW,	IDLE_TIME_FLD,
+	USERATTR_AUDIT_FLAGS_KW,	ALWAYS_AUDIT_FLAGS_FLD,
+	USERATTR_ROLE_AUTH_KW,		ROLE_AUTH_FLD,
+	GROUPS,
+};
+
+#define	ua_num_keys	(sizeof (ua_mods) / sizeof (ua_mod_t))
+
+static char *scope = NSS_REP_FILES;
+static char *type = USERATTR_TYPE_NORMAL_KW;
+static sec_repository_t *scope_rep = NULL;
 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
 
-/*ARGSUSED*/
 static int
 verify_conv(int num_msg, struct pam_message **msg,
     struct pam_response **response, void *ptr)
 {
 	char *passwd = ptr;
+	struct pam_message	*m;
+	struct pam_response	*r;
+	char	*temp;
+	int	k, i;
+
+	if (num_msg <= 0)
+		return (PAM_CONV_ERR);
 
 	/*
 	 * We assume the first (and only) request is to verify
 	 * the provided auth token.  This is necessary until
 	 * PAM_SILENT is fixed by 6758592.
 	 */
-	struct pam_response *r = malloc(sizeof (struct pam_response));
-	if (r == NULL)
+	*response = (struct pam_response *)calloc(num_msg,
+	    sizeof (struct pam_response));
+	if (*response == NULL)
 		return (PAM_BUF_ERR);
 
-	*response = r;
-	r->resp = strdup(passwd);
-	if (r->resp == NULL) {
+	k = num_msg;
+	m = *msg;
+	r = *response;
+
+	temp = strdup(passwd);
+	if (temp == NULL) {
+		rad_log(RL_DEBUG, "strdup of passwd failed.");
 		free(r);
 		return (PAM_BUF_ERR);
 	}
-
-	r->resp_retcode = 0;
+	while (k--) {
+		r->resp = strdup(passwd);
+		if (r->resp == NULL) {
+			/* free responses */
+			r = *response;
+			for (i = 0; i < num_msg; i++, r++) {
+				if (r->resp)
+					free(r->resp);
+			}
+			free(*response);
+			*response = NULL;
+			return (PAM_BUF_ERR);
+		}
+		m++; r++;
+	}
 	return (PAM_SUCCESS);
 }
 
 static int
 update_user_passwd(const char *user, const char *passwd)
 {
+	pam_repository_t auth_rep = {scope, NULL, 0};
 	pam_handle_t *pamh;
 	struct pam_conv pam_conv = { verify_conv, (void *)passwd };
 	int res;
@@ -111,49 +187,176 @@
 	res = pam_start("other", user, &pam_conv, &pamh);
 	if (res != PAM_SUCCESS) {
 		pamh = NULL;
-		rad_log(RL_WARN, "Failed to initialize PAM: %s\n",
+		rad_log(RL_ERROR, "Failed to initialize PAM: %s",
 		    pam_strerror(pamh, res));
 		return (res == PAM_PERM_DENIED ? PAM_EPERM : PAM_ERROR);
 	}
 
+	if ((res = pam_set_item(pamh, PAM_REPOSITORY,
+	    (void *)&auth_rep)) != PAM_SUCCESS) {
+		rad_log(RL_ERROR, "Failed to set repository: %s",
+		    pam_strerror(pamh, res));
+		(void) pam_end(pamh, res);
+		return (res == PAM_PERM_DENIED ? PAM_EPERM : PAM_ERROR);
+	}
+
 	res = pam_chauthtok(pamh, PAM_SILENT|PAM_NO_AUTHTOK_CHECK);
 	if (res != PAM_SUCCESS) {
-		rad_log(RL_WARN, "Failed to change auth token: %s\n",
+		rad_log(RL_ERROR, "Failed to change auth token: %s",
 		    pam_strerror(pamh, res));
-		pam_end(pamh, res);
+		(void) pam_end(pamh, res);
 		return (res == PAM_PERM_DENIED ? PAM_EPERM : PAM_ERROR);
 	}
+	(void) pam_end(pamh, res);
+	return (res);
+}
 
-	pam_end(pamh, PAM_SUCCESS);
+static char *list_to_string(data_t *list)
+{
+	int size, index;
+	int item_len = 0;
+	char *retstr = NULL;
+	size = array_size(list);
+	if (size == 0)
+		return (retstr);
+	for (index = 0; index < size; index++) {
+		const char *fld_str = data_to_string(array_get(list, index));
+		if (fld_str != NULL && fld_str[0] != '\0') {
+			item_len += strlen(fld_str) + 1;
+		}
+	}
+	if (item_len <= 0)
+		return (retstr);
+	retstr = malloc(item_len + 1);
+	if (retstr == NULL) {
+		rad_log(RL_ERROR, "Error allocating list items.");
+		return (retstr);
+	}
+	*retstr = '\0';
+	for (index = 0; index < size; index++) {
+		const char *fld_str = data_to_string(array_get(list, index));
+		if (fld_str != NULL && fld_str[0] != '\0') {
+			if (index == 0)
+				*retstr = '\0';
+			(void) strncat(retstr, fld_str, item_len);
+			if (index < (size - 1))
+				(void) strncat(retstr, ",", item_len);
+		}
+	}
+	return (retstr);
+}
 
-	return (0);
+static void add_kv_field(const char *argv[], int *argc, data_t **input,
+boolean_t new_user, char *kw, char *chgfield)
+{
+	data_t *field;
+	data_t *fieldChanged;
+	data_t *user = input[0];
+	field = struct_get(user, kw);
+	fieldChanged = (new_user ? NULL : struct_get(input[2], chgfield));
+	if ((fieldChanged != NULL && data_to_boolean(fieldChanged) == B_TRUE) ||
+	    field != NULL) {
+		int len;
+		char *qt_str;
+		if (strcmp(kw, GROUPS) == 0) {
+			qt_str = list_to_string(field);
+			if (qt_str != NULL &&
+			    qt_str[0] != '\0') {
+				argv[(*argc)++] = strdup("-G");
+				argv[(*argc)++] = qt_str;
+			} else if (!new_user) {
+				argv[(*argc)++] = strdup("-G");
+				argv[(*argc)++] = strdup("");
+			}
+		} else {
+			if (field != NULL) {
+				if (strcmp(kw, USERATTR_AUTHS_KW) == 0 ||
+				    strcmp(kw, USERATTR_ROLES_KW) == 0 ||
+				    strcmp(kw, USERATTR_PROFILES_KW) == 0) {
+					char *fld_str = list_to_string(field);
+					if (fld_str != NULL &&
+					    strlen(fld_str) > 0) {
+						argv[(*argc)++] = strdup("-K");
+						len = strlen(fld_str) +
+						    strlen(kw) + 2;
+						qt_str = malloc(len);
+						if (qt_str == NULL) {
+							rad_log(RL_ERROR,
+							    "Error allocating"
+							    " memory.");
+							return;
+						}
+						(void) snprintf(qt_str, len,
+						    "%s=%s", kw, fld_str);
+						argv[(*argc)++] = qt_str;
+					} else if (!new_user) {
+						len = strlen(kw) + 4;
+						argv[(*argc)++] = strdup("-K");
+						qt_str = malloc(len);
+						(void) snprintf(qt_str, len,
+						    "%s=%s", kw, "");
+						argv[(*argc)++] = qt_str;
+					}
+				}
+			} else if (!new_user) {
+				len = strlen(kw) + 4;
+				argv[(*argc)++] = strdup("-K");
+				qt_str = malloc(len);
+				(void) snprintf(qt_str, len, "%s=%s", kw, "");
+				argv[(*argc)++] = qt_str;
+			}
+		}
+	}
 }
 
 static int
 build_args_array(const char *argv[], int *argc, boolean_t new_user, char *uids,
-    char *gids, data_t **input)
+char *gids, data_t **input)
 {
 	data_t *user = input[0];
 	data_t *field;
+	data_t *fieldChanged;
 	int count = 0;
 
-	argv[count++] = new_user ? USERADD : USERMOD;
+	if (strcmp(type, USERATTR_TYPE_ROLE) == 0) {
+		argv[count++] = strdup(new_user ? ROLEADD : ROLEMOD);
+	} else {
+		argv[count++] = strdup(new_user ? USERADD : USERMOD);
+	}
+	argv[count++] = strdup("-S");
+	argv[count++] = strdup(scope);
+	fieldChanged = (new_user ? NULL : struct_get(input[2],
+	    "homedirChanged"));
+	field = struct_get(user, "homeDirectory");
 	if (new_user) {
-		field = struct_get(user, "homeDirectory");
-		if (field) {
-			argv[count++] = "-d";
-			argv[count++] = data_to_string(field);
+		if (field != NULL) {
+			argv[count++] = strdup("-d");
+			argv[count++] = strdup(data_to_string(field));
 		} else {
-			argv[count++] = "-b";
-			argv[count++] = BASE_DIR;
+			argv[count++] = strdup("-b");
+			argv[count++] = strdup(BASE_DIR);
 		}
-		argv[count++] = "-m";
+		argv[count++] = strdup("-m");
+	} else {
+		if ((fieldChanged != NULL &&
+		    data_to_boolean(fieldChanged) == B_TRUE &&
+		    field != NULL) || field != NULL) {
+			argv[count++] = strdup("-d");
+			argv[count++] = strdup(data_to_string(field));
+		}
 	}
 
+	fieldChanged = (new_user ? NULL : struct_get(input[2], "descChanged"));
 	field = struct_get(user, "description");
-	if (field) {
-		argv[count++] = "-c";
-		argv[count++] = data_to_string(field);
+	if ((fieldChanged != NULL && data_to_boolean(fieldChanged) == B_TRUE &&
+	    field != NULL) || field != NULL) {
+		argv[count++] = strdup("-c");
+		argv[count++] = strdup(data_to_string(field));
+		if (strchr(argv[count-1], ':')
+		    != NULL) {
+			rad_log(RL_ERROR, "Error in description field.");
+			return (-1);
+		}
 	}
 
 	/* set uid only if we are adding a user */
@@ -164,10 +367,10 @@
 
 			if ((uid > 99) && (uid <= MAXUID)) {
 				(void) snprintf(uids, GUID_MAX, "%d", uid);
-				argv[count++] = "-u";
-				argv[count++] = uids;
+				argv[count++] = strdup("-u");
+				argv[count++] = strdup(uids);
 			} else if (uid != 0) {
-				rad_log(RL_WARN, "invalid uid found %d", uid);
+				rad_log(RL_ERROR, "Invalid uid found %d", uid);
 				return (1);
 			}
 		}
@@ -175,21 +378,36 @@
 
 	/* append gid */
 	field = struct_get(user, "groupID");
-	if (field) {
+	fieldChanged = (new_user ? NULL : struct_get(input[2], "gidChanged"));
+	if ((fieldChanged != NULL && data_to_boolean(fieldChanged) == B_TRUE &&
+	    field != NULL) || field != NULL) {
 		gid_t gid = data_to_uinteger(field);
 
 		if (gid > 0) {
 			(void) snprintf(gids, GUID_MAX, "%d", gid);
-			argv[count++] = "-g";
-			argv[count++] = gids;
+			argv[count++] = strdup("-g");
+			argv[count++] = strdup(gids);
 		}
 	}
 
 	field = struct_get(user, "defaultShell");
-	if (field) {
-		argv[count++] = "-s";
-		argv[count++] = data_to_string(field);
+	fieldChanged = (new_user ? NULL : struct_get(input[2],
+	    "defShellChanged"));
+	if ((fieldChanged != NULL && data_to_boolean(fieldChanged) == B_TRUE &&
+	    field != NULL) || field != NULL) {
+		argv[count++] = strdup("-s");
+		argv[count++] = strdup(data_to_string(field));
 	}
+	add_kv_field(argv, &count, input, new_user,
+	    USERATTR_PROFILES_KW, "profilesChanged");
+	if (strcmp(type, USERATTR_TYPE_ROLE)) {
+		add_kv_field(argv, &count, input, new_user,
+		    USERATTR_ROLES_KW, "rolesChanged");
+	}
+	add_kv_field(argv, &count, input, new_user,
+	    USERATTR_AUTHS_KW, "authsChanged");
+	add_kv_field(argv, &count, input, new_user,
+	    GROUPS, "groupsChanged");
 
 	argv[count] = NULL;
 	*argc = count;
@@ -201,9 +419,22 @@
 static data_t *
 make_user(const struct passwd *pwe)
 {
+	if (pwe == NULL) {
+		rad_log(RL_ERROR, "Invalid passwd struct");
+		return (NULL);
+	}
 	data_t *user = data_new_struct(&t__User);
+	if (user == NULL) {
+		rad_log(RL_ERROR, "User object is null.");
+		return (NULL);
+	}
 
 	data_t *username = data_new_string(pwe->pw_name, lt_copy);
+	if (username == NULL) {
+	rad_log(RL_ERROR, "Username is null.");
+		return (NULL);
+	}
+
 	data_t *user_id = data_new_uinteger(pwe->pw_uid);
 	data_t *group_id = data_new_uinteger(pwe->pw_gid);
 	data_t *desc = data_new_string(
@@ -211,34 +442,245 @@
 
 	data_t *home_dir = data_new_string(pwe->pw_dir, lt_copy);
 	data_t *shell = data_new_string(pwe->pw_shell, lt_copy);
+	data_t *inactive = data_new_integer(-1);
+	data_t *min = data_new_integer(-1);
+	data_t *max = data_new_integer(-1);
+	data_t *warn = data_new_integer(-1);
+	data_t *accountStatus = data_new_string("UNKNOWN", lt_const);
 
-	if ((user == NULL) || (username == NULL) || (user_id == NULL) ||
-	    (group_id == NULL) || (desc == NULL) || (home_dir == NULL) ||
-	    (shell == NULL)) {
-		data_free(user);
-		data_free(username);
-		data_free(user_id);
-		data_free(group_id);
-		data_free(desc);
-		data_free(home_dir);
-		data_free(shell);
-		return (NULL);
+	struct_set(user, "username", username);
+	struct_set(user, "userID", user_id);
+	struct_set(user, "groupID", group_id);
+	struct_set(user, "description", desc);
+	struct_set(user, "homeDirectory", home_dir);
+	struct_set(user, "defaultShell", shell);
+	struct_set(user, "inactive", inactive);
+	struct_set(user, "min", min);
+	struct_set(user, "max", max);
+	struct_set(user, "warn", warn);
+	struct_set(user, "accountStatus", accountStatus);
+
+	return (data_purify_deep(user));
+}
+
+static data_t *
+make_attrs_array(const nss_attr_t *attrs_lst)
+{
+	data_t *attr_arr = NULL;
+	data_t *attr;
+	int i;
+
+	if (attrs_lst != NULL && attrs_lst->attr_cnt > 0) {
+		attr_arr = data_new_array(&t_array_string,
+		    attrs_lst->attr_cnt);
+		if (attr_arr == NULL) {
+			rad_log(RL_ERROR,
+			    "Error allocating attr array");
+			return (NULL);
+		}
+		for (i = 0; i < attrs_lst->attr_cnt; i++) {
+			attr = data_new_string(attrs_lst->attrvals[i],
+			    lt_copy);
+			if (attr == NULL) {
+				rad_log(RL_ERROR,
+				    "Error allocating attr");
+				data_free(attr_arr);
+				return (NULL);
+			}
+			(void) array_add(attr_arr, attr);
+		}
 	} else {
-		struct_set(user, "username", username);
-		struct_set(user, "userID", user_id);
-		struct_set(user, "groupID", group_id);
-		struct_set(user, "description", desc);
-		struct_set(user, "homeDirectory", home_dir);
-		struct_set(user, "defaultShell", shell);
+		attr_arr = data_new_array(&t_array_string, 1);
+		if (attr_arr == NULL) {
+			rad_log(RL_ERROR,
+			    "Error allocating attr array");
+			return (NULL);
+		}
+		attr = data_new_string("", lt_copy);
+		if (attr == NULL) {
+			rad_log(RL_ERROR,
+			    "Error allocating attr");
+			data_free(attr_arr);
+			return (NULL);
+		}
+		(void) array_add(attr_arr, attr);
 	}
+
+	return (attr_arr);
+}
+
+
+static data_t *
+load_userattr(userattr_t *ua, data_t *user)
+{
+	char *attrs_lst;
+	data_t *attr, *attrs_arr;
+	int i, rc = 0;
+
+	for (i = 0; i < ua_num_keys; i++) {
+		if (strcmp(ua_mods[i].ua_key, GROUPS) == 0) {
+			rc = _nss_get_userattrs(ua->name, ua_mods[i].ua_key,
+			    scope_rep, &attrs_lst);
+		} else {
+			char *kv_attr;
+			attrs_lst = NULL;
+			if ((kv_attr = kva_match(ua->attr,
+			    (char *)ua_mods[i].ua_key)) != NULL) {
+				attrs_lst = strdup(kv_attr);
+				rc = 0;
+			}
+		}
+		if (rc == 0) {
+			if (attrs_lst != NULL) {
+				char *fldname;
+				if (strcmp(ua_mods[i].ua_key,
+				    USERATTR_AUTHS_KW) == 0 ||
+				    strcmp(ua_mods[i].ua_key,
+				    USERATTR_PROFILES_KW) == 0 ||
+				    strcmp(ua_mods[i].ua_key,
+				    USERATTR_ROLES_KW) == 0 ||
+				    strcmp(ua_mods[i].ua_key,
+				    USERATTR_LIMPRIV_KW) == 0 ||
+				    strcmp(ua_mods[i].ua_key,
+				    USERATTR_DFLTPRIV_KW) == 0 ||
+				    strcmp(ua_mods[i].ua_key, GROUPS) == 0) {
+					char *vals;
+					char *token, *lasts;
+
+					vals = attrs_lst;
+					attrs_arr = data_new_array(
+					    &t_array_string, 1);
+					if (attrs_arr == NULL) {
+						rad_log(RL_ERROR,
+						    "Error allocating "
+						    "attr array");
+						return (NULL);
+					}
+					for (token = strtok_r(vals, ",",
+					    &lasts); token != NULL;
+					    token = strtok_r(NULL, ",",
+					    &lasts)) {
+						attr = data_new_string(token,
+						    lt_copy);
+						if (attr == NULL) {
+							rad_log(RL_ERROR,
+							    "Error allocating"
+							    " attr");
+							data_free(attrs_arr);
+							return (NULL);
+						} else {
+							(void) array_add(
+							    attrs_arr, attr);
+						}
+					}
+					fldname = (ua_mods[i].ua_fldname
+					    == NULL) ? ua_mods[i].ua_key :
+					    ua_mods[i].ua_fldname;
+					struct_set(user, fldname,
+					    attrs_arr);
+					free(attrs_lst);
+				} else {
+					attrs_arr = data_new_string(
+					    attrs_lst, lt_copy);
+					/*
+					 * Need to fix audit flags
+					 */
+					if (strcmp(ua_mods[i].ua_key,
+					    USERATTR_AUDIT_FLAGS_KW)
+					    == 0) {
+						struct_set(user,
+						    ALWAYS_AUDIT_FLAGS_FLD,
+						    attrs_arr);
+					} else {
+						fldname = (ua_mods[i].ua_fldname
+						    == NULL) ? ua_mods[i].ua_key
+						    : ua_mods[i].ua_fldname;
+						struct_set(user,
+						    fldname,
+						    attrs_arr);
+					}
+					free(attrs_lst);
+				}
+			}
+		}
+	}
+
 	return (user);
 }
 
+/* converts expire field in string format to date */
+static char *
+convtodate(int expire)
+{
+	time_t tminsec;
+	struct tm  ts;
+	char buf[80];
+
+	if (expire == -1)
+		return (NULL);
+	tminsec = expire * DAY;
+	ts = *localtime(&tminsec);
+	(void) strftime(buf, sizeof (buf), "%y-%m-%d %H:%M:%S", &ts);
+	return (strdup(buf));
+}
+
+static data_t *
+load_shadow(const struct spwd *sp, data_t *user)
+{
+	char *exp_val, *status;
+	if (sp == NULL || user == NULL) {
+		rad_log(RL_ERROR, "Invalid arg in update_shadowinfo.");
+		return (NULL);
+	}
+	if (sp->sp_expire == -1)
+		exp_val = "";
+	else
+		exp_val = convtodate(sp->sp_expire);
+	if (exp_val == NULL) {
+		rad_log(RL_ERROR, "Error gettting shadow expire.");
+		return (NULL);
+	}
+
+	data_t *expire = data_new_string(exp_val, lt_copy);
+	data_t *inactive = data_new_integer(sp->sp_inact);
+	data_t *min = data_new_integer(sp->sp_min);
+	data_t *max = data_new_integer(sp->sp_max);
+	data_t *warn = data_new_integer(sp->sp_warn);
+	data_t *accountStatus;
+
+	if (sp->sp_pwdp == NULL || *sp->sp_pwdp == '\0') {
+		status = "NOPASSWORD";
+	} else if (strncmp(sp->sp_pwdp, LOCKSTRING,
+	    sizeof (LOCKSTRING)-1) == 0) {
+		status = "LOCKED";
+	} else if (strncmp(sp->sp_pwdp, NOLOGINSTRING,
+	    sizeof (NOLOGINSTRING)-1) == 0) {
+		status = "NOLOGIN";
+	} else if (strncmp(sp->sp_pwdp, UNINITPW, sizeof (UNINITPW)-1) == 0) {
+		status = "NOTACTIVATED";
+	} else if ((strlen(sp->sp_pwdp) == 13 && sp->sp_pwdp[0] != '$') ||
+	    sp->sp_pwdp[0] == '$') {
+		status = "PASSWORD";
+	} else {
+		status = "UNKNOWN";
+	}
+	accountStatus = data_new_string(status, lt_const);
+
+	struct_set(user, "expire", expire);
+	struct_set(user, "inactive", inactive);
+	struct_set(user, "min", min);
+	struct_set(user, "max", max);
+	struct_set(user, "warn", warn);
+	struct_set(user, "accountStatus", accountStatus);
+	return (data_purify_deep(user));
+}
+
+
 static data_t *
 make_error(data_t *e) {
 	data_t *error = data_new_struct(&t__UserMgrError);
 	struct_set(error, "errorCode", e);
-	return (data_purify(error));
+	return (data_purify_deep(error));
 }
 
 static boolean_t
@@ -279,17 +721,33 @@
 {
 	int res = UT_NORMAL;
 
-	userattr_t *attr = getusernam(username);
-	if (attr) {
-		char *type = kva_match(attr->attr, USERATTR_TYPE_KW);
+	userattr_t *puattr = NULL;
+	nss_XbyY_buf_t *buf = NULL;
+
+	if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS)  {
+		rad_log(RL_ERROR,
+		    "Error getting handle to repository");
+		return (-1);
+	}
 
-		if ((type) &&
+	if (check_rep(scope_rep) != 0 || username == NULL)
+		return (-1);
+
+
+	init_nss_buffer(SEC_REP_DB_USERATTR, &buf);
+	if ((scope_rep->rops->get_usernam((char *)username,
+	    &puattr, buf)) == SEC_REP_SUCCESS) {
+		char *type = kva_match(puattr->attr, USERATTR_TYPE_KW);
+
+		if ((type != NULL) &&
 		    ((strcmp(type, USERATTR_TYPE_ADMIN_KW) == 0) ||
-		    (strcmp(type, USERATTR_TYPE_NONADMIN_KW) == 0))) {
+		    (strcmp(type, USERATTR_TYPE_ROLE) == 0))) {
 			res = UT_ROLE;
 		}
+		free(puattr);
 	}
-	enduserattr();
+	free_nss_buffer(&buf);
+	free_repository_handle(scope_rep);
 
 	return (res);
 }
@@ -298,7 +756,7 @@
 is_local_user(boolean_t *luser, const char *username) {
 	FILE *fp = fopen(PWD_FILE, "r");
 	if (fp == NULL) {
-		rad_log(RL_DEBUG, "unable to open %s", PWD_FILE);
+		rad_log(RL_ERROR, "unable to open %s", PWD_FILE);
 		return (1);
 	}
 
@@ -318,46 +776,28 @@
 static int
 is_last_admin(boolean_t *admin, const char *username)
 {
-	userattr_t *attr = getusernam(username);
-	if ((attr == NULL) ||
-	    !kva_vsearch(attr->attr, USERATTR_ROLES_KW, ROOT)) {
+	userattr_t *puattr = NULL;
+	nss_XbyY_buf_t *buf = NULL;
+	boolean_t last_admin = B_TRUE;
+	boolean_t local_user;
+	int r;
+
+	if (check_rep(scope_rep) != 0 || username == NULL)
+		return (-1);
+	init_nss_buffer(SEC_REP_DB_USERATTR, &buf);
+	(void) scope_rep->rops->get_usernam((char *)username, &puattr, buf);
+	if ((puattr == NULL) ||
+	    kva_vsearch(puattr->attr, USERATTR_ROLES_KW, ROOT) == NULL) {
 		*admin = B_FALSE;
-
-		free_userattr(attr);
-		enduserattr();
-
+		free_userattr(puattr);
+		free_nss_buffer(&buf);
 		return (0);
 	}
-
-	FILE *fp = fopen(USERATTR_FILENAME, "r");
-	if (fp == NULL) {
-		rad_log(RL_DEBUG, "unable to open %s", USERATTR_FILENAME);
+	r = is_local_user(&local_user, puattr->name);
+	if (r != 0)
 		return (1);
-	}
-
-	boolean_t last_admin = B_TRUE;
-	while (((attr = fgetuserattr(fp)) != NULL) && (last_admin)) {
-		if (strcmp(username, attr->name) != 0) {
-			if (kva_vsearch(attr->attr, USERATTR_ROLES_KW, ROOT)) {
-				/* verify that attr->name is a local user */
-				boolean_t local_user;
-				int r = is_local_user(&local_user, attr->name);
-				if (r != 0) {
-					free_userattr(attr);
-					enduserattr();
-					(void) fclose(fp);
-					return (1);
-				}
-				if (local_user)
-					last_admin = B_FALSE;
-			}
-		}
-	}
-
-	free_userattr(attr);
-	enduserattr();
-	(void) fclose(fp);
-
+	if (local_user)
+		last_admin = B_FALSE;
 	*admin = last_admin;
 	return (0);
 }
@@ -366,13 +806,74 @@
 get_user(const char *username)
 {
 	data_t *user;
-	struct passwd *entry = getpwnam(username);
-	if (entry) {
-		user = make_user(entry);
-		endpwent();
+	struct spwd *spwd = NULL;
+	userattr_t *uattr = NULL;
+	struct passwd *entry = NULL;
+	nss_XbyY_buf_t *buf = NULL;
+	int rc;
+
+	init_nss_buffer(SEC_REP_DB_PASSWD, &buf);
+	rc = scope_rep->rops->get_pwnam((char *)username,
+	    &entry, buf);
+	if (entry != NULL) {
+		if ((user = make_user(entry)) == NULL) {
+			rad_log(RL_ERROR,
+			    "Unable to create user obj.");
+			free(entry);
+			free_nss_buffer(&buf);
+			return (NULL);
+		}
+		free(entry);
+	} else {
+		rad_log(RL_DEBUG,
+		    "%s not found. rc = %d",
+		    username, rc);
+		free_nss_buffer(&buf);
+		return (NULL);
 	}
-
-	return (user);
+	free_nss_buffer(&buf);
+	init_nss_buffer(SEC_REP_DB_USERATTR, &buf);
+	rc = scope_rep->rops->get_usernam((char *)username, &uattr, buf);
+	if (uattr != NULL) {
+		rad_log(RL_DEBUG, "Loading userattr"
+		    " info for user %s", username);
+		char *uatype = kva_match(uattr->attr, USERATTR_TYPE_KW);
+		if ((type != NULL && uatype != NULL &&
+		    strcmp(uatype, type)) ||
+		    (type != NULL && uatype == NULL &&
+		    strcmp(type, USERATTR_TYPE_ROLE) == 0)) {
+			free(uattr);
+			free_nss_buffer(&buf);
+			return (NULL);
+		}
+		if ((user = load_userattr(uattr, user)) == NULL) {
+			rad_log(RL_ERROR, "Error loading userattr"
+			    " info for user %s", username);
+			free(uattr);
+			free_nss_buffer(&buf);
+			return (NULL);
+		}
+		free(uattr);
+	} else if (uattr == NULL &&
+	    strcmp(type, USERATTR_TYPE_ROLE) == 0) {
+		free_nss_buffer(&buf);
+		return (NULL);
+	}
+	free_nss_buffer(&buf);
+	init_nss_buffer(SEC_REP_DB_SHADOW, &buf);
+	rc = scope_rep->rops->get_spnam((char *)username, &spwd, buf);
+	if (spwd != NULL) {
+		if ((user = load_shadow(spwd, user)) == NULL) {
+			rad_log(RL_ERROR, "Error filling shadow info"
+			    "for user %s", username);
+			free(spwd);
+			free_nss_buffer(&buf);
+			return (NULL);
+		}
+		free(spwd);
+	}
+	free_nss_buffer(&buf);
+	return (data_purify_deep(user));
 }
 
 /*ARGSUSED*/
@@ -381,40 +882,55 @@
     data_t **rtnval, data_t **error)
 {
 	conerr_t rtn_code = ce_ok;
+	data_t *users;
+	nss_XbyY_buf_t *buf = NULL;
+	struct passwd *entry;
+	int count = 0;
 
-	data_t *users = data_new_array(&t_array__User, 100);
-	FILE *fp = fopen(PWD_FILE, "r");
-	if (fp) {
-		struct passwd *entry;
-		while ((entry = fgetpwent(fp)) != NULL) {
-			/*
-			 * prune system users including noaccess,
-			 * nobody, nobody4
-			 */
-			if ((entry->pw_uid > 99) &&
-			    (entry->pw_uid != UID_NOACCESS) &&
-			    (entry->pw_uid != UID_NOBODY) &&
-			    (entry->pw_uid != UID_NOBODY4)) {
+	rad_log(RL_DEBUG, "In readUsers. scope:%s, type=%s", scope, type);
+	if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS)  {
+		rad_log(RL_ERROR, "Error getting handle to repository");
+		return (-1);
+	}
+	if (check_rep(scope_rep) != 0) {
+		free_repository_handle(scope_rep);
+		*rtnval = NULL;
+		*error = make_error(&e__UserMgrErrorType_READERROR);
+		return (ce_object);
+	}
+	users = data_new_array(&t_array__User, 100);
+	init_nss_buffer(SEC_REP_DB_PASSWD, &buf);
+	scope_rep->rops->set_pwent();
+	while ((entry = scope_rep->rops->get_pwent(buf)) != NULL) {
+		/*
+		 * prune system users including noaccess,
+		 * nobody, nobody4
+		 */
+		if (((entry->pw_uid > 99) &&
+		    (entry->pw_uid != UID_NOACCESS) &&
+		    (entry->pw_uid != UID_NOBODY) &&
+		    (entry->pw_uid != UID_NOBODY4)) ||
+		    (entry->pw_uid == 0)) {
+			data_t *user = get_user(entry->pw_name);
+			if (user != NULL) {
+				(void) array_add(users, user);
+				count++;
+			} else {
+				rad_log(RL_DEBUG, "No users found");
+			}
 
-				data_t *user = make_user(entry);
-				if (user != NULL)
-					(void) array_add(users, user);
-			}
 		}
-
-		endpwent();
-		(void) fclose(fp);
 	}
-
-	if (data_verify(users, users->d_type, B_FALSE)) {
+	scope_rep->rops->end_pwent();
+	free_nss_buffer(&buf);
+	if (data_verify(users, users->d_type, B_TRUE) == B_TRUE) {
 		*rtnval = users;
 	} else {
 		data_free(users);
-		*rtnval = NULL;
 		*error = make_error(&e__UserMgrErrorType_READERROR);
 		rtn_code = ce_object;
 	}
-
+	free_repository_handle(scope_rep);
 	return (rtn_code);
 }
 
@@ -425,11 +941,19 @@
 {
 	conerr_t rtn_code = ce_ok;
 
+	rad_log(RL_DEBUG, "In readGroups. scope:%s", scope);
+	if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS)  {
+		rad_log(RL_ERROR, "Error getting handle to repository");
+		return (-1);
+	}
 	data_t *groups = data_new_array(&t_array__Group, 50);
 	FILE *fp = fopen(GRP_FILE, "r");
 	if (fp) {
 		struct group *entry;
-		while ((entry = fgetgrent(fp)) != NULL) {
+		nss_XbyY_buf_t *buf = NULL;
+		init_nss_buffer(SEC_REP_DB_GROUP, &buf);
+		scope_rep->rops->set_group();
+		while ((entry = scope_rep->rops->get_group(buf)) != NULL) {
 			data_t *group = data_new_struct(&t__Group);
 
 			struct_set(group, "groupName",
@@ -448,9 +972,8 @@
 			struct_set(group, "groupMembers", members);
 			(void) array_add(groups, group);
 		}
-
-		endgrent();
-		(void) fclose(fp);
+		scope_rep->rops->end_group();
+		free_nss_buffer(&buf);
 	}
 
 	if (data_verify(groups, groups->d_type, B_TRUE)) {
@@ -462,6 +985,7 @@
 
 		rtn_code = ce_object;
 	}
+	free_repository_handle(scope_rep);
 
 	return (rtn_code);
 }
@@ -514,28 +1038,36 @@
 	if (args[1] != NULL)
 		password = data_to_secret(args[1]);
 
+	rad_log(RL_DEBUG, "In addUser.scope : %s", scope);
+	if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS)  {
+		rad_log(RL_ERROR,
+		    "Error getting handle to repository");
+		*error = make_error(
+		    &e__UserMgrErrorType_READERROR);
+		return (ce_object);
+	}
 	const char *argv[ARG_COUNT];
 	char uids[GUID_MAX];
 	char gids[GUID_MAX];
 	int argc;
 
 	if (build_args_array(argv, &argc, B_TRUE, uids, gids, args) != 0) {
-		rad_log(RL_DEBUG, "invalid arguments found.");
+		rad_log(RL_DEBUG, "Invalid arguments found.");
 		*error = make_error(&e__UserMgrErrorType_INVALIDDATA);
 		return (ce_object);
 	}
 
-	argv[argc++] = username;
+	argv[argc++] = strdup(username);
 	argv[argc] = NULL;
 	assert(argc < ARG_COUNT);
 
 	int estatus;
 	int fstatus = rad_forkexec_wait(NULL, argv, &estatus);
+	if ((fstatus == 0) && (estatus == 0)) {
+		rad_log(RL_DEBUG,
+		    "%s created successfully", username);
 
-	if ((fstatus == 0) && (estatus == 0)) {
-		rad_log(RL_DEBUG, "%s created successfully.", username);
-
-		if (password) {
+		if (password != NULL && password[0] != '\0') {
 			int res = update_user_passwd(username, password);
 			if (res != 0) {
 				switch (res) {
@@ -543,28 +1075,48 @@
 					rtn_code = ce_priv;
 					break;
 				default:
+					rad_log(RL_ERROR,
+					    "Error from pam");
 					*error = make_error(
 					    &e__UserMgrErrorType_PASSERROR);
 					rtn_code = ce_object;
 				}
+				*rtnval = NULL;
+				return (rtn_code);
 			}
 		}
 
 		data_t *new_user;
+		free_repository_handle(scope_rep);
+		(void) sleep(2);
+		if (get_repository_handle(scope, &scope_rep)
+		    != SEC_REP_SUCCESS)  {
+			rad_log(RL_ERROR,
+			    "Error getting handle to"
+			    " repository");
+			*error = make_error(
+			    &e__UserMgrErrorType_READERROR);
+			return (ce_object);
+		}
 		if ((new_user = get_user(username)) != NULL) {
-			*rtnval = new_user;
+			if ((*rtnval = data_purify_deep(new_user)) == NULL) {
+				*error = make_error(
+				    &e__UserMgrErrorType_READERROR);
+				return (ce_object);
+			}
 			return (ce_ok);
 		} else {
-			rad_log(RL_DEBUG, "unable to read newly created user");
+			rad_log(RL_ERROR,
+			    "Unable to read newly created user");
 			*error = make_error(&e__UserMgrErrorType_PASSERROR);
 			return (ce_object);
 		}
 	} else if (fstatus != 0) {
-		rad_log(RL_DEBUG, "unable to fork child process");
+		rad_log(RL_ERROR, "Unable to fork child process");
 		*error = make_error(&e__UserMgrErrorType_READERROR);
 		rtn_code = ce_object;
 	} else {
-		rad_log(RL_WARN, "error creating user %s", username);
+		rad_log(RL_ERROR, "Error creating user %s", username);
 
 		switch (estatus) {
 		case EX_NO_PERM:
@@ -584,6 +1136,7 @@
 			rtn_code = ce_object;
 		}
 	}
+	free_repository_handle(scope_rep);
 
 	return (rtn_code);
 }
@@ -606,14 +1159,20 @@
 	char gids[GUID_MAX];
 	int argc;
 
+	rad_log(RL_DEBUG, "In modifyUser. scope:%s", scope);
+	if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS)  {
+		rad_log(RL_ERROR,
+		    "Error getting handle to repository");
+		return (-1);
+	}
 	if (build_args_array(argv, &argc, B_FALSE, uids, gids, args) != 0) {
-		rad_log(RL_WARN, "invalid arguments");
+		rad_log(RL_ERROR,
+		    "Invalid arguments");
 		*error = make_error(&e__UserMgrErrorType_INVALIDDATA);
 		return (ce_object);
 	}
-
 	if (argc > 2) {
-		argv[argc++] = username;
+		argv[argc++] = strdup(username);
 		argv[argc] = NULL;
 		assert(argc < ARG_COUNT);
 
@@ -622,20 +1181,32 @@
 
 		if ((fstatus == 0) && (estatus == 0)) {
 			data_t *modified_user;
+			free_repository_handle(scope_rep);
+			(void) sleep(2);
+			if (get_repository_handle(scope, &scope_rep)
+			    != SEC_REP_SUCCESS)  {
+				rad_log(RL_ERROR,
+				    "Error getting handle"
+				    " to repository");
+				return (-1);
+			}
 			if ((modified_user = get_user(username)) != NULL) {
 				*rtnval = modified_user;
 			} else {
-				rad_log(RL_DEBUG, "Cannot read modified user");
+				rad_log(RL_ERROR,
+				    "Cannot read modified user");
 				*error =
 				    make_error(&e__UserMgrErrorType_READERROR);
 				return (ce_object);
 			}
 		} else if (fstatus != 0) {
-			rad_log(RL_DEBUG, "unable to fork child process");
+			rad_log(RL_ERROR,
+			    "Unable to fork child process");
 			*error = make_error(&e__UserMgrErrorType_READERROR);
 			rtn_code = ce_object;
 		} else {
-			rad_log(RL_DEBUG, "error modifying user %s", username);
+			rad_log(RL_ERROR,
+			    "Error modifying user %s", username);
 			switch (estatus) {
 			case EX_NO_PERM:
 			case EX_NO_AUTH:
@@ -652,7 +1223,8 @@
 	if ((rtn_code == ce_ok) && password) {
 		int res = update_user_passwd(username, password);
 		if (res != 0) {
-			rad_log(RL_DEBUG, "unable to set user password");
+			rad_log(RL_ERROR,
+			    "Unable to set user password");
 			switch (res) {
 			case PAM_EPERM:
 				rtn_code = ce_priv;
@@ -671,6 +1243,7 @@
 	if (rtn_code != ce_ok)
 		data_free(*rtnval);
 
+	free_repository_handle(scope_rep);
 	return (rtn_code);
 }
 
@@ -682,9 +1255,20 @@
 	assert(args[0] != NULL);
 
 	const char *username = data_to_string(args[0]);
-	const char *argv[] = {USERDEL, "-r", username, NULL};
+	const char *argv[] = {USERDEL, "-S", scope, "-r", username, NULL};
+
+	if (strcmp(type, USERATTR_TYPE_ROLE) == 0) {
+		argv[0] = ROLEDEL;
+	}
 
 	boolean_t last_admin;
+	rad_log(RL_DEBUG, "In deleteUser. scope:%s", scope);
+	if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS)  {
+		rad_log(RL_ERROR,
+		    "Error getting handle to repository");
+		*error = make_error(&e__UserMgrErrorType_READERROR);
+		return (ce_object);
+	}
 	if (is_last_admin(&last_admin, username) != 0) {
 		*error = make_error(&e__UserMgrErrorType_READERROR);
 		return (ce_object);
@@ -692,7 +1276,8 @@
 
 	if ((get_user_type(ROOT) == UT_ROLE) && last_admin) {
 		*error = make_error(&e__UserMgrErrorType_LASTADMIN);
-		rad_log(RL_DEBUG, "cannot delete last local administrator.");
+		rad_log(RL_ERROR,
+		    "Cannot delete last local administrator");
 		return (ce_object);
 	}
 
@@ -700,16 +1285,18 @@
 	int fstatus = rad_forkexec_wait(NULL, argv, &estatus);
 
 	if ((fstatus == 0) && (estatus == 0)) {
-		rad_log(RL_DEBUG, "%s deleted successfully", username);
+		rad_log(RL_DEBUG,
+		    "%s deleted successfully", username);
 		return (ce_ok);
 	}
 
 	/* unable to delete home directory, try again without the -r option */
 	if (estatus == EX_HOMEDIR) {
-		rad_log(RL_WARN, "Unable to determine the status of home %s",
+		rad_log(RL_WARN,
+		    "Unable to determine the status of home %s",
 		    "directory, trying again.");
 
-		const char *argv[] = {USERDEL, username, NULL};
+		const char *argv[] = {USERDEL, "-S", scope, username, NULL};
 		fstatus = rad_forkexec_wait(NULL, argv, &estatus);
 
 		if ((fstatus == 0) && (estatus == 0)) {
@@ -721,7 +1308,7 @@
 	conerr_t rtn_code = ce_ok;
 
 	if (fstatus != 0) {
-		rad_log(RL_DEBUG, "unable to fork child process");
+		rad_log(RL_DEBUG, "Unable to fork child process");
 		*error = make_error(&e__UserMgrErrorType_READERROR);
 		rtn_code = ce_object;
 	} else {
@@ -739,11 +1326,23 @@
 	if (rtn_code == ce_priv)
 		data_free(*error);
 
+	free_repository_handle(scope_rep);
 	return (rtn_code);
 }
 
 /*ARGSUSED*/
 conerr_t
+api_UserMgr_invoke_getUser(rad_instance_t *inst, adr_method_t *meth,
+    data_t **rtnval, data_t **args, int count, data_t **error)
+{
+	/* will implement along with other fixes. */
+	*rtnval = NULL;
+	*error = make_error(&e__UserMgrErrorType_READERROR);
+	return (ce_object);
+}
+
+/*ARGSUSED*/
+conerr_t
 api_UserMgr_invoke_isAdministrator(rad_instance_t *inst, adr_method_t *meth,
     data_t **rtnval, data_t **args, int count, data_t **error)
 {
@@ -758,7 +1357,7 @@
 	enduserattr();
 
 	data_t *res = data_new_boolean(admin);
-	if (*rtnval = data_purify(res)) {
+	if ((*rtnval = data_purify_deep(res)) != NULL) {
 		return (ce_ok);
 	} else {
 		*error = make_error(&e__UserMgrErrorType_READERROR);
@@ -827,7 +1426,6 @@
 			rtn_code = ce_object;
 		}
 	}
-
 	return (rtn_code);
 }
 
@@ -839,7 +1437,7 @@
 	const char *username = data_to_string(args[0]);
 
 	data_t *type = data_new_enum(&t__UserType, get_user_type(username));
-	if (*rtnval = data_purify(type)) {
+	if ((*rtnval = data_purify_deep(type)) != NULL) {
 		return (ce_ok);
 	} else {
 		*error = make_error(&e__UserMgrErrorType_READERROR);
@@ -954,38 +1552,259 @@
 	data_t *group_id = data_new_uinteger(group);
 	data_t *default_shell = data_new_string(shell, lt_copy);
 	data_t *home_dir = data_new_string(basedir, lt_copy);
+	data_t *inactive = data_new_integer(-1);
+	data_t *min = data_new_integer(-1);
+	data_t *max = data_new_integer(-1);
+	data_t *warn = data_new_integer(-1);
+	data_t *accountStatus = data_new_string("UNKNOWN", lt_const);
 
-	if ((user == NULL) || (username == NULL) || (group_id == NULL) ||
-	    (default_shell == NULL) || (home_dir == NULL)) {
-		data_free(user);
-		data_free(username);
-		data_free(group_id);
-		data_free(default_shell);
-		data_free(home_dir);
+	struct_set(user, "username", username);
+	struct_set(user, "userID", data_new_uinteger(0));
+	struct_set(user, "groupID", group_id);
+	struct_set(user, "defaultShell", default_shell);
+	struct_set(user, "homeDirectory", home_dir);
+	struct_set(user, "inactive", inactive);
+	struct_set(user, "min", min);
+	struct_set(user, "max", max);
+	struct_set(user, "warn", warn);
+	struct_set(user, "accountStatus", accountStatus);
 
+	if ((*rtnval = data_purify_deep(user)) == NULL) {
 		*error = make_error(&e__UserMgrErrorType_READERROR);
 		return (ce_object);
-	} else {
-		struct_set(user, "username", username);
-		struct_set(user, "userID", data_new_uinteger(0));
-		struct_set(user, "groupID", group_id);
-		struct_set(user, "defaultShell", default_shell);
-		struct_set(user, "homeDirectory", home_dir);
-
-		if (!(*rtnval = data_purify(user))) {
-			*error = make_error(&e__UserMgrErrorType_READERROR);
-			return (ce_object);
-		}
 	}
 
 	return (ce_ok);
 }
 
+
+static void
+populate_list(nss_attr_t *list, const char *attr_name, conerr_t *rtn_code,
+data_t **rtnval, data_t **error)
+{
+	data_t *attrs_arr = NULL;
+	*rtn_code = ce_ok;
+
+	if (list != NULL) {
+		attrs_arr = make_attrs_array(list);
+		if (attrs_arr == NULL) {
+			rad_log(RL_ERROR, "Error making %s list.", attr_name);
+			*error = make_error(&e__UserMgrErrorType_READERROR);
+			*rtn_code = ce_object;
+		}
+		if ((*rtnval = data_purify_deep(attrs_arr)) == NULL) {
+			rad_log(RL_ERROR, "Error in return type.");
+			*error = make_error(&e__UserMgrErrorType_READERROR);
+			*rtn_code = ce_object;
+		}
+	} else {
+		rad_log(RL_ERROR,
+		    "Error getting assigned %s.", attr_name);
+		*error = make_error(&e__UserMgrErrorType_READERROR);
+		*rtn_code = ce_object;
+	}
+}
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_read_profiles(rad_instance_t *inst, adr_attribute_t *attr,
+    data_t **rtnval, data_t **error)
+{
+	conerr_t rtn_code = ce_ok;
+	nss_attr_t *profs_lst = NULL;
+
+	rad_log(RL_DEBUG, "In read_profiles");
+	_nss_get_assign_profiles(NULL, &profs_lst);
+	populate_list(profs_lst, USERATTR_PROFILES_KW, &rtn_code,
+	    rtnval, error);
+	return (rtn_code);
+}
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_read_roles(rad_instance_t *inst, adr_attribute_t *attr,
+    data_t **rtnval, data_t **error)
+{
+	conerr_t rtn_code = ce_ok;
+	nss_attr_t *roles_lst = NULL;
+
+	rad_log(RL_DEBUG, "In read_roles.");
+	_nss_get_assign_roles(NULL, &roles_lst);
+	populate_list(roles_lst, USERATTR_ROLES_KW, &rtn_code,
+	    rtnval, error);
+	return (rtn_code);
+}
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_read_auths(rad_instance_t *inst, adr_attribute_t *attr,
+    data_t **rtnval, data_t **error)
+{
+	conerr_t rtn_code = ce_ok;
+	nss_attr_t *auths_lst = NULL;
+
+	rad_log(RL_DEBUG, "In read_auths");
+	_nss_get_assign_auths(NULL, &auths_lst);
+	populate_list(auths_lst, USERATTR_AUTHS_KW,
+	    &rtn_code, rtnval, error);
+	return (rtn_code);
+}
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_read_defaultPrivs(rad_instance_t *inst, adr_attribute_t *attr,
+    data_t **rtnval, data_t **error)
+{
+	conerr_t rtn_code = ce_ok;
+	nss_attr_t *privs_lst = NULL;
+
+	rad_log(RL_DEBUG, "In read_deafutlPrivs");
+	_nss_get_assign_privs(NULL, USERATTR_DFLTPRIV_KW,  &privs_lst);
+	populate_list(privs_lst, USERATTR_DFLTPRIV_KW,
+	    &rtn_code, rtnval, error);
+	return (rtn_code);
+}
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_read_limitPrivs(rad_instance_t *inst, adr_attribute_t *attr,
+    data_t **rtnval, data_t **error)
+{
+	conerr_t rtn_code = ce_ok;
+	nss_attr_t *privs_lst = NULL;
+
+	rad_log(RL_DEBUG, "In read_limitPrivs");
+	_nss_get_assign_privs(NULL, USERATTR_LIMPRIV_KW,  &privs_lst);
+	populate_list(privs_lst, USERATTR_LIMPRIV_KW,
+	    &rtn_code, rtnval, error);
+	return (rtn_code);
+}
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_read_supplGroups(rad_instance_t *inst, adr_attribute_t *attr,
+    data_t **rtnval, data_t **error)
+{
+	conerr_t rtn_code = ce_ok;
+	nss_attr_t *grps_lst = NULL;
+
+	rad_log(RL_DEBUG, "In SupplGroups.");
+	_nss_get_assign_grps(NULL, &grps_lst);
+	populate_list(grps_lst, GROUPS, &rtn_code, rtnval, error);
+	return (rtn_code);
+}
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_read_scopes(rad_instance_t *inst, adr_attribute_t *attr,
+    data_t **rtnval, data_t **error)
+{
+	conerr_t rtn_code = ce_ok;
+	char *scopes_str;
+	char *lasts;
+	char *token;
+	data_t *scope;
+
+	rad_log(RL_DEBUG, "In readScopes.");
+	scopes_str = _nss_get_scopes();
+	data_t *scopes_arr = data_new_array(&t_array_string, 2);
+	token = strtok_r(scopes_str, ",", &lasts);
+	do {
+		if (token != NULL) {
+			scope = data_new_string((const char *)token,
+			    lt_copy);
+			(void) array_add(scopes_arr, scope);
+		}
+	} while ((token = strtok_r(NULL, ",", &lasts)) != NULL);
+	if (data_verify(scopes_arr, scopes_arr->d_type, B_TRUE)) {
+		*rtnval = scopes_arr;
+	} else {
+		data_free(scopes_arr);
+		*rtnval = NULL;
+		*error = make_error(&e__UserMgrErrorType_READERROR);
+		rtn_code = ce_object;
+	}
+	return (rtn_code);
+}
+
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_read_auditClasses(rad_instance_t *inst, adr_attribute_t *attr,
+    data_t **rtnval, data_t **error)
+{
+	/* will implement along with other fixes. */
+	*rtnval = NULL;
+	*error = make_error(&e__UserMgrErrorType_READERROR);
+	return (ce_object);
+}
+
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_read_pamUserConfFiles(rad_instance_t *inst, adr_attribute_t *attr,
+    data_t **rtnval, data_t **error)
+{
+	/* will implement along with other fixes. */
+	*rtnval = NULL;
+	*error = make_error(&e__UserMgrErrorType_READERROR);
+	return (ce_object);
+}
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_invoke_setScope(rad_instance_t *inst, adr_method_t *meth,
+    data_t **rtnval, data_t **args, int count, data_t **error)
+{
+	boolean_t setOK = B_TRUE;
+	conerr_t rtn_code = ce_ok;
+	int uscope = enum_tovalue(data_get_internal(args[0], dt_enum));
+
+	rad_log(RL_DEBUG, "In setScope : %d.", uscope);
+	if (uscope == 1) {
+		setOK = __ns_ldap_is_shadow_update_enabled();
+		rad_log(RL_DEBUG, "is_shadow_update_enabled:%s",
+		    (setOK == B_TRUE) ? "TRUE" : "FALSE");
+	}
+	scope = (char *)strdup((uscope == 1) ? NSS_REP_LDAP : NSS_REP_FILES);
+	return (rtn_code);
+}
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_invoke_setFilter(rad_instance_t *inst, adr_method_t *meth,
+    data_t **rtnval, data_t **args, int count, data_t **error)
+{
+	conerr_t rtn_code = ce_ok;
+	int utype = enum_tovalue(data_get_internal(args[0], dt_enum));
+
+	rad_log(RL_DEBUG, "In setFilter : %d.", utype);
+	if (utype != 0 && utype != 1) {
+		rad_log(RL_DEBUG, "Invalid type :%d", utype);
+		return (rtn_code);
+	}
+	type = (char *)strdup((utype == 1) ?
+	    USERATTR_TYPE_ROLE : USERATTR_TYPE_NORMAL_KW);
+	return (rtn_code);
+}
+
+/*ARGSUSED*/
+conerr_t
+api_UserMgr_invoke_isSystemLabeled(rad_instance_t *inst, adr_method_t *meth,
+    data_t **rtnval, data_t **args, int count, data_t **error)
+{
+	/* will implement along with other fixes. */
+	*rtnval = NULL;
+	*error = make_error(&e__UserMgrErrorType_READERROR);
+	return (ce_object);
+}
+
 static rad_modinfo_t modinfo = {"usermgr", "User Management"};
 
 int
 _rad_init(void *handle)
 {
+
 	if (rad_module_register(handle, RAD_MODVERSION, &modinfo) == -1)
 		return (-1);
 
@@ -993,7 +1812,7 @@
 		return (0);
 
 	(void) cont_insert_singleton(rad_container, adr_name_fromstr(
-	    "com.oracle.solaris.vp.panels.usermgr:type=UserMgr"),
+	    "com.oracle.solaris.rad.usermgr:type=UserMgr"),
 	    &api_UserMgr_svr);
 
 	return (0);
--- a/usr/src/java/vpanels/app/usermgr/build.xml	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/build.xml	Fri Apr 27 00:52:26 2012 -0400
@@ -39,7 +39,7 @@
 	    value="com.oracle.solaris.vp.panels.usermgr.client.swing.UserMgrPanelDescriptor" />
 	<property name="panel.name" value="User Manager" />
 	<property name="panel.icon.src"
-	    value="com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-32.png" />
+	    value="com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-32.png" />
 	<property name="panel.icon.dst" value="usermgr.png" />
 
 	<target name="generate_project" depends="panelsdef.generate_project">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/ActionString.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,142 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.util.*;
+
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * ActionString interposes between the application code and it's resource
+ * bundle, but parses the returned string for the mnemonic indicator and
+ * removes it.  The mnemonic character is '&', as used in Windows.  This
+ * class make it easy to localize the text and associated mnemonics in a
+ * resource properties file - mnemonics can be embedded within the string,
+ * obviating the need for seperate resource strings for the mnemonics.
+ *
+ * Note: many Swing components can now take in HTML encoded text in addition
+ * to plain text. To encode a mnemonic in HTML the '&' has to be encoded
+ * in the HTML escaped form '&amp;'. Otherwise the HTML processing within
+ * Swing will remove the a single '&'.
+ *
+ */
+public class ActionString {
+
+    private String  string;
+    private int mnemonic = 0;
+
+    /**
+     * Returns the localized message associated with the specified message key
+     * from the default resource bundle.  Strip out the mnemonic indicator.
+     * Users of this class can then use getString() and getMnemonic().
+     *
+     * @param	key	message lookup key
+     */
+    public ActionString(String key) {
+
+	string = Finder.getString(key);
+	split();
+
+    } // constructor
+
+    /*
+     * Returns the text string without the mnemonic indicator
+     *
+     * @return the text string without the mnemonic character
+     */
+    public String getString() {
+
+	return string;
+
+    } // getString
+
+
+    /*
+     * Returns the mnemonic character
+     *
+     * @return the mnemonic character
+     */
+    public int getMnemonic() {
+
+	return mnemonic;
+
+    } // getMnemonic
+
+
+    /**
+     * Split the retrieved message into its string and mnemonic parts.
+     */
+    private void split() {
+
+	/*
+	 * Simple check to see if the text is HTML or plain text. If the text
+	 * is HTML the mnemonic indicator will be encoded as '&amp;' and not
+	 * the plain text '&'. Therefore extraction of the mnemonic itself
+	 * is a little more interesting. Also the underline tags need to
+	 * be inserted to ensure that the mnemonic character is correctly
+	 * displayed underlined when the text is HTML.
+	 */
+	boolean isHtml =
+		(string.startsWith("<html>") && string.endsWith("</html>"));
+
+	String ampString = null;
+
+	if (isHtml) {
+	    ampString = "&amp;";
+	} else {
+	    ampString = "&";
+	}
+
+	int ampStringLen = ampString.length();
+	int i = string.indexOf(ampString);
+
+	if (i > -1) {
+	    String sUpper = string.toUpperCase();
+	    mnemonic = sUpper.charAt(i + ampStringLen);
+
+	    StringBuffer s = new StringBuffer();
+	    s.append(string.substring(0, i));
+
+	    if (isHtml) {
+		s.append("<u>");
+	    }
+
+	    s.append(string.substring(i + ampStringLen, i+ ampStringLen + 1));
+
+	    if (isHtml) {
+		s.append("</u>");
+	    }
+
+	    s.append(string.substring(i + ampStringLen + 1, string.length()));
+
+	    string = s.toString();
+	}
+
+    } // split
+
+} // ActionString
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AddUserAction.java	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AddUserAction.java	Fri Apr 27 00:52:26 2012 -0400
@@ -25,6 +25,7 @@
 
 package com.oracle.solaris.vp.panels.usermgr.client.swing;
 
+import java.awt.*;
 import java.awt.event.*;
 import java.util.List;
 import javax.swing.*;
@@ -32,41 +33,77 @@
 import com.oracle.solaris.vp.panel.common.action.*;
 import com.oracle.solaris.vp.panel.common.control.*;
 import com.oracle.solaris.vp.panel.swing.action.AddManagedObjectAction;
-import com.oracle.solaris.vp.panels.usermgr.*;
+import com.oracle.solaris.vp.panel.swing.view.ChangeIndicator;
+import com.oracle.solaris.rad.usermgr.*;
 import com.oracle.solaris.vp.util.misc.ObjectUtil;
 import com.oracle.solaris.vp.util.misc.finder.Finder;
 import com.oracle.solaris.vp.util.misc.property.*;
 import com.oracle.solaris.vp.util.swing.*;
 import com.oracle.solaris.vp.util.swing.layout.*;
 import com.oracle.solaris.vp.util.swing.property.*;
+import com.oracle.solaris.vp.util.misc.ChangeableAggregator;
+
+/*
+ * Add a new user or role
+ */
 
 @SuppressWarnings({"serial"})
 public class AddUserAction extends AddManagedObjectAction
     <UserManagedObject, AddUserAction.Data, UserManagedObject> {
 
+    private UserManagedObject umo = null;
+    private UserImpl user = null;
+
     //
     // Inner classes
     //
 
-    protected class Data {
+    protected class Data implements ActionListener {
 	//
 	// Instance data
 	//
 
-	public StringProperty userNameProperty = new StringProperty();
-	public StringProperty userDescProperty = new StringProperty();
+	private JLabel uidLabel;
+	private HintTextField uidField;
+	private JLabel descLabel;
+	private JComboBox groupCombo;
+	private HintTextField homeField;
+	private JComboBox shellCombo;
+	public MutableProperty<String> typeProperty = new StringProperty();
+	public StringProperty nameProperty = new StringProperty();
+	public LongProperty uidProperty = new LongProperty();
+	public MutableProperty<String> descProperty = new StringProperty();
+	public MutableProperty<String> groupProperty = new StringProperty();
+	public MutableProperty<String> homeProperty = new StringProperty();
+	public MutableProperty<String> shellProperty = new StringProperty();
 	public MutableProperty<char[]> passProperty =
 	    new BasicMutableProperty<char[]>();
 	public MutableProperty<char[]> passConfirmProperty =
 	    new BasicMutableProperty<char[]>();
-	public JOptionPane pane;
-	public JDialog dialog;
+
+	private JOptionPane pane;
+	private JDialog dialog;
+        private static final String ACTION_ADV_SETTINGS = "settings";
+        private AdvancedSettingsDialog advDialog = null;
+	private UserMgrPanelDescriptor descriptor = null;
+	private ActionString actString = null;
 
 	//
 	// Constructors
 	//
 
 	public Data() {
+	    pane = new JOptionPane(createForm(), JOptionPane.PLAIN_MESSAGE,
+		JOptionPane.OK_CANCEL_OPTION);
+	    UserMgrUtils.removeIcons(pane);
+
+	    String title = Finder.getString("usermgr.new.title." +
+		descriptor.getTypeString());
+	    dialog = pane.createDialog(getHasComponent().getComponent(),
+		title);
+	}
+
+    private JPanel createForm() {
 	    ActionListener listener =
 		new ActionListener() {
 		    @Override
@@ -75,79 +112,242 @@
 		    }
 		};
 
-	    // Intro text
-	    JLabel introLabel = new JLabel(
-		Finder.getString("usermgr.adduser.label.intro"));
+	descriptor = control.getPanelDescriptor();
+	user = descriptor.getDefaultUser();
+
+	JPanel form = new JPanel(new GridBagLayout());
+	GridBagConstraints gbc = new GridBagConstraints();
+	int width = GUIUtil.getTextFieldWidth();
+
+	gbc.gridx = 0;
+	gbc.gridy = 0;
+	gbc.weightx = 1.0;
+	gbc.anchor = GridBagConstraints.LINE_START;
+        int hGap = GUIUtil.getHalfGap();
+	gbc.insets = new Insets(0, 0, hGap, hGap);
 
-	    // User name
-	    JLabel userNameLabel = new JLabel(
-		Finder.getString("usermgr.basic.label.username"));
-	    JTextField userNameField = GUIUtil.createTextField();
-	    userNameField.addActionListener(listener);
+	// Intro text
+	JLabel introLabel = new JLabel(
+	Finder.getString("usermgr.new.label." +
+		descriptor.getTypeString()));
+	form.add(introLabel, gbc);
+
+	// User name
+	actString = new ActionString("usermgr.basic.name." +
+		descriptor.getTypeString());
+        JLabel nameLabel = new JLabel(actString.getString());
+        nameLabel.setDisplayedMnemonic(actString.getMnemonic());
+
+	JTextField nameField = GUIUtil.createTextField();
+	nameField.addActionListener(listener);
 	    new TextComponentPropertySynchronizer<String, JTextComponent>
-		(userNameProperty, userNameField, false);
+		(nameProperty, nameField, false);
+
+	// Connect the label to the field
+	nameLabel.setLabelFor(nameField);
+
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(nameLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(nameField, gbc);
+	form.add(new Spacer(), gbc);
+
+	// Description
+	actString = new ActionString("usermgr.basic.desc." +
+		descriptor.getTypeString());
+        descLabel = new JLabel(actString.getString());
+        descLabel.setDisplayedMnemonic(actString.getMnemonic());
+	JTextField descField = GUIUtil.createTextField();
+	new TextComponentPropertySynchronizer<String, JTextField>(
+	    descProperty, descField);
+
+	// Connect the label to the field
+	descLabel.setLabelFor(descField);
+
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(descLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(descField, gbc);
+
+	// User ID
+	actString = new ActionString("usermgr.basic.uid." +
+		descriptor.getTypeString());
+        uidLabel = new JLabel(actString.getString());
+        uidLabel.setDisplayedMnemonic(actString.getMnemonic());
+
+
+	uidField = new HintTextField(width);
+	uidField.setHintText(
+	    Finder.getString("usermgr.new.value.auto"));
+	uidField.setDocument(new NumericDocument());
+	new HintTextPropertySynchronizer<Long>(uidProperty,
+	    uidField, 0L);
+	ChangeIndicator uidChange = new ChangeIndicator();
+	uidProperty.addChangeListener(uidChange);
+	uidProperty.save();
+	// uidField.addActionListener(listener);
+
+	// Connect the label to the field
+	uidLabel.setLabelFor(uidField);
+
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(uidLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(uidField, gbc);
+	form.add(new Spacer(), gbc);
 
-	    // User Description
-	    JLabel userDescLabel = new JLabel(
-			Finder.getString("usermgr.basic.label.userdesc"));
-	    JTextField userDescField = GUIUtil.createTextField();
-	    userDescField.addActionListener(listener);
-	    new TextComponentPropertySynchronizer<String, JTextComponent>
-		(userDescProperty, userDescField, false);
+	// Group Name
+	actString = new ActionString("usermgr.basic.label.group");
+        JLabel groupLabel = new JLabel(actString.getString());
+        groupLabel.setDisplayedMnemonic(actString.getMnemonic());
+	groupCombo = new JComboBox();
+	new ComboBoxPropertySynchronizer<String>(groupProperty, groupCombo);
+
+	for (Group g : descriptor.getGroups()) {
+	    groupCombo.addItem(g.getGroupName());
+	    if (user.getGroupID() == g.getGroupID()) {
+		groupCombo.setSelectedItem(g.getGroupName());
+	    }
+	}
+
+	// Connect the label to the field
+	groupLabel.setLabelFor(groupCombo);
+
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(groupLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(groupCombo, gbc);
+
+	// Home Directory
+	actString = new ActionString("usermgr.basic.label.home");
+        JLabel homeLabel = new JLabel(actString.getString());
+        homeLabel.setDisplayedMnemonic(actString.getMnemonic());
+
+	homeField = new HintTextField(width);
+	homeField.setHintText(Finder.getString("usermgr.new.value.auto"));
+	new HintTextPropertySynchronizer<String>(homeProperty, homeField, "");
+	ChangeIndicator homeChange = new ChangeIndicator();
+	homeProperty.addChangeListener(homeChange);
+	homeProperty.save();
+
+	// Connect the label to the field
+	homeLabel.setLabelFor(homeField);
+
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(homeLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(homeField, gbc);
+
+	// Login Shell
+	actString = new ActionString("usermgr.basic.label.shell");
+        JLabel shellLabel = new JLabel(actString.getString());
+        shellLabel.setDisplayedMnemonic(actString.getMnemonic());
+	shellCombo = new JComboBox();
+	new ComboBoxPropertySynchronizer<String>(shellProperty, shellCombo);
+	for (String s : descriptor.getShells())
+	    shellCombo.addItem(s);
+
+	shellCombo.setSelectedItem(user.getDefaultShell());
+	// Connect the label to the field
+	shellLabel.setLabelFor(shellCombo);
+
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(shellLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(shellCombo, gbc);
 
 	    // Password
-	    int width = GUIUtil.getTextFieldWidth();
-	    JLabel passLabel = new JLabel(
-		Finder.getString("usermgr.basic.label.pass"));
+	actString = new ActionString("usermgr.basic.label.pass");
+        JLabel passLabel = new JLabel(actString.getString());
+        passLabel.setDisplayedMnemonic(actString.getMnemonic());
+
 	    JPasswordField passField = new JPasswordField(width);
 	    passField.addActionListener(listener);
-	    new PasswordFieldPropertySynchronizer(passProperty,
-		passField, false);
+	new PasswordFieldPropertySynchronizer(passProperty, passField, false);
+
+	// Connect the label to the field
+	passLabel.setLabelFor(passField);
 
-	    // Password Confirm
-	    JLabel passConfirmLabel = new JLabel(
-		Finder.getString("usermgr.basic.label.passconfirm"));
-	    JPasswordField passConfirmField = new JPasswordField(width);
-	    new PasswordFieldPropertySynchronizer(passConfirmProperty,
-		passConfirmField, false);
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(passLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(passField, gbc);
+
+	// Password Confirm
+	actString = new ActionString("usermgr.basic.label.passconfirm");
+        JLabel passConfirmLabel = new JLabel(actString.getString());
+        passConfirmLabel.setDisplayedMnemonic(actString.getMnemonic());
 
-	    JPanel formPanel = new JPanel();
-	    formPanel.setOpaque(false);
-	    Form form = new Form(formPanel, VerticalAnchor.TOP);
+	JPasswordField passConfirmField = new JPasswordField(width);
+	new PasswordFieldPropertySynchronizer(
+		passConfirmProperty, passConfirmField, false);
 
-	    int gap = GUIUtil.getHalfGap() * 2;
+	// Connect the label to the field
+	passConfirmLabel.setLabelFor(passConfirmField);
 
-	    ColumnLayoutConstraint c = new ColumnLayoutConstraint(
-		HorizontalAnchor.FILL, gap);
-	    RowLayoutConstraint row = new RowLayoutConstraint(
-		VerticalAnchor.CENTER, gap);
-	    row.setLayoutIfInvisible(true);
-	    HasAnchors a = new SimpleHasAnchors(
-		HorizontalAnchor.LEFT, VerticalAnchor.CENTER);
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(passConfirmLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(passConfirmField, gbc);
+
+	// Advanced Settings
+	actString = new ActionString("usermgr.advanced.settings");
+	JButton advSettings = new JButton(actString.getString());
+	advSettings.setActionCommand(ACTION_ADV_SETTINGS);
+	advSettings.addActionListener(this);
+	advSettings.setMnemonic(actString.getMnemonic());
 
-	    form.addRow(HorizontalAnchor.LEFT, c);
-	    form.add(introLabel, row);
-
-	    form.addTable(2, gap, gap, HorizontalAnchor.LEFT, c);
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++;
+	gbc.gridwidth = GridBagConstraints.REMAINDER;
+	gbc.anchor = GridBagConstraints.SOUTHWEST;
+	form.add(advSettings, gbc);
 
-	    form.add(userNameLabel, a);
-	    form.add(userNameField, a);
-
-	    form.add(userDescLabel, a);
-	    form.add(userDescField, a);
+	return form;
+    }
 
-	    form.add(passLabel, a);
-	    form.add(passField, a);
-
-	    form.add(passConfirmLabel, a);
-	    form.add(passConfirmField, a);
+	/**
+	 * action listener for Adv settings button
+	 */
+        @Override
+        public void actionPerformed(ActionEvent e)  {
+            String actionCmd = e.getActionCommand();
+	    if (actionCmd == ACTION_ADV_SETTINGS) {
+		UserMgrPanelDescriptor descriptor =
+			control.getPanelDescriptor();
+		if (umo == null || user == null) {
+		    user = new UserImpl();
+		    umo = new UserManagedObject(descriptor, user, null);
+		}
 
-	    pane = new JOptionPane(formPanel, JOptionPane.PLAIN_MESSAGE,
-		JOptionPane.OK_CANCEL_OPTION);
-
-	    dialog = pane.createDialog(getHasComponent().getComponent(),
-		Finder.getString("usermgr.adduser.title"));
-	}
+		if (advDialog == null ||
+		    descriptor.isTypeRole() != advDialog.isTypeRole()) {
+		    advDialog = new AdvancedSettingsDialog(
+			getHasComponent().getComponent(), descriptor, umo);
+		} else {
+		    advDialog.setUser(umo);
+		}
+		advDialog.show();
+		if (advDialog.getValue() == JOptionPane.OK_OPTION) {
+		    advDialog.update();
+    		}
+	    }
+        }
     }
 
     //
@@ -169,6 +369,10 @@
 
     public AddUserAction(MainControl control) {
 	super(ADD_TEXT, null, control);
+        ActionString actStr = new ActionString(
+	    "usermgr.action.add.button");
+	putValue(Action.NAME, actStr.getString());
+	putValue(Action.MNEMONIC_KEY, actStr.getMnemonic());
 	this.control = control;
 	setLoops(true);
     }
@@ -178,8 +382,8 @@
     //
 
     @Override
-    public Data getRuntimeInput(List<UserManagedObject> selection, Data uData)
-	throws ActionAbortedException {
+    public Data getRuntimeInput(List<UserManagedObject> selection,
+    	Data uData) throws ActionAbortedException {
 
 	// Since this action navigates to the new object once created, we must
 	// first navigate to control so that any outstanding changes in the
@@ -210,35 +414,53 @@
 
     @Override
     public UserManagedObject workBusy(List<UserManagedObject> selection,
-	Data uData) throws ActionAbortedException, ActionFailedException,
+	Data uData) throws ActionFailedException,
+		ActionAbortedException,
 	ActionUnauthorizedException {
 
+
 	UserMgrPanelDescriptor descriptor = control.getPanelDescriptor();
 
-	String username = uData.userNameProperty.getValue();
+	String username = uData.nameProperty.getValue();
 	UserMgrUtils.validateUsername(descriptor, username);
 
-	String description = uData.userDescProperty.getValue();
+	String description = uData.descProperty.getValue();
 	UserMgrUtils.validateUserDesc(description);
 
+	String group = uData.groupProperty.getValue();
+	String shell = uData.shellProperty.getValue();
+	String homedir = uData.homeProperty.getValue();
+
 	char[] password = uData.passProperty.getValue();
 	char[] password2 = uData.passConfirmProperty.getValue();
 	UserMgrUtils.validatePassword(true, password, password2);
 
-	UserImpl user = descriptor.getDefaultUser();
-	user.setUsername(username);
-	user.setDescription(description);
 	UserMgrUtils.clearPassword(password2);
 
-	UserManagedObject umo = new UserManagedObject(descriptor,
+	user.setUsername(username);
+	if (uData.uidProperty.isChanged()) {
+	    long uid = uData.uidProperty.getValue();
+	    user.setUserID(uid);
+	}
+
+	user.setDescription(description);
+	user.setDefaultShell(shell);
+	user.setHomeDirectory(homedir);
+
+	if (umo == null) {
+	    umo = new UserManagedObject(descriptor,
 	    user, password);
+	} else {
+	    umo.setUser(user, password);
+	}
 
-	descriptor.addUserManagedObject(umo);
+	descriptor.addToAddList(umo);
+	descriptor.saveAddedUsers();
 
 	// Navigate to the newly created user
 	Navigable navigable = new SimpleNavigable(
-	    UserMgrControl.ID, umo.getName(),
-	    UserMgrControl.PARAM_USER, umo.getId());
+	    UserMgrBasicControl.ID, umo.getName(),
+	    UserMgrBasicControl.PARAM_USER, umo.getId());
 
 	control.getNavigator().goToAsync(false, control, navigable);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AdvancedSettings.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import com.oracle.solaris.vp.util.misc.property.*;
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/*
+ * AdvancedSettings abstract class. All the advanced settings
+ * such as Rights, Groups etc. implement this class
+ */
+
+public abstract class AdvancedSettings {
+
+    protected String label;	// Text shown in the settings list
+    protected Icon icon;	// Corresponding icon.
+    protected MutableProperty<String> settingsProperty = new StringProperty();
+
+    public AdvancedSettings(String label, Icon icon) {
+        this.label = label;
+	this.icon = icon;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    @Override
+    public String toString() {
+        return label;
+    }
+
+    public Icon getIcon() {
+        return icon;
+    }
+
+    public MutableProperty<String> getProperty() {
+        return settingsProperty;
+    }
+
+    protected abstract void init(UserMgrPanelDescriptor paneDesc);
+    protected abstract JPanel getPanel();
+    protected abstract void setUser(UserManagedObject userObj);
+    protected abstract void updateUser();
+    protected abstract boolean isChanged();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AdvancedSettingsDialog.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,252 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.Border;
+import com.oracle.solaris.vp.panel.common.action.*;
+import com.oracle.solaris.vp.panel.common.control.*;
+import com.oracle.solaris.vp.panel.swing.control.*;
+import com.oracle.solaris.vp.panel.swing.view.*;
+import com.oracle.solaris.vp.util.misc.ChangeableAggregator;
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+import com.oracle.solaris.vp.util.misc.property.*;
+import com.oracle.solaris.vp.util.swing.ClippedBorder;
+import com.oracle.solaris.vp.util.swing.SimpleCellRenderer;
+
+/*
+ * Dialog for advanced settings. The settings list varies
+ * depending on a user or a role. The Roles settings are
+ * shown only for the user, not for the role.
+ */
+
+public class AdvancedSettingsDialog implements ListSelectionListener {
+
+    //
+    // Static data
+    //
+
+    private JPanel cards;
+
+    class SettingsRenderer extends SimpleCellRenderer<AdvancedSettings> {
+    	public SettingsRenderer() {
+	    super();
+	}
+
+	@Override
+	public Icon getIcon(Component comp, AdvancedSettings value,
+		boolean isSelected, boolean hasFocus) {
+
+	    //
+	    // Current Visual designer doesn't like any icons.
+	    // If needed in future, just call return value.getIcon();
+
+	    return (null);
+	}
+
+	public String getText(Component comp, AdvancedSettings value,
+		boolean isSelected, boolean hasFocus) {
+	    return (value.getLabel());
+	}
+    }
+
+    //
+    // Instance data
+    //
+
+    private ManagedObjectTableModel model;
+    private UserMgrPanelDescriptor panelDesc;
+    private JOptionPane pane;
+    private JDialog dialog;
+    private AdvancedSettings userSettings[] = {
+    	new GroupsSettings(),
+    	new RolesSettings(),
+    	new RightsSettings(),
+    	new AuthsSettings()
+    };
+
+    // Role doesn't have roles to assign
+    private AdvancedSettings roleSettings[] = {
+    	new GroupsSettings(),
+    	new RightsSettings(),
+    	new AuthsSettings()
+    };
+
+    private AdvancedSettings settingsList[];
+
+    private AdvancedSettings curSettings;
+    private UserManagedObject userObj;
+    private boolean isRole;
+    private String title = Finder.getString("usermgr.advanced.title");
+
+    private MutableProperty<String> rightsProperty = new StringProperty();
+    private MutableProperty<String> rolesProperty = new StringProperty();
+    private MutableProperty<String> groupsProperty = new StringProperty();
+    private MutableProperty<String> authsProperty = new StringProperty();
+
+
+    //
+    // Constructors
+    //
+
+    public AdvancedSettingsDialog(Component parent,
+	    UserMgrPanelDescriptor panelDesc,
+	    UserManagedObject userObj) {
+        String utitle = title;
+	this.userObj = userObj;
+	if (panelDesc.isTypeRole()) {
+	    settingsList = roleSettings;
+	    isRole = true;
+	} else {
+	    settingsList = userSettings;
+	    isRole = false;
+	}
+        pane = new JOptionPane(createForm(panelDesc),
+		JOptionPane.PLAIN_MESSAGE,
+		JOptionPane.OK_CANCEL_OPTION);
+	UserMgrUtils.removeIcons(pane);
+	String name = userObj.getUsername();
+	if (name != null) {
+	    utitle = title + " (" + userObj.getUsername() + ")";
+	}
+	// dialog = pane.createDialog(null, utitle);
+	dialog = pane.createDialog(parent, utitle);
+	dialog.setResizable(true);
+    }
+
+    /**
+     * Populate various settings from the new user
+     */
+    public void setUser(UserManagedObject userObj) {
+        this.userObj = userObj;
+        String utitle = title;
+	String name = userObj.getUsername();
+	if (name != null) {
+	    utitle = title + " (" + userObj.getUsername() + ")";
+	}
+	dialog.setTitle(utitle);
+
+	for (int i = 0; i < settingsList.length; i++) {
+		AdvancedSettings settings = settingsList[i];
+		settings.setUser(userObj);
+	}
+    }
+
+    /**
+     * Show the dialog. Block until dismissed
+     */
+    public void show() {
+    	dialog.setVisible(true);
+    }
+
+    /**
+     * Create the main form/panel.
+     */
+    private JPanel createForm(UserMgrPanelDescriptor panelDesc) {
+    	JPanel form = new JPanel(new BorderLayout());
+    	cards = new JPanel(new CardLayout());
+	JList list = new JList(settingsList);
+	SettingsRenderer renderer = new SettingsRenderer();
+	renderer.configureFor(list);
+	list.setCellRenderer(renderer);
+	list.addListSelectionListener(this);
+	Border border = list.getBorder();
+	list.setBorder(new ClippedBorder(border, false, true, true, true));
+	JScrollPane scrollPane = new JScrollPane(list);
+
+	scrollPane.setVerticalScrollBarPolicy(
+		ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
+	scrollPane.setHorizontalScrollBarPolicy(
+		ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+	form.add(scrollPane, BorderLayout.WEST);
+	for (int i = 0; i < settingsList.length; i++) {
+		curSettings = settingsList[i];
+		curSettings.init(panelDesc);
+		curSettings.setUser(userObj);
+		cards.add(curSettings.getPanel(), curSettings.getLabel());
+	}
+	list.setSelectedIndex(0);
+	form.add(cards, BorderLayout.CENTER);
+	form.setPreferredSize(new Dimension(700, 400));
+
+    	return form;
+    }
+
+    public void valueChanged(ListSelectionEvent e) {
+   	JList list = (JList) e.getSource();
+   	curSettings = settingsList[list.getSelectedIndex()];
+   	CardLayout cl = (CardLayout) cards.getLayout();
+	cl.show(cards, curSettings.getLabel());
+    }
+
+    public int getValue() {
+	Number n;
+	int option;
+	Object obj = pane.getValue();
+
+	if (obj.getClass().getSuperclass() == Number.class) {
+	    n = (Number) obj;
+	    option = n.intValue();
+	    return option;
+	}
+
+	return JOptionPane.CANCEL_OPTION;
+    }
+
+    /**
+     * Find out if any of the settings is changed
+     */
+    public boolean isChanged() {
+	for (int i = 0; i < settingsList.length; i++) {
+	    if (settingsList[i].isChanged()) {
+		return (true);
+	    }
+	}
+
+    	return (false);
+    }
+
+    /**
+     * Returns the type of user: role or normal user
+     */
+    public boolean isTypeRole() {
+        return isRole;
+    }
+
+    /**
+     * Update user object based on advanced settings
+     */
+    public void update() {
+	for (int i = 0; i < settingsList.length; i++) {
+	    settingsList[i].updateUser();
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Arranger.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,377 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.tree.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.beans.*;
+import java.util.*;
+import java.io.*;
+
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * SMC code adapted for Visual Panels
+ */
+public class Arranger extends DoubleTrees {
+
+    JButton moveUpItem, moveDownItem;
+
+    public Arranger() {
+
+	// Map DoubleTrees variables here for better descriptive names
+	moveUpItem = addAllItem;
+	moveDownItem = delAllItem;
+
+	setListeners();
+    }
+
+    public Arranger(String srcHeader, String dstHeader) {
+
+	super(srcHeader, dstHeader);
+
+	// Map DoubleTrees variables here for better descriptive names
+	moveUpItem = addAllItem;
+	moveDownItem = delAllItem;
+
+	setListeners();
+
+    }
+
+    /**
+     * Create any dynamic images we need.
+     */
+    public void addNotify() {
+
+	ActionString actionString;
+
+	super.addNotify();
+
+	delItem.setIcon(Finder.getIcon("images/remove.png"));
+	delItem.setHorizontalTextPosition(JButton.RIGHT);
+
+	moveDownItem.setIcon(Finder.getIcon("images/move_dn.png"));
+	moveDownItem.setHorizontalTextPosition(JButton.LEFT);
+        actionString = new ActionString("usermgr.advanced.move_down_btn");
+        moveDownItem.setText(actionString.getString());
+        moveDownItem.setMnemonic(actionString.getMnemonic());
+
+	addItem.setIcon(Finder.getIcon("images/add.png"));
+	addItem.setHorizontalTextPosition(JButton.LEFT);
+
+	moveUpItem.setIcon(Finder.getIcon("images/move_up.png"));
+	moveUpItem.setHorizontalTextPosition(JButton.LEFT);
+	actionString = new ActionString("usermgr.advanced.move_up_btn");
+        moveUpItem.setText(actionString.getString());
+        moveUpItem.setMnemonic(actionString.getMnemonic());
+
+    } // addNotify
+
+    public void setListeners() {
+
+	addItem.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		move(srcTree, dstTree);
+	    }
+	});
+
+	delItem.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		move(dstTree, srcTree);
+	    }
+	});
+
+	moveUpItem.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		reorder(dstTree, -1);
+	    }
+	});
+
+	moveDownItem.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		reorder(dstTree, +1);
+		}
+	    });
+
+	MouseListener ml = new MouseAdapter() {
+	    public void mouseClicked(MouseEvent e) {
+		handleMouse(e);
+	    }
+
+	    public void mousePressed(MouseEvent e) {
+		handleMouse(e);
+	    }
+	};
+
+	srcTree.addMouseListener(ml);
+	dstTree.addMouseListener(ml);
+
+    }
+
+    private void updateMoveButtons(DblTreeNode node, boolean flag) {
+
+	if (flag) {
+	    DefaultTreeModel    dstModel = (DefaultTreeModel)dstTree.getModel();
+	    DblTreeNode root = (DblTreeNode)dstModel.getRoot();
+
+	    int index = dstModel.getIndexOfChild(root, node);
+	    int limit = dstModel.getChildCount(root);
+
+	    if (index > 0)
+		moveUpItem.setEnabled(true);
+	    else
+		moveUpItem.setEnabled(false);
+	    if (index < (limit - 1))
+		moveDownItem.setEnabled(true);
+	    else
+		moveDownItem.setEnabled(false);
+	} else {
+	    moveUpItem.setEnabled(false);
+	    moveDownItem.setEnabled(false);
+	}
+
+    }
+
+    private void handleMouse(MouseEvent e) {
+
+	JTree  tree1, tree2;
+
+	if (e.getSource() == srcTree) {
+	    tree1 = srcTree;
+	    tree2 = dstTree;
+
+	    delItem.setEnabled(false);
+	    moveUpItem.setEnabled(false);
+	    moveDownItem.setEnabled(false);
+	} else {
+            tree1 = dstTree;
+	    tree2 = srcTree;
+	    addItem.setEnabled(false);
+	}
+	TreePath selPath = tree1.getPathForLocation(e.getX(), e.getY());
+
+	if (selPath != null) {
+	    tree2.clearSelection();
+	    int selCount = selPath.getPathCount();
+
+	    DblTreeNode node = (DblTreeNode)selPath.getLastPathComponent();
+	    if (e.getClickCount() < 2) {
+		boolean flag;
+		if (selCount == 2)
+		    flag = true;
+		else
+		    flag = false;
+
+		if (e.getSource() == srcTree) {
+		    addItem.setEnabled(flag);
+		} else {
+		    delItem.setEnabled(flag);
+		    updateMoveButtons(node, flag);
+		}
+	    } else if (e.getClickCount() == 2) {
+		if ((selCount == 2) && node.isLeaf())
+		    move(tree1, tree2);
+	    }
+        }
+
+    }
+
+    public void move(JTree src, JTree dst) {
+	DblTreeNode node;
+
+	TreePath selPath = src.getSelectionPath();
+	if (selPath == null) // nothing selected (should be disabled)
+	    return;
+	else if (selPath.getPathCount() != 2)
+	    return;
+	else {
+	    node = (DblTreeNode)selPath.getLastPathComponent();
+	    moveLeaf(src, dst, node);
+
+	    if (src == dstTree) {
+		addItem.setEnabled(true);
+		delItem.setEnabled(false);
+		updateMoveButtons(node, false);
+	    } else {
+		addItem.setEnabled(false);
+		delItem.setEnabled(true);
+		updateMoveButtons(node, true);
+	    }
+	}
+
+    }
+
+
+    private int matchChild(JTree src,
+	JTree dst,
+	DblTreeNode srcNode,
+	DblTreeNode newparent,
+	Enumeration dstKids,
+	int index) {
+
+	DefaultTreeModel    srcModel = (DefaultTreeModel)src.getModel();
+	DefaultTreeModel    dstModel = (DefaultTreeModel)dst.getModel();
+
+	DblTreeNode dstNode = null;
+	String srcString = srcNode.toString();
+	while (dstKids.hasMoreElements()) {
+	    String teststring;
+
+	    dstNode = (DblTreeNode)dstKids.nextElement();
+	    // if(dstNode.isLeaf() == false)
+	    //	break;  // leaves come first
+	    teststring = dstNode.toString();
+	    if (teststring.compareTo(srcString) < 0) {
+		index++;
+		continue;
+	    } else {
+		break;
+	    }
+	}
+
+	srcModel.removeNodeFromParent(srcNode);
+	dstModel.insertNodeInto(srcNode, newparent, index);
+	index++;
+	return index;
+
+    }
+
+    public void moveLeaf(JTree src, JTree dst, DblTreeNode node) {
+
+	if (node.isEnabled()) {
+	    TreePath nodepath = new TreePath(node.getPath());
+	    boolean expanded = src.isExpanded(nodepath);
+	    initLeaf(src, dst, node);
+	    nodepath = new TreePath(node.getPath());
+	    dst.setSelectionPath(nodepath);
+
+	    if (expanded)
+		dst.expandPath(nodepath);
+	}
+
+    }
+
+
+    public void initLeaf(JTree src, JTree dst, DblTreeNode node) {
+
+	DefaultTreeModel    srcModel = (DefaultTreeModel)src.getModel();
+	DefaultTreeModel    dstModel = (DefaultTreeModel)dst.getModel();
+	DblTreeNode parent, newparent, clonedParent, root;
+	int index = 0;
+	root = (DblTreeNode)dstModel.getRoot();
+	int limit = dstModel.getChildCount(root);
+
+	if (dst == dstTree) {
+	    srcModel.removeNodeFromParent(node);
+	    dstModel.insertNodeInto(node, root, limit);
+	} else {
+	    Enumeration kids = root.children();
+	    index = matchChild(src, dst, node, root, kids, index);
+	}
+
+	TreePath nodepath = new TreePath(node.getPath());
+	dst.scrollPathToVisible(nodepath);
+    }
+
+
+    public void reorder(JTree dst, int delta) {
+
+	DefaultTreeModel    dstModel = (DefaultTreeModel)dst.getModel();
+	DblTreeNode dstRoot = (DblTreeNode)dstModel.getRoot();
+	DblTreeNode node;
+
+	TreePath selPath = dst.getSelectionPath();
+	if (selPath == null) // nothing selected (should be disabled)
+	    return;
+
+	node = (DblTreeNode)selPath.getLastPathComponent();
+	int index = dstModel.getIndexOfChild(dstRoot, node);
+	int limit = dstModel.getChildCount(dstRoot);
+	index += delta;
+
+	if ((index < 0) || (index >= limit))
+	    return;
+
+	boolean expanded = dst.isExpanded(selPath);
+	dst.clearSelection();
+
+	dstModel.removeNodeFromParent(node);
+	dstModel.insertNodeInto(node, dstRoot, index);
+
+	TreePath nodepath = new TreePath(node.getPath());
+	if (expanded)
+	    dst.expandPath(nodepath);
+
+	dst.setSelectionPath(nodepath);
+	dst.scrollPathToVisible(nodepath);
+
+	if (index > 0)
+	    moveUpItem.setEnabled(true);
+	else
+	    moveUpItem.setEnabled(false);
+
+	if (index < (limit - 1))
+	    moveDownItem.setEnabled(true);
+	else
+	    moveDownItem.setEnabled(false);
+
+    }
+
+    /**
+     * Set the focus listeners for the components in the selector panel that
+     * can have unique help that may be context-specific.  Client apps
+     * should call this method after the Arranger is created, but
+     * before the dialog is shown.  Any of the listener arguments can be
+     * null, if the client app can accept the default help for the particular
+     * component.
+     *
+     * @param upButtonListener		listener for the move-up button
+     * @param downButtonListener	listener for the move-down button
+     * @see ContextHelpListener
+     */
+    public void setFocusListeners(
+                FocusListener upButtonListener,
+                FocusListener downButtonListener) {
+
+        if (upButtonListener != null)
+            moveUpItem.addFocusListener(upButtonListener);
+
+        if (downButtonListener != null)
+            moveDownItem.addFocusListener(downButtonListener);
+
+    } // setFocusListeners
+
+    public void resetModels() {
+	srcTree.setModel(new DefaultTreeModel(new DblTreeNode("All Items")));
+	dstTree.setModel(new DefaultTreeModel(new DblTreeNode("All Items")));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AttrObj.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,318 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.lang.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * The AttrObj class implements a generic attribute key/value set.
+ * The set has a single key name and zero or more string values.
+ *
+ */
+
+@SuppressWarnings("unchecked")
+public class AttrObj extends Object implements Cloneable {
+
+    // Private attributes backstopped by persistent storage
+    protected Vector<String> vector = null;	// Vector of values for key
+    private String key = null;		// keyword for attribute
+
+    /**
+     * Constructor takes the set key name.
+     *
+     * @param keyword	A key name
+     *
+     */
+    public AttrObj(String keyword) {
+
+	super();
+	key = keyword;
+	vector = new Vector<String>(10);
+
+    }
+
+    /**
+     * Return an array of string values for the set.
+     *
+     * @return An array of string values
+     *
+     */
+    public String [] get() {
+
+	String [] attrArray = new String[vector.size()];
+	vector.copyInto(attrArray);
+	return (attrArray);
+
+    }
+
+    /**
+     * Return a vector of string values for the set.
+     *
+     * @return A vector of string values
+     *
+     */
+    public Vector getVector() {
+
+	return ((Vector)vector.clone());
+
+    }
+
+    /**
+     * Return the first string value in the set.
+     *
+     * @return A string value
+     *
+     */
+    public String getString() {
+
+	return (vector.elementAt(0));
+
+    }
+
+    /**
+     * Return true if the set contains the specified key name.
+     *
+     * @param key	The key name
+     * @return True if the set contains the key name
+     *
+     */
+    public boolean contains(String key) {
+
+	return (vector.contains(key));
+
+    }
+
+    /**
+     * Return the key name for the set.
+     *
+     * @return A key name
+     *
+     */
+    public String getKey() {
+
+	return (key);
+
+    }
+
+    /**
+     * Set the specified string value as the values for the set.
+     * Replaces any existing values.
+     *
+     * @param string	A string value
+     *
+     */
+    public void set(String string) {
+	vector.removeAllElements();
+	vector.addElement(string);
+    }
+
+    /**
+     * Set the specified string values as the values for the set.
+     * Replaces any existing values.
+     *
+     * @param array	An array of string values
+     *
+     */
+    public void set(String [] array) {
+
+	vector.removeAllElements();
+	for (int i = 0; i < array.length; i++) {
+	    vector.addElement(array[i]);
+	}
+
+    }
+
+    /**
+     * Set the specified int value as the values for the set.
+     * Replaces any existing values.
+     *
+     * @param value	An integer value
+     *
+     */
+    public void set(int value) {
+
+	vector.removeAllElements();
+	vector.addElement(Integer.toString(value));
+
+    }
+
+    /**
+     * Set the specified string values as the values for the set.
+     * Replaces any existing values.
+     *
+     * @param newVec	A vector of string values
+     *
+     */
+    public void set(Vector newVec) {
+
+	vector.removeAllElements();
+	vector = (Vector) newVec.clone();
+
+    }
+
+    /**
+     * Add the specified string value to the set.
+     * Duplicates are removed.
+     *
+     * @param string	A string value
+     *
+     */
+    public void add(String string) {
+	if (! vector.contains(string))
+	vector.addElement(string);
+    }
+
+    /**
+     * Add the specified string values to the set.
+     * Duplicates are removed.
+     *
+     * @param array	An array of string values
+     *
+     */
+    public void add(String [] array) {
+
+	for (int i = 0; i < array.length; i++) {
+	if (! vector.contains(array[i]))
+	    vector.addElement(array[i]);
+	}
+
+    }
+
+    /**
+     * Add the specified string values to the set.
+     * Duplicates are removed.
+     *
+     * @param newVec	A vector of string values
+     *
+     */
+    public void add(Vector newVec) {
+
+	Enumeration v1 = newVec.elements();
+	while (v1.hasMoreElements()) {
+	String string = (String) v1.nextElement();
+	if (! vector.contains(string))
+	    vector.addElement(string);
+	}
+
+    }
+
+    /**
+     * Remove the specified string value from the set.
+     *
+     * @param string	A string value
+     *
+     */
+    public void del(String string) {
+
+	vector.removeElement(string);
+
+    }
+
+    /**
+     * Remove the specified string values from the set.
+     *
+     * @param array	An array of string values
+     *
+     */
+    public void del(String [] array) {
+
+	for (int i = 0; i < array.length; i++) {
+	vector.removeElement(array[i]);
+	}
+
+    }
+
+    /**
+     * Remove the specified string values from the set.
+     *
+     * @param oldVec	A vector of string values
+     *
+     */
+    public void del(Vector oldVec) {
+
+	Enumeration v1 = oldVec.elements();
+	while (v1.hasMoreElements()) {
+	String string = (String) v1.nextElement();
+	if (vector.contains(string))
+	    vector.removeElement(string);
+	}
+
+    }
+
+    /**
+     * The equals method checks that all attributes of this user
+     * authorization attributes object equal the corresponding
+     * attributes of the specified user attributes object.
+     * If so, true is returned; otherwise, false is returned.
+     *
+     * @param	userAttr    Specified user attr object to be compared
+     *
+     * @return	true if the specified object is identical
+     *
+     */
+    public boolean equals(AttrObj newAttrObj) {
+
+	String s1, s2;
+
+	// Number and instances of attributes must be the same
+	if (vector.size() != newAttrObj.vector.size())
+	    return (false);
+	Enumeration v1 = vector.elements();
+	Enumeration v2 = newAttrObj.vector.elements();
+
+	while (v1.hasMoreElements()) {
+	    s1 = (String) v1.nextElement();
+	    s2 = (String) v2.nextElement();
+	    if (! s1.equals(s2))
+		return (false);
+	}
+	// Everything matches, must be equal
+	return (true);
+
+    }
+
+    /**
+     * Display the contents of the set to sysout for debugging purposes.
+     *
+     */
+    public void debugPrint() {
+
+	String strlist = new String("");
+	String sep = "	";
+	if (vector != null) {
+	    Enumeration attrs = vector.elements();
+	    while (attrs.hasMoreElements()) {
+		strlist = strlist + sep + (String)attrs.nextElement();
+		sep = ", ";
+	    }
+	}
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrCompare.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,88 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+
+import java.util.*;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * The AuthAttrCompare class implements the Compare interface
+ * for the QuickSort sorting class.  This implementation of compare
+ * compares two AuthAttrObj objects based upon comparing the
+ * authorization names in each object.
+ *
+ */
+
+public class AuthAttrCompare implements Compare {
+
+    /**
+     * The compare method compares two AuthAttrObj objects by comparing
+     * their authorization names.  The parameters are specified as Object class
+     * objects for QuickSort.  Special handling is required for header entry
+     * objects so that the headers with fewer name elements precede headers
+     * with more name elements, when the name elements match.
+     *
+     * @param	a   The first AuthAttrObj object.
+     * @param	b   The second AuthAttrObj object.
+     *
+     */
+    public final int doCompare(Object a, Object b) {
+
+	AuthAttrObj e1, e2;
+	StringTokenizer e1Tok, e2Tok;
+	String e1Name, e2Name;
+	int e1Count, e2Count;
+
+	e1 = (AuthAttrObj)a;
+	e2 = (AuthAttrObj)b;
+	e1Name = e1.getAuthName();
+	e2Name = e2.getAuthName();
+	e1Count = 0;
+	e2Count = 0;
+
+	// headers must immediately precede their authorizations
+	if (e1Name.endsWith("."))
+	    e1Count = 1;
+	if (e2Name.endsWith("."))
+	    e2Count = 1;
+
+	// The entries must have the same
+	// number of components (dots) to be lexically compared
+	e1Tok = new StringTokenizer(e1Name, ".", true);
+	e2Tok = new StringTokenizer(e2Name, ".", true);
+	e1Count += e1Tok.countTokens();
+	e2Count += e2Tok.countTokens();
+	if (e1Count == e2Count)
+	    return (e1Name.compareTo(e2Name));
+	else if (e1Count > e2Count)
+	    return 1;
+	else
+	    return -1;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrMgmt.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,451 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+
+import java.lang.*;
+import java.util.*;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * The AuthAttrMgmt class is a User Manager client object that supports
+ * the data underlying the Authorizations tab dialog panel.  This class
+ * will remotely access the authorizations table for the management scope
+ * that User Manager is currently executing in, and cache this list in
+ * the VUserMgr object for this client.  If the list has already been
+ * read (from a previous property dialog instance), that list is reused
+ * (a refresh will clear the list and cause it to be reread when the
+ * next instance of this class is created.
+ * <p>
+ * This object reads the list of authorizations granted to the authenticated
+ * principal running User Manager.  The authorization rights entry for the
+ * selected target entity in the property dialog is passed to this object
+ * in its constructor.  Since authorizations could be assigned to a user,
+ * a role, and a profile, the constructor takes an ExtAttrObj instance.
+ * With the full list of authorizations, the target and authenticated user
+ * authorization entries, a list of AuthAttrModelEntry objects is created
+ * and sorted into authorization name order for use in the Authorizations
+ * tab dialog.  When the property dialog completes (the OK button pushed),
+ * this object will build a new list of authorizations for the selected
+ * target user to replace the list in the ExtAttrObj instance passed in
+ * the constructor for the this entity (preserving other key/value
+ * attributes).
+ *
+ */
+
+public class AuthAttrMgmt {
+
+    // ========================================================================
+    //
+    // Public static define constants
+    //
+    // ========================================================================
+
+    public static final int ATTRMGMT_USER = 0;
+    public static final int ATTRMGMT_PROFILE = 1;
+
+    // ========================================================================
+    //
+    // Private class attributes
+    //
+    // ========================================================================
+
+    private UserMgrPanelDescriptor panelDesc = null;
+    private UserManagedObject userObj = null;
+    private ExtAttrObj	    tgt_auth;	// Authorizations for target entity
+    private AuthAttrObj []  auth_list;	// List of authorizations
+    private AuthAttrModelEntry [] auth_entries; // List of auth model entries
+    private int		    tgt_type;	// Type of target: user or profile
+    private String	    tgt_name;	// Name of target user, role, profile
+
+    // ========================================================================
+    //
+    // Constructors
+    //
+    // ========================================================================
+
+    /**
+     * This constructor creates a new authorization management object.	It
+     * accepts the reference to the application instance, the attribute
+     * authorization object for the user/role/profile, the type of target
+     * entity (user or profile), and the name of the target entity.
+     * The target attribute authorization object may be null, indicating
+     * no previous authorizations exist.
+     *
+     * @param	theApp	Application instance
+     * @param	tgtAttr	UserAttrObj or ProfAttrObj for the target entity
+     * @param	tgtType	Type of target: user or profile define constant
+     * @param	tgtName	Name of target user, role, or profile
+     *
+     */
+    public AuthAttrMgmt(UserMgrPanelDescriptor panelDesc,
+        UserManagedObject userObj) {
+
+	// Save stuff
+	this.panelDesc = panelDesc;
+	this.userObj = userObj;
+
+	this.auth_list = null;
+
+    }
+
+    // ========================================================================
+    //
+    // Public methods
+    //
+    // ========================================================================
+
+    /**
+     * The readAuthInfo method reads the full set of authorizations from
+     * the authorization table in the current management scope and retrieves
+     * the list of granted authorizations for the authenticated user currently
+     * running the User Manager tool.  This information is retrieved
+     * from the remote management server by the application Content instance
+     * and cached there so it can be reused by instances of this object.
+     *
+     */
+    public void readAuthInfo() {
+
+	// See if we have already gotten the list of authorizations.
+	// If not, read the list from the application content instance.
+	if ((auth_list == null) && (panelDesc != null)) {
+	    List<String> auths = panelDesc.getAuths();
+	    updateAuths(auths);
+            int authsize =  auths.size();
+	    auth_list = new AuthAttrObj[authsize];
+
+	    for (int i = 0; i < authsize; i++) {
+		auth_list[i] = new AuthAttrObj(auths.get(i));
+	    }
+	}
+    }
+
+    /**
+     * Return a list of AuthAttrModelEntry objects for the selected target
+     * user.  Each entry object represents an authorization right or an
+     * authorization header (if its name ends in a period).  Each entry is
+     * marked as to whether it can be granted or revoked in the tab dialog,
+     * and whether it is currently granted to the target user.	The list
+     * is returned in sorted order by authorization name, so the rights
+     * for a particular set are found immediately after the header for the set.
+     * For those rights without header entries in the authorization attribute
+     * table, a dummy header entry is created.	Header entries are used
+     * in the setAuthEntries method to condense the auth entries set for the
+     * target user.
+     *
+     * @return	An array of authorization model entries in sorted order
+     *
+     */
+    public AuthAttrModelEntry [] getAuthEntries() {
+
+	AuthAttrModelEntry [] entrylist;
+	AuthAttrModelEntry entry;
+	// UserAttrObj tmp_auth;
+	Vector<AuthAttrModelEntry> entries;
+	String auth_name, hdr_name, str;
+	int numauths, i, j;
+
+	// See if we have already gotten the list of authorizations
+	// If not, read the list from the management server and save in views.
+	if (this.auth_list == null)
+	    this.readAuthInfo();
+
+	// Sort the list of authorization objects.  Need at least two entries
+	// to require sorting.
+	if (auth_list.length > 1) {
+	    AuthAttrCompare comp = new AuthAttrCompare();
+	    Sort.sort(auth_list, comp);
+	}
+
+	// Create a vector of auth model entry objects, one for each auth
+	// in the master list.	Check if the current admin running the tool has
+	// the right to grant this right.  Check if the target user has this
+	// right already granted.
+	// If the auth right prefix changes and the
+	// next entry is not a header entry, create a dummy header entry for
+	// the new right (and any subsequent rights with the same prefix).
+	hdr_name = "";
+	numauths = auth_list.length;
+	entries = new Vector<AuthAttrModelEntry>(numauths);
+	Vector authNames = getUserAuths();
+
+	AuthAttrModelEntry prev_entry = null;
+	for (i = 0; i < numauths; i++) {
+	    auth_name = auth_list[i].getAuthName();
+
+	    // Create a new auth model entry object
+	    entry = new AuthAttrModelEntry(auth_list[i]);
+
+	    if (hasObject(auth_name)) {
+		if (hasWildAuth(auth_name) && prev_entry != null) {
+		    prev_entry.setHeader(true);
+		}
+	    }
+	    prev_entry = entry;
+
+	    // Process explicit header entry
+	    // if (auth_name.endsWith(".")) 		// Cannot grant header
+	    if (entry.isHeader()) {		// Cannot grant header
+		hdr_name = auth_name;
+		entries.addElement(entry);		// Add hdr entry to list
+		continue;				// and skip the rest...
+	    }
+
+	    // Check for and process implicit header entry
+	    j = auth_name.lastIndexOf('.');
+	    if (j > 0) {
+		str = auth_name.substring(0, (j + 1));
+		if (! (str.equals(hdr_name))) {
+		    hdr_name = str;			// Add dummy hdr entry
+		    entries.addElement(
+				new AuthAttrModelEntry(hdr_name, "", ""));
+		}
+	    }
+
+	    // All entries can be granted
+	    entry.setToBeGranted();
+
+	    if ((authNames != null) && (checkAuthName(authNames, auth_name)))
+		entry.grant();
+	    entries.addElement(entry);		// Add rights entry
+
+	}						// End of for loop
+
+	// Turn vector of auth model objects into an array
+	entrylist = new AuthAttrModelEntry[entries.size()];
+	entries.copyInto((Object [])entrylist);
+
+	// Return the list of model entries for presentation
+	return (entrylist);
+
+    }
+
+    /**
+     * Update the selected target user list of granted authorizations based
+     * upon the list of authorization model entries returned from the Rights
+     * tab dialog.  The existing list of authorizations will be deleted and
+     * a new list constructed.	Each authorization model entry which is marked
+     * granted will be included in the new authorization object.  The new
+     * user authorization attribute object is returned.
+     * <p>
+     * Additionally, if all rights (except the "grant"
+     * right) for a common set of rights (all rights with the same prefix)
+     * are granted, then replace the set with the "*" right with that same
+     * prefix; e.g., if all rights under "com.sun.usermgr.xxx" are granted,
+     * set the single right "com.sun.usermgr.*" instead.  This will collapse
+     * the granted rights into fewer entries.  Note the com.sun.usermgr.grant
+     * right is not included in the com.sun.usermgr.* right, so it will be
+     * set separately.
+     * <p>
+     * This method assumes it is processing the same auth model entry array
+     * that was previously returned by the getAuthEntries method; that is,
+     * the array of entries is in sorted order by auth right name.
+     *
+     * @param	auth_entries	Array of authorization model entry objects
+     *
+     * @return	The new user authorization attribute object for the targer user
+     *
+     */
+    public Vector<String> setAuthEntries(AuthAttrModelEntry [] auth_entries) {
+
+	String [] auth_names;
+	Vector<String> v;
+	String name;
+	int i, last_hdr;
+	boolean sw;
+
+	v = new Vector<String>();
+
+
+	// Walk through the authorization entries. When we encounter a header
+	// entry and it is granted, we set the "*" right (the entire common
+	// set of rights with the same prefix are granted) and do not set any
+	// of the specific rights.  The "grant" right is an exception; that is,
+	// it is included in the granted rights if it is granted independently
+	// of checking the header entry.
+	sw = true;
+	for (i = 0; i < auth_entries.length; i++) {
+	    name = auth_entries[i].getAuthName();
+
+	    // Process header entry
+	    if (auth_entries[i].isHeader()) {
+		if (auth_entries[i].isGranted()) {
+		    sw = false;
+
+		    for (int j = 0; j < i; j++) {
+			if (auth_entries[j].isGranted()) {
+			    if (auth_entries[i].getAuthName().startsWith(
+				auth_entries[j].getAuthName())) {
+				auth_entries[i].revoke();
+				break;
+			    }
+			}
+		    }
+		    if (auth_entries[i].isGranted()) {
+			if (name.endsWith(AuthAttrObj.SOLARIS_DOT)) {
+			    v.addElement(name.concat(AuthAttrObj.SOLARIS_ALL));
+			} else {
+			    v.addElement(name);
+			}
+		    }
+		} else {
+		    sw = true;				// Test each right
+		}
+		continue;
+	    }
+
+	    // Process rights entry
+	    if (auth_entries[i].isGranted()) {
+		if ((sw) || (name.endsWith(AuthAttrObj.SOLARIS_GRANT)))
+		    v.addElement(name);
+	    }
+	}						// End of for loop
+
+	ExtAttrObj new_auth = null;
+
+	// Return the new auth object.
+	return (v);
+
+    }
+
+    /**
+     * Check if this user account has been granted the specified
+     * authorization.
+     *
+     * @param An authorization name
+     *
+     */
+    public boolean checkAuthName(Vector authNames, String authStr) {
+
+	String authname = authStr;
+
+	if (authNames == null)
+	    return (false);
+	if (authNames.contains(authname))
+	    return true;
+
+	// try to find a wildcard match further up the tree
+	StringTokenizer tk = new StringTokenizer(authname,
+	    AuthAttrObj.SOLARIS_DOT);
+	String matchType;
+	int tokCount = tk.countTokens() -1;
+	if (tokCount < 1) {
+	    // not enough tokens; invalid authname?
+	    return false;
+	}
+
+	// Grant authorization does not match against "All"
+	// However, grant does match another grant further up the tree
+	if (authname.endsWith("." + AuthAttrObj.SOLARIS_GRANT))
+	    matchType = AuthAttrObj.SOLARIS_GRANT;
+	else
+	    matchType = AuthAttrObj.SOLARIS_ALL;
+
+	// walk the tree from the root, looking for implicit matches
+	String authPath = "";
+	for (int i = 0; i < tokCount; i++) {
+	    authPath = authPath.concat((String)tk.nextElement() +
+					AuthAttrObj.SOLARIS_DOT);
+	    if (authNames.contains(authPath.concat(matchType)))
+		return true;
+	}
+	return false;
+
+    }
+
+    private Vector<String> getUserAuths() {
+        String auths = userObj.getAuths();
+	Vector<String> userAuths = null;
+
+	if (auths != null) {
+	    String[] authList = userObj.getAuths().split(",");
+	    userAuths = new Vector<String>(authList.length);
+	    for (String auth : authList) {
+		userAuths.add(auth);
+	    }
+	}
+
+	return (userAuths);
+    }
+
+    private void updateAuths(List<String> auths) {
+        Vector<String> uAuths = getUserAuths();
+	if (uAuths == null || uAuths.size() == 0) {
+	    return;
+	}
+
+
+	for (String uAuth : uAuths) {
+	    int idx = uAuth.indexOf(AuthAttrObj.SOLARIS_SLASH);
+
+	    if (idx == -1) {
+		continue; // doesn't contain object name
+	    }
+	    // Contains object name
+	    String authStr = uAuth.substring(0, idx);
+
+	    for (int j = 0; j < auths.size(); j++) {
+		String auth = auths.get(j);
+		if (auth.equals(authStr)) {
+		    String nextauth = auths.get(j+1);
+		    String wildAuth = getWildAuth(authStr);
+
+		    if (nextauth.equals(wildAuth) == false) {
+			auths.add(j+1, wildAuth);
+		    }
+		    auths.add(j+2, uAuth);
+		}
+	    }
+	}
+    }
+
+    /*
+     * Translate the authname to authname
+     */
+    private String getWildAuth(String auth) {
+        return (auth + AuthAttrObj.SOLARIS_SLASH + AuthAttrObj.SOLARIS_ALL);
+    }
+
+    /**
+     * Check if the authname has the wildcard '*'
+     */
+    private boolean hasWildAuth(String auth) {
+        return (auth.endsWith(AuthAttrObj.SOLARIS_SLASH +
+		AuthAttrObj.SOLARIS_ALL));
+    }
+
+    /**
+     * Check if the authname is in the form: auth/<object>
+     */
+    private boolean hasObject(String auth) {
+	if (auth.indexOf(AuthAttrObj.SOLARIS_SLASH) == -1) {
+	    return (false);
+	} else {
+	    return (true);
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrModelEntry.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,323 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.lang.*;
+
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * The AuthAttrModelEntry class encapsulates a single authorization right
+ * header entry or grantable right entry.  This class is used to present
+ * the authorization rights in the User Manager Authorizations tab dialog.
+ * An array of instances of this class represent all the authorization rights
+ * in the management scope currently selected for User Manager.
+ * <p>
+ * The instance contains the name of the authorization right or header,
+ * a short description of the right used in the presentation, a reference
+ * to a help file or localization resource property file and message id
+ * used to present a detailed explanation of the right or set of rights,
+ * a boolean grant attribute, and a boolean check attribute.
+ * If the grant attribute is true, the authorization can be granted to the
+ * selected user; that is, it can be selected in the presentation and checked
+ * or unchecked.  If the check attribute is true, the user already has this
+ * authorization granted to them.
+ *
+ */
+
+public class AuthAttrModelEntry {
+
+    // ========================================================================
+    //
+    // Private class attributes
+    //
+    // ========================================================================
+
+    private String  name;		// Authorization name
+    private String  desc;		// Authorization short description
+    private String  help;		// Authorization help file or message id
+    private boolean grant;		// True if right can be granted
+    private boolean check;		// True if right has been granted
+    private boolean header;		// True if is a header
+    private boolean visible = true;	// True is visible
+
+    // ========================================================================
+    //
+    // Constructors
+    //
+    // ========================================================================
+
+    /**
+     * This constructor creates a new authorization right model entry object
+     * from an AuthAttrObj object.
+     *
+     * @param	authAttr    The AuthAttrObj source object.
+     *
+     */
+    public AuthAttrModelEntry(AuthAttrObj authAttr) {
+
+	this.name = authAttr.getAuthName();
+	this.desc = authAttr.getShortDesc();
+	this.help = authAttr.getLongDescId();
+	this.grant = false;
+	this.check = false;
+	this.header = hasHeader();
+    }
+
+    /**
+     * This constructor creates a new authorization right model entry object
+     * from its parameters.
+     *
+     * @param	authName    The authorization name.
+     * @param	authDesc    The authorization short description.
+     * @param	authHelp    The authorization help file or long message file+id
+     *
+     */
+    public AuthAttrModelEntry(String authName, String authDesc,
+	String authHelp) {
+
+	this.name = authName;
+	this.desc = authDesc;
+	this.help = authHelp;
+	this.grant = false;
+	this.check = false;
+	this.header = hasHeader();
+
+    }
+    // ========================================================================
+    //
+    // Public methods
+    //
+    // ========================================================================
+
+    /**
+     * Return the authorizatino name.  If the name ends with a period, it is
+     * an authorization set header name; otherwise, it is an authorization
+     * grantable right name.
+     *
+     * @return	The name of the authorization
+     *
+     */
+    public String getAuthName() {
+
+	return (this.name);
+
+    }
+
+    /**
+     * Return the authorization name.
+     *
+     * @return The authorization name
+     *
+     */
+    public String getName() {
+
+	int i = name.indexOf(AuthAttrObj.SOLARIS_SLASH);
+	String nameStr;
+
+	if (i >= 0) {
+	    nameStr = name.substring(i+1);
+	    if (nameStr.equals(AuthAttrObj.SOLARIS_ALL)) {
+		nameStr = "All";
+	    }
+	} else {
+	    nameStr = name;
+	}
+	return (nameStr);
+
+    }
+
+    /**
+     * Return the short description of the authorization.  This description
+     * is used in the presentation of the authorization in the User Manager
+     * Rights tab dialog.
+     *
+     * @return	The short description of the authorization
+     *
+     */
+    public String getDesc() {
+
+	return (this.desc);
+
+    }
+
+    /**
+     * Return the help file name or long description file name and message
+     * identifier for the authorization.  If the value returned ends in
+     * "html" or "htm", it is a help file relative path name.  Add the
+     * path name to the management installation base directory path to get
+     * the full path to the help file, then generate a "file" URL from this
+     * path for HTML help file renderers.  If the value contains a "+"
+     * character, it is a long message file relative path name and messaged
+     * identifier combination.	Add the relative path to the installation
+     * base directory to get the full path name to the resource bundle
+     * property file.  Use the string after the plus sign as the message
+     * key in that resource file.
+     *
+     * @return	The help description file name URL or file name and message id
+     *
+     */
+    public String getHelp() {
+
+	return (this.help);
+
+    }
+
+    /**
+     * Determines if this authorization is a special authorization header entry.
+     *
+     * @return	True if this authorization entry is for a header entry.
+     *
+     */
+    public boolean isHeader() {
+
+	return (header);
+
+    }
+
+    /**
+     * Determines if this authorization is a special authorization header entry.
+     *
+     * @return	True if this authorization entry is for a header entry.
+     *
+     */
+    public boolean hasHeader() {
+
+	return (name.endsWith(AuthAttrObj.SOLARIS_DOT));
+
+    }
+
+    /**
+     * Determines if this authorization is a special authorization header entry.
+     *
+     * @return	True if this authorization entry is for a header entry.
+     *
+     */
+    public void setHeader(boolean val) {
+	header = val;
+    }
+
+    /**
+     * Determines if this authorization can be granted by the administrator
+     * currently running the User Manager tool.  If the administrator can
+     * grant this authorization right to the selected user, a true value
+     * is returned.  If the authorization is a header or cannot be granted,
+     * a false value is returned.
+     *
+     * @return	True if the authorization can be granted
+     *
+     */
+    public boolean canBeGranted() {
+
+	return (this.grant);
+
+    }
+
+    /**
+     * Determines if this authorization is currently granted to the selected
+     * target user in the User Manager tool.  If the user has this authorization
+     * right, a true value is returned; otherwise, a false value is returned.
+     *
+     * @return	True if the user is granted this authorization right
+     *
+     */
+    public boolean isGranted() {
+
+	return (this.check);
+
+    }
+
+    /**
+     * Grant the authorization right to the selected target user in the
+     * User Manager tool.  The caller should first test if the authorization
+     * is grantable by calling the canBeGranted method.
+     *
+     */
+    public void grant() {
+
+	this.check = true;
+
+    }
+
+    /**
+     * Revoke the authorization right for the selected target user in the
+     * User Manager tool.  The caller should first test if the authorization
+     * is revokable by calling the canBeGranted method.  The administrator
+     * must be capable of granting the right in order to revoke it.
+     *
+     */
+    public void revoke() {
+
+	this.check = false;
+
+    }
+
+    /**
+     * Set the ability to grant or revoke the authorization right.
+     * The administrator running the User Manager tool must have the grant
+     * right controlling this authorization.
+     *
+     */
+    public void setToBeGranted() {
+
+	this.grant = true;
+
+    }
+
+    public boolean hasObject() {
+	if (name.indexOf(AuthAttrObj.SOLARIS_SLASH) == -1) {
+	    return (false);
+	} else {
+	    return (true);
+	}
+    }
+
+    /**
+     * Set the long descriptions for the authorization.
+     * Any existing log descriptions are replaced.
+     *
+     * @param	An array of long descriptions
+     *
+     */
+    public boolean isVisible() {
+
+	return (visible);
+    }
+
+    /**
+     * Set the long descriptions for the authorization.
+     * Any existing log descriptions are replaced.
+     *
+     * @param	An array of long descriptions
+     *
+     */
+    public void setVisible(boolean visibility) {
+
+	visible = visibility;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrObj.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,455 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.lang.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * Description:
+ * The AuthAttrObj class encapsulates the set of authorizations currently
+ * set for the specified user.
+ *
+ * @return    none.
+ */
+
+public class AuthAttrObj extends ExtAttrObj implements Cloneable {
+
+    // Private attributes back stopped by persistent storage
+    private String authName = null;	// The authorization name
+    private String [] shortDesc = null; // Short description (32 chars)
+    private String [] longDesc = null;	// Long description, not localized
+    private boolean visible = true;
+
+    // The following is the list of attribute keys that are supported.
+
+    public static final String SOLARIS_AUTH_HELP = "help";
+    public static final String SOLARIS_ALL = "*";
+    public static final String SOLARIS_DOT = ".";
+    public static final String SOLARIS_GRANT = "grant";
+    public static final String SOLARIS_SLASH = "/";
+
+
+    /**
+     *	Null constructor.
+     *
+     */
+    public AuthAttrObj() {
+
+	super();
+
+    }
+
+    /**
+     * This constructor takes the authorization name.
+     *
+     */
+    public AuthAttrObj(String authName) {
+
+	super();
+	this.authName = authName;
+
+    }
+
+
+    // Public methods
+
+    /**
+     * Return a copy of this object.
+     *
+     * @return	A new copy of this object
+     *
+     */
+    public Object clone() {
+
+	AuthAttrObj newobj = new AuthAttrObj(this.authName);
+	newobj.setShortDesc(this.shortDesc);
+	newobj.setLongDesc(this.longDesc);
+
+	super.clone(newobj);
+	return (newobj);
+
+    }
+
+    /**
+     * Check if this instance matches another AuthAttrObj instance.
+     * The other instance matches this instance if it has the
+     * same authorization name.
+     *
+     * @param  otherAttr  The other AuthAttrObj instance
+     *
+     * @returnTrue if the other instance matches this one
+     *
+     */
+    public boolean matches(AuthAttrObj otherAttr) {
+
+	boolean bool = false;
+	try {
+	    if (this.authName.equals(otherAttr.getAuthName()))
+		bool = true;
+	} catch (Exception ex) {
+	}
+	return (bool);
+
+    }
+
+    /**
+     * Return the authorization name.
+     *
+     * @return The authorization name
+     *
+     */
+    public String getAuthName() {
+
+	return (this.authName);
+
+    }
+
+    /**
+     * Return the authorization name.
+     *
+     * @return The authorization name
+     *
+     */
+    public String getName() {
+
+	int i = authName.indexOf(SOLARIS_SLASH);
+	String nameStr;
+
+	if (i >= 0) {
+	    nameStr = authName.substring(i+1);
+	    if (nameStr.equals(SOLARIS_ALL)) {
+		nameStr = "All";
+	    }
+	} else {
+	    nameStr = authName;
+	}
+
+	return (nameStr);
+
+    }
+
+    /**
+     * Set the authorization name.
+     *
+     * @param	The authorization name
+     *
+     */
+    public void setAuthName(String authName) {
+
+	this.authName = authName;
+
+    }
+
+    /**
+     * Return a copy of this object.
+     *
+     * @return	A new copy of this object
+     *
+     */
+    public String getShortDesc() {
+
+	if (this.shortDesc == null)
+	    return (null);
+	else
+	    return (this.shortDesc[0]);
+
+    }
+
+    /**
+     * Return an array of short descriptions for the authorization.
+     *
+     * @return	An array of short descriptions
+     *
+     */
+    public String [] getShortDescs() {
+
+	if (this.shortDesc == null)
+	    return (null);
+	else
+	    return (this.shortDesc);
+
+    }
+
+    /**
+     * Set the short description for this authorizations.
+     * Any existing descriptions are replaced.
+     *
+     * @param	The short description
+     *
+     */
+    public void setShortDesc(String shortDesc) {
+
+	if (this.shortDesc == null)
+	    this.shortDesc = new String [1];
+	this.shortDesc[0] = shortDesc;
+
+    }
+
+    /**
+     * Set an array of short descriptions for the authorization.
+     * Any existing descriptions are replaced.
+     *
+     * @param	The authorization name
+     *
+     */
+    public void setShortDesc(String [] shortDesc) {
+
+	this.shortDesc = shortDesc;
+
+    }
+
+    /**
+     * Return a localized short description.
+     *
+     * @return	A localized short description
+     *
+     */
+    public String getShortDesc(Locale locale) {
+
+	if (this.shortDesc == null)
+	    return null;
+	else
+	    return (this.shortDesc[0]);
+
+    }
+
+    /**
+     * Return the relative pathname of the authorization help file
+     * on the management server.
+     *
+     * @return	A help file pathname
+     *
+     */
+    public String getHelpFileName() {
+
+	Vector v = this.getAttribute(SOLARIS_AUTH_HELP);
+	if ((v != null) && (v.size() > 0))
+	    return ((String) v.elementAt(0));
+	else
+	    return (null);
+    }
+
+    /**
+     * Set the relative pathname of the authorization help file
+     * on the management server.  Any existing help file pathnames
+     * are replaced.
+     *
+     * @param	A help file pathname
+     *
+     */
+    public void setHelpFileName(String helpFile) {
+
+	this.setAttribute(SOLARIS_AUTH_HELP, helpFile);
+
+    }
+
+    /**
+    /**
+     * Return the relative pathname of the authorization help file
+     * on the management server.
+    /**
+     * Return the relative pathname of the authorization help file
+     * on the management server.
+     *
+     * @return	A help file pathname
+     *
+     */
+    public String getLongDescId() {
+
+	Vector v = this.getAttribute(SOLARIS_AUTH_HELP);
+	if ((v != null) && (v.size() > 0))
+	    return ((String) v.elementAt(0));
+	else
+	    return (null);
+    }
+
+    /**
+     * Return the relative pathnames of the authorization help files
+     * on the management server.
+     *
+     * @return	An array of help file pathnames
+     *
+     *
+     */
+    public String [] getLongDescIds() {
+
+	return (this.getAttributeArray(SOLARIS_AUTH_HELP));
+
+    }
+
+    /**
+     * Return the relative pathnames of the authorization help files
+     * on the management server.
+     *
+     * @return	A vector of help file pathnames
+     *
+     */
+    public Vector getLongDescIdsVector() {
+
+	return (this.getAttribute(SOLARIS_AUTH_HELP));
+
+    }
+
+    /**
+     * Set the relative pathname of the authorization help file
+     * on the management server.  Any existing help file pathnames
+     * are replaced.
+     *
+     * @param	A help file pathname
+     *
+     */
+    public void setLongDescId(String longDescHelp) {
+
+	this.setAttribute(SOLARIS_AUTH_HELP, longDescHelp);
+
+    }
+
+    /**
+     * Set the relative pathnames of the authorization help files
+     * on the management server.  Any existing help file pathnames
+     * are replaced.
+     *
+     * @param	An array of help file pathnames
+     *
+     */
+    public void setLongDescId(String [] longDescIdArray) {
+
+	this.setAttribute(SOLARIS_AUTH_HELP, longDescIdArray);
+
+    }
+
+    /**
+     * Set the relative pathnames of the authorization help files
+     * on the management server.  Any existing help file pathnames
+     * are replaced.
+     *
+     * @param	A vector of help file pathnames
+     *
+     */
+    public void setLongDescIdVector(Vector names) {
+
+	this.setAttribute(SOLARIS_AUTH_HELP, names);
+
+    }
+
+    /**
+     * Return a long description for the authorization.
+     *
+     * @return	A long description
+     *
+     */
+    public String getLongDesc() {
+
+	if (this.longDesc == null)
+	    return null;
+	else
+	    return (this.longDesc[0]);
+
+    }
+
+    /**
+     * Return an array of long descriptions for the authorization.
+     *
+     * @return	An array of long descriptions
+     *
+     */
+    public String [] getLongDescs() {
+
+	if (this.longDesc == null)
+	    return null;
+	else
+	    return (this.longDesc);
+
+    }
+
+    /**
+     * Return a localized long description for the authorization.
+     *
+     * @return	A localized long description
+     *
+     */
+    public String getLongDesc(Locale locale) {
+
+	if (this.longDesc == null)
+	    return null;
+	else
+	    return (this.longDesc[0]);
+
+    }
+
+    /**
+     * @param	A long description
+     *
+     */
+    public void setLongDesc(String longDesc) {
+
+	if (this.longDesc == null)
+	    this.longDesc = new String[1];
+	this.longDesc[0] = longDesc;
+
+    }
+
+    /**
+     * Set the long descriptions for the authorization.
+     * Any existing log descriptions are replaced.
+     *
+     * @param	An array of long descriptions
+     *
+     */
+    public void setLongDesc(String [] longDesc) {
+
+	this.longDesc = longDesc;
+
+    }
+
+    /**
+     * Set the long descriptions for the authorization.
+     * Any existing log descriptions are replaced.
+     *
+     * @param	An array of long descriptions
+     *
+     */
+    public boolean isVisible() {
+
+	return (visible);
+    }
+
+    /**
+     * Set the long descriptions for the authorization.
+     * Any existing log descriptions are replaced.
+     *
+     * @param	An array of long descriptions
+     *
+     */
+    public void setVisible(boolean visibility) {
+
+	visible = visibility;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthsPanel.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,414 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.tree.*;
+
+import java.util.List;
+import java.util.*;
+import java.io.*;
+import java.net.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * Authorization Settings Panel
+ */
+
+public class AuthsPanel extends JPanel {
+
+    private UserManagedObject userObj = null;
+    private UserMgrPanelDescriptor panelDesc = null;
+
+    private AuthAttrMgmt authAttrMgmt;
+    private AuthAttrModelEntry[] authArr;
+    private DblTreeNode root;
+
+    public static SelPanel authPanel;
+    private DblTreeNode [] authNode;
+
+    private boolean isNew;
+    private boolean viewNames = false;
+
+    /**
+     * Constructs a panel to contain authorizations properties for the
+     * right object.
+     *
+     */
+    public AuthsPanel(UserMgrPanelDescriptor panelDesc,
+		UserManagedObject userObj) {
+	super();
+	this.panelDesc = panelDesc;
+        this.userObj = userObj;
+	isNew = userObj.isNewUser();
+
+	createGui();
+	loadAuths();
+
+    } // constructor
+
+    /**
+     * Method for creating GUI
+     */
+    private void createGui() {
+
+	// set the panel layout
+	GridBagLayout gridbag = new GridBagLayout();
+	GridBagConstraints gbc = new GridBagConstraints();
+	this.setLayout(gridbag);
+
+	authPanel = new SelPanel("usermgr.advanced.auths.available",
+		"usermgr.advanced.auths.granted");
+
+	authPanel.srcTree.setCellRenderer(new AuthRenderer(this));
+	authPanel.dstTree.setCellRenderer(new AuthRenderer(this));
+
+	Constraints.constrain(this, authPanel,
+	    0, 0, 1, 1, gbc.BOTH, gbc.CENTER, 1.0, 1, 10, 10, 10, 10);
+    } // end createGui
+
+    public void loadUserAuths() {
+	authPanel.resetAll();
+
+	if (isNew == false) {
+	    authAttrMgmt = new AuthAttrMgmt(panelDesc, userObj);
+	    authArr = authAttrMgmt.getAuthEntries();
+	    setAuthArr(authArr);
+        }
+
+	if (authArr == null) {
+	    return;
+	}
+
+
+	// At this point, everything is in the left tree, with
+	// all of the branches collaped.
+
+	for (int i = 0; i < authArr.length; i++) {
+	    if (authArr[i].isHeader()) {
+
+		// Expand all the headers
+
+		TreePath nodepath = new TreePath(authNode[i].getPath());
+		authPanel.srcTree.expandPath(nodepath);
+	    } else {
+
+		// Move all the granted auths leaves to the right
+		if (isNew == false && authArr[i].isGranted()) {
+		    authPanel.initLeaf(authPanel.srcTree, authPanel.dstTree,
+		    authNode[i]);
+		}
+	    }
+	}
+
+	authPanel.srcTree.setRootVisible(false);
+	authPanel.setInitSelection();
+    }
+
+    /**
+     * Load the Source and Destination trees for authorizations excluded and
+     * included lists.
+     */
+    private void loadAuths() {
+
+	// Reset the data models. So old data is discarded
+	authPanel.resetModels();
+
+	DefaultTreeModel srcModel =
+	    (DefaultTreeModel)authPanel.srcTree.getModel();
+	root = (DblTreeNode)srcModel.getRoot();
+	int topCount = 0;
+	int headerCount = 0;
+
+	// First time through use a dummy profile
+	authAttrMgmt = new AuthAttrMgmt(panelDesc, userObj);
+
+	authArr = authAttrMgmt.getAuthEntries();
+
+	int [] headerList = new int[authArr.length];
+	authNode = new DblTreeNode[authArr.length];
+
+	for (int i = 0; i < authArr.length; i++) {
+	    AuthTreeNode authObject = new AuthTreeNode(authArr[i], i);
+	    authNode[i] = new DblTreeNode((Object)authObject);
+
+	    String nodeName = authArr[i].getAuthName();
+	    if (authArr[i].isHeader()) {
+		// Add subheaders to headers
+
+		boolean foundHeader = false;
+		int	headerIndex = 0;
+
+		for (int j = 0; j < headerCount; j++) {
+		    int k = headerList[j];
+		    AuthTreeNode  headerNode =
+			(AuthTreeNode)authNode[k].getUserObject();
+		    String headerName = headerNode.toString();
+		    if (nodeName.startsWith(headerName)) {
+			foundHeader = true;
+			headerIndex = k;
+			// loop for closest match
+		    }
+		}
+
+		if (foundHeader) {
+		    authNode[headerIndex].add(authNode[i]);
+		} else {
+		    srcModel.insertNodeInto(authNode[i], root, topCount++);
+		    TreePath nodepath = new TreePath(authNode[i].getPath());
+		    authPanel.srcTree.scrollPathToVisible(nodepath);
+		}
+		// add header to header list
+		headerList[headerCount++] = i;
+
+	    } else { // Add the leaves to the headers
+
+		// Set auth's treenode disabled to
+		// indicate the auth "can not be granted" to another user
+		// (No auths leaves could ever have child nodes)
+
+		if (authArr[i].canBeGranted() == false) {
+		    authNode[i].setEnabled(false);
+		}
+		if (headerCount > 0) {
+		    for (int j = headerCount - 1; j >= 0; j--) {
+			AuthTreeNode  headerNode = (AuthTreeNode)
+			    authNode[headerList[j]].getUserObject();
+			String headerName = headerNode.toString();
+			if (nodeName.startsWith(headerName)) {
+			    authNode[headerList[j]].add(authNode[i]);
+			    break;
+			}
+		    }
+		} else {
+		    srcModel.insertNodeInto(authNode[i], root, topCount++);
+		}
+	    }
+	}
+
+	loadUserAuths();
+
+    } // end loadAuths
+
+
+    public void setAuthArr(AuthAttrModelEntry[] arr) {
+	authArr = arr;
+    }
+
+    public AuthAttrModelEntry[] getAuthArr() {
+	return authArr;
+    }
+
+    public boolean getViewNames() {
+	return viewNames;
+    }
+
+
+    public void getChecks() {
+
+	AuthAttrModelEntry[] authEntryArr = getAuthArr();
+
+	if (authNode == null) {
+	    return;
+        }
+
+	for (int i = 0; i < authNode.length; i++) {
+	    if (authEntryArr[i].isHeader()) {
+		authEntryArr[i].grant();
+		continue;
+	    }
+
+	    // root is in the excluded tree.
+	    if (authNode[i].getRoot().equals(root))
+		authEntryArr[i].revoke();
+	    else
+		authEntryArr[i].grant();
+	}
+
+	DblTreeNode node;
+	Enumeration inclAuths = root.depthFirstEnumeration();
+	while (inclAuths.hasMoreElements()) {
+	    node = (DblTreeNode)inclAuths.nextElement();
+	    if (node.isRoot())
+		continue;
+
+	    AuthTreeNode authtreenode = (AuthTreeNode)node.getUserObject();
+	    int i = authtreenode.getSubscript();
+	    if (authEntryArr[i].isHeader())
+		authEntryArr[i].revoke();
+	}
+
+	setAuthArr(authEntryArr);
+
+    } // end getChecks
+
+    /**
+     * Get the authorizations assigned to the selected user/role.
+     */
+    public Vector<String> getAssignedAuths() {
+	getChecks();
+        Vector<String> vAuths = authAttrMgmt.setAuthEntries(getAuthArr());
+
+	return vAuths;
+    }
+
+    /**
+     * Get a list of available authorizations that can be assigned
+     * to selected user/role.
+     */
+    private String[] getAvailableAuths() {
+	List<String> auths = panelDesc.getAuths();
+        int authsize =  auths.size();
+	String[] authList = new String[authsize];
+
+	for (int i = 0; i < authsize; i++) {
+	    authList[i] = auths.get(i);
+	}
+    	return (authList);
+    }
+
+    /**
+     * Refresh authorizations for the new user.
+     */
+    public void setUser(UserManagedObject userObj) {
+    	this.userObj = userObj;
+	loadAuths();
+    }
+
+    public UserManagedObject updateUser() {
+        Vector<String> vAuths = getAssignedAuths();
+	String authStr;
+
+	if (vAuths.size() > 0) {
+		authStr = vAuths.elementAt(0);
+	} else {
+		authStr = "";
+	}
+
+	for (int i = 1; i < vAuths.size(); i++) {
+	    authStr = authStr.concat(",");
+	    authStr = authStr.concat(vAuths.elementAt(i));
+        }
+
+	userObj.getAuthsProperty().setValue(authStr);
+
+	return (userObj);
+    }
+
+} // end AuthsPanel
+
+class AuthTreeNode {
+
+    String name = null;
+    AuthAttrModelEntry authModel = null;
+    boolean enabled = true;
+    int subscript;
+
+    public AuthTreeNode(AuthAttrModelEntry authModel, int subscript) {
+	name = authModel.getName();
+	enabled = authModel.canBeGranted();
+	this.authModel = authModel;
+	this.subscript = subscript;
+    }
+
+    public String getDesc() {
+	return authModel.getDesc();
+    }
+
+    public String toString() {
+	return name;
+    }
+
+    public AuthAttrModelEntry getAuthModel() {
+	return authModel;
+    }
+
+    public boolean isEnabled() {
+	return enabled;
+    }
+
+    public int getSubscript() {
+	return this.subscript;
+    }
+
+}
+
+class AuthRenderer extends DefaultTreeCellRenderer {
+
+    private boolean selected;
+    static AuthsPanel authsPanel;
+
+    public AuthRenderer(AuthsPanel authsPanel) {
+	this.authsPanel = authsPanel;
+	setClosedIcon(null);
+	setOpenIcon(null);
+    }
+
+    public Component getTreeCellRendererComponent(
+	JTree tree,
+	Object value,
+	boolean selected,
+	boolean expanded,
+	boolean leaf,
+	int row,
+	boolean hasFocus) {
+
+	AuthTreeNode authdef = null;
+	FocusEvent e = null;
+
+	this.selected = selected;
+
+	DefaultTreeCellRenderer cr =
+	    (DefaultTreeCellRenderer)tree.getCellRenderer();
+
+	DblTreeNode node = (DblTreeNode)value;
+	// authdef = (AuthTreeNode)node.getUserObject();
+
+	if (node.getParent() == null) {
+	    setText("All Authorizations");
+	} else  if (node.getUserObject() instanceof AuthTreeNode) {
+	    authdef = (AuthTreeNode)node.getUserObject();
+	    setText(authdef.toString());
+
+	}
+
+	super.getTreeCellRendererComponent(tree, value,
+		selected, expanded, leaf, row, hasFocus);
+
+	return this;
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthsSettings.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,79 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+
+/**
+ * Implements Authorization Settings in the Advanced
+ * Settings
+ */
+public class AuthsSettings extends AdvancedSettings {
+
+    private static final String NAME =
+    	Finder.getString("usermgr.advanced.auths");
+    private static final Icon ICON = Finder.getIcon(
+	"images/user-24.png");
+
+    private UserMgrPanelDescriptor panelDesc = null;
+    private UserManagedObject userObj = null;
+    private AuthsPanel panel = null;
+
+    public AuthsSettings() {
+	super(NAME, ICON);
+    }
+
+    public void setUser(UserManagedObject userObj) {
+	if (panel == null) {
+		panel = new AuthsPanel(panelDesc, userObj);
+	}
+	panel.setUser(userObj);
+	getProperty().update(userObj.getAuths(), false);
+    }
+
+    public void updateUser() {
+	userObj = panel.updateUser();
+	getProperty().setValue(userObj.getAuths());
+    }
+
+    public boolean isChanged() {
+        if (userObj != null) {
+	    return (userObj.getAuthsProperty().isChanged());
+	} else {
+	    return false;
+	}
+    }
+
+    public void init(UserMgrPanelDescriptor panelDesc) {
+	this.panelDesc = panelDesc;
+    }
+
+    public JPanel getPanel() {
+    	return panel;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Compare.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * Compare: an interface to enable users to define the result of
+ *	    a comparison of two objects.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+public interface Compare {
+
+    /**
+     * doCompare
+     *
+     * @param  obj1 first object to compare.
+     * @param  obj2 second object to compare.
+     * @return -1 if obj1 < obj2, 0 if obj1 == obj2, 1 if obj1 > obj2.
+     */
+    public int doCompare(Object obj1, Object obj2);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Constraints.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,121 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.applet.*;
+import java.awt.*;
+import java.lang.*;
+
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * A general utility class to make it easy to apply GridBagConstraints
+ * to GridBagLayout.
+ * Code lifted from "Java in a Nutshell", O'Reilly & Associated, Inc.
+ * and wrapped in a final class.
+ */
+public final class Constraints {
+
+    /**
+     * This is the main constrain() method.  It has arguments for
+     * all constraints.
+     */
+    public static void constrain(
+	    Container	container,
+	    Component	component,
+	    int 	gridx,
+	    int 	gridy,
+	    int 	gridwidth,
+	    int 	gridheight,
+	    int 	fill,
+	    int 	anchor,
+	    double	weightx,
+	    double	weighty,
+	    int 	top,
+	    int 	left,
+	    int 	bottom,
+	    int 	right)
+    {
+	GridBagConstraints gbc = new GridBagConstraints();
+	gbc.gridx = gridx;
+	gbc.gridy = gridy;
+	gbc.gridwidth = gridwidth;
+	gbc.gridheight = gridheight;
+	gbc.fill = fill;
+	gbc.anchor = anchor;
+	gbc.weightx = weightx;
+	gbc.weighty = weighty;
+
+	if (top+bottom+left+right > 0)
+	    gbc.insets = new Insets(top, left, bottom, right);
+
+	((GridBagLayout)container.getLayout()).setConstraints(component, gbc);
+	container.add(component);
+    }
+
+
+    /**
+     * This version of constrain() specifies the position of a component
+     * that does not grow and does not have margins.
+     */
+    public static void constrain(
+	    Container	container,
+	    Component	component,
+	    int 	gridx,
+	    int 	gridy,
+	    int 	gridwidth,
+	    int 	gridheight)
+    {
+	constrain(container, component,
+	    gridx, gridy, gridwidth, gridheight,
+	    GridBagConstraints.NONE, GridBagConstraints.NORTHWEST,
+	    0.0, 0.0, 0, 0, 0, 0);
+    }
+
+
+    /**
+     * This version of constrain() specifies the position of a component
+     * that does not grow but does have margins.
+     */
+    public static void constrain(
+	    Container	container,
+	    Component	component,
+	    int 	gridx,
+	    int 	gridy,
+	    int 	gridwidth,
+	    int 	gridheight,
+	    int 	top,
+	    int 	left,
+	    int 	bottom,
+	    int 	right)
+    {
+	constrain(container, component,
+	    gridx, gridy, gridwidth, gridheight,
+	    GridBagConstraints.NONE, GridBagConstraints.NORTHWEST,
+	    0.0, 0.0, top, left, bottom, right);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DblTreeNode.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,130 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import javax.swing.tree.*;
+
+/**
+ * SMC code adapted for Visual Panels
+ */
+public class DblTreeNode extends DefaultMutableTreeNode implements Comparable {
+
+    boolean enabled = true;
+    boolean cyclic = false;
+    boolean conflict = false;
+
+    /**
+     * The comparableObject is used when comparing two
+     * DblTreeNode objects. By default the String
+     * representation (toString()) is used when comparing
+     * DblTreeNode objects. This may not always give the
+     * desired ordering when displaying nodes in a list. To overcome this
+     * when the comparableObject is not null
+     * the String representation of the
+     * comparableObject is used. This could be as simple as an
+     * Integer.
+     */
+    private Object comparableObject;
+
+    public DblTreeNode() {
+	super();
+    }
+
+    public DblTreeNode(Object object) {
+	super(object);
+    }
+
+    public DblTreeNode(String string) {
+	super(string);
+    }
+
+    public boolean isEnabled() {
+	return enabled;
+    }
+
+    public void setEnabled(boolean flag) {
+	enabled = flag;
+    }
+
+    public boolean isCyclic() {
+	return cyclic;
+    }
+
+    public void setCyclic(boolean flag) {
+	cyclic = flag;
+    }
+
+    public boolean isConflict() {
+	return conflict;
+    }
+
+    public void setConflict(boolean flag) {
+	conflict = flag;
+    }
+
+    /**
+     * Set the <code>comparableObject</code> which will be used by
+     * the <code>compareTo()</code> method. Use <code>null</code> to
+     * use <code>this</code> object (default).
+     *
+     * @param comparableObject
+     *	Object used by <code>compareTo()</code>
+     */
+    public void setComparableObject(Object comparableObject) {
+	this.comparableObject = comparableObject;
+    }
+
+    /**
+     * Get the <code>comparableObject</code> which will be used by
+     * the <code>compareTo()</code> method. This method never returns
+     * <code>null</code>. If the <code>comparableObject</code> is set to
+     * <code>null</code> by <code>setComparableObject(null)</code> this
+     * method returns <code>this</code>.
+     *
+     * @return
+     *	Object used by <code>compareTo()</code>
+     */
+    public Object getComparableObject() {
+	if (comparableObject == null) {
+	    return this;
+	} else {
+	    return comparableObject;
+	}
+    }
+
+    public int compareTo(Object object) {
+	String string = getComparableObject().toString();
+
+	if (object instanceof DblTreeNode) {
+	    DblTreeNode other = (DblTreeNode) object;
+	    return string.compareTo(other.getComparableObject().toString());
+	} else {
+	    return string.compareTo(object.toString());
+	}
+    }
+}
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DeleteUserAction.java	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DeleteUserAction.java	Fri Apr 27 00:52:26 2012 -0400
@@ -25,15 +25,22 @@
 
 package com.oracle.solaris.vp.panels.usermgr.client.swing;
 
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
 import java.util.List;
 import javax.swing.JOptionPane;
 import com.oracle.solaris.vp.panel.common.action.*;
 import com.oracle.solaris.vp.panel.common.control.Control;
 import com.oracle.solaris.vp.panel.swing.action.DeleteManagedObjectAction;
 import com.oracle.solaris.vp.panel.swing.control.SwingControl;
+import com.oracle.solaris.vp.util.misc.*;
 import com.oracle.solaris.vp.util.misc.finder.Finder;
 import com.oracle.solaris.vp.util.swing.GUIUtil;
 
+/**
+ * Delete a user or role
+ */
 @SuppressWarnings({"serial"})
 public class DeleteUserAction extends DeleteManagedObjectAction
     <UserManagedObject, UserManagedObject, List<UserManagedObject>> {
@@ -57,6 +64,10 @@
 
     public DeleteUserAction(SwingControl control) {
 	super(DELETE_TEXT, null, control);
+        ActionString actStr = new ActionString(
+	    "usermgr.action.delete.button");
+	putValue(Action.NAME, actStr.getString());
+	putValue(Action.MNEMONIC_KEY, actStr.getMnemonic());
 	this.control = control;
     }
 
@@ -71,17 +82,24 @@
 	if (selection.isEmpty()) {
 	    throw new ActionAbortedException();
 	}
+	UserMgrPanelDescriptor descriptor = (UserMgrPanelDescriptor)
+	    control.getPanelDescriptor();
 
-	String message = Finder.getString("usermgr.action.delete.confirm",
-					  selection.get(0).getName());
+	String message = Finder.getString("usermgr.action.delete.confirm." +
+		descriptor.getTypeString(), selection.get(0).getName());
 
-	int response = GUIUtil.showConfirmation(
-	    getHasComponent().getComponent(), null, message,
-	    JOptionPane.YES_NO_OPTION);
+	JOptionPane pane = new JOptionPane(message,
+	    JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
+	 UserMgrUtils.removeIcons(pane);
+	 JDialog dialog = pane.createDialog(getHasComponent().getComponent(),
+		Finder.getString("usermgr.action.delete.title." +
+		descriptor.getTypeString()));
 
-	if (response != JOptionPane.YES_OPTION) {
+	dialog.setVisible(true);
+
+	if (!ObjectUtil.equals(pane.getValue(), JOptionPane.OK_OPTION)) {
 	    throw new ActionAbortedException();
-	}
+        }
 
 	return null;
     }
@@ -98,13 +116,14 @@
 	if (!selection.isEmpty()) {
 	    UserMgrPanelDescriptor descriptor = (UserMgrPanelDescriptor)
 		control.getPanelDescriptor();
-	    descriptor.deleteUserManagedObject(selection.get(0));
+	    descriptor.addToDeleteList(selection.get(0));
+	    descriptor.saveDeletedUsers();
 	    // If the running Control is a UserMgrControl for a just-deleted
 	    // service, reset the Control and navigate back to its parent
 	    Control child = control.getRunningChild();
-	    if (child instanceof UserMgrControl) {
+	    if (child instanceof UserMgrBasicControl) {
 		UserManagedObject umo =
-		    ((UserMgrControl)child).getUserManagedObject();
+		    ((UserMgrBasicControl)child).getUserManagedObject();
 
 		if (selection.contains(umo)) {
 		    child.doCancel();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTrees.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,282 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.tree.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.io.*;
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * DoubleTrees class implements an excluded and included tree
+ */
+public class DoubleTrees extends JPanel {
+
+    public final static Border emptyBorder10 = new EmptyBorder(10, 10, 10, 10);
+
+    public JTree srcTree;
+    public JTree dstTree;
+    public JButton addItem;
+    public JButton delItem;
+    public JButton addAllItem;
+    public JButton delAllItem;
+
+    public JPanel selPanel = this;
+
+    /**
+     * Constructor.
+     */
+    public DoubleTrees() {
+	String srcHeader = "excluded_tree_header";
+	String dstHeader = "included_tree_header";
+
+	makePanel(srcHeader, dstHeader);
+    }
+
+
+    public DoubleTrees(String srcHeader, String dstHeader) {
+	makePanel(srcHeader, dstHeader);
+    }
+
+    private void makePanel(JPanel panel, String srcHeader, String dstHeader) {
+	DoubleTreesLayout layout = new DoubleTreesLayout();
+	panel.setLayout(layout);
+
+	DoubleTreesConstraints constraints = new DoubleTreesConstraints();
+
+	// src label
+
+	JLabel srcLabel = new JLabel();
+	setUpLabel(srcLabel, srcHeader);
+
+	constraints.location = constraints.LEFT_LABEL;
+	constraints.insets = new Insets(5, 5, 5, 5);
+
+	layout.setConstraints(srcLabel, constraints);
+	panel.add(srcLabel);
+
+	// src tree
+
+	JScrollPane srcScroll = newTree();
+	srcTree = (JTree) srcScroll.getViewport().getView();
+
+	constraints.location = constraints.LEFT_SCROLLPANE;
+	constraints.insets = new Insets(5, 5, 5, 5);
+
+	layout.setConstraints(srcScroll, constraints);
+	panel.add(srcScroll);
+
+	srcLabel.setLabelFor(srcTree);
+
+	// buttons
+
+	JPanel buttonPanel = new JPanel();
+
+	Component spacer1 = Box.createVerticalStrut(5);
+	Component spacer2 = Box.createVerticalStrut(25);
+	Component spacer3 = Box.createVerticalStrut(5);
+
+	GridBagLayout buttonLayout = new GridBagLayout();
+	GridBagConstraints buttonConstraints = new GridBagConstraints();
+
+	buttonPanel.setLayout(buttonLayout);
+
+	addItem = new JButton();
+	addItem.setEnabled(false);
+	setUpButton(addItem, "usermgr.advanced.add_btn");
+
+	delItem = new JButton();
+	delItem.setEnabled(false);
+	setUpButton(delItem, "usermgr.advanced.remove_btn");
+
+	addAllItem = new JButton();
+	setUpButton(addAllItem, "usermgr.advanced.add_all_btn");
+
+	delAllItem = new JButton();
+	setUpButton(delAllItem, "usermgr.advanced.remove_all_btn");
+
+	buttonConstraints.gridx = 0;
+	buttonConstraints.gridy = buttonConstraints.RELATIVE;
+	buttonConstraints.gridwidth = 1;
+	buttonConstraints.gridheight = 1;
+	buttonConstraints.weightx = 0.0;
+	buttonConstraints.weighty = 0.0;
+	buttonConstraints.fill = buttonConstraints.HORIZONTAL;
+	buttonConstraints.anchor = buttonConstraints.CENTER;
+
+	buttonPanel.add(addItem, buttonConstraints);
+	buttonPanel.add(spacer1, buttonConstraints);
+	buttonPanel.add(delItem, buttonConstraints);
+	buttonPanel.add(spacer2, buttonConstraints);
+	buttonPanel.add(addAllItem, buttonConstraints);
+	buttonPanel.add(spacer3, buttonConstraints);
+	buttonPanel.add(delAllItem, buttonConstraints);
+
+	constraints.location = constraints.BUTTONS;
+
+	layout.setConstraints(buttonPanel, constraints);
+	panel.add(buttonPanel);
+
+	// dst label
+
+	JLabel dstLabel = new JLabel();
+	setUpLabel(dstLabel, dstHeader);
+
+	constraints.location = constraints.RIGHT_LABEL;
+	constraints.insets = new Insets(5, 5, 5, 5);
+
+	layout.setConstraints(dstLabel, constraints);
+	panel.add(dstLabel);
+
+	// dst tree
+
+	JScrollPane dstScroll = newTree();
+	dstTree = (JTree) dstScroll.getViewport().getView();
+
+	constraints.location = constraints.RIGHT_SCROLLPANE;
+	constraints.insets = new Insets(5, 5, 5, 5);
+
+	layout.setConstraints(dstScroll, constraints);
+	panel.add(dstScroll);
+
+	dstLabel.setLabelFor(dstTree);
+    }
+
+    private void makePanel(String srcHeader, String dstHeader) {
+	makePanel(this, srcHeader, dstHeader);
+    }
+
+    private JScrollPane newTree() {
+	DefaultTreeModel treeModel = new DefaultTreeModel(
+		new DblTreeNode("All Items"));
+
+	JTree tree = new JTree(treeModel);
+	JScrollPane treeScroll = new JScrollPane(tree);
+
+	tree.getSelectionModel().setSelectionMode(
+		TreeSelectionModel.SINGLE_TREE_SELECTION);
+
+	tree.setLargeModel(true);
+	tree.setRootVisible(false);
+	tree.setShowsRootHandles(true);
+
+	treeScroll.setVerticalScrollBarPolicy(
+		ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
+	treeScroll.setHorizontalScrollBarPolicy(
+		ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+
+	tree.putClientProperty("JTree.lineStyle", "Angled");
+
+	return treeScroll;
+    }
+
+    /**
+     * Convenience method for creating & initializing
+     * a new JLabel
+     *
+     * @param  label the component to initialize
+     * @param  txt the text displayed
+     */
+    private void setUpLabel(JLabel label, String txt) {
+        ActionString actionString = new ActionString(txt);
+        label.setText(actionString.getString());
+        label.setDisplayedMnemonic(actionString.getMnemonic());
+	label.setHorizontalAlignment(label.LEFT);
+	label.setVerticalAlignment(label.BOTTOM);
+    }
+
+    /**
+     * Convenience method for creating & initializing
+     * a new JButton
+     *
+     * @param  button the component to initialize
+     * @param  txt the text displayed
+     */
+    private void setUpButton(AbstractButton button, String txt) {
+        ActionString actionString = new ActionString(txt);
+        button.setText(actionString.getString());
+        button.setMnemonic(actionString.getMnemonic());
+    }
+
+    /**
+     * Set initial selection of a tree node
+     *
+     */
+    public void setInitSelection() {
+	DblTreeNode child;
+	TreePath nodepath;
+
+	DefaultTreeModel srcModel = (DefaultTreeModel)srcTree.getModel();
+	DefaultTreeModel dstModel = (DefaultTreeModel)dstTree.getModel();
+	DblTreeNode srcRoot = (DblTreeNode)srcModel.getRoot();
+	DblTreeNode dstRoot = (DblTreeNode)dstModel.getRoot();
+
+	if (srcTree.isRootVisible()) {
+
+	    nodepath = new TreePath(srcRoot);
+	    srcTree.setSelectionPath(nodepath);
+            addItem.setEnabled(true);
+            delItem.setEnabled(false);
+
+	} else if (srcRoot.getChildCount() > 0) {
+
+	    child = (DblTreeNode)srcRoot.getFirstChild();
+	    nodepath = new TreePath(child.getPath());
+	    srcTree.setSelectionPath(nodepath);
+	    srcTree.scrollPathToVisible(nodepath);
+	    addItem.setEnabled(true);
+	    delItem.setEnabled(false);
+
+        } else if (dstTree.isRootVisible()) {
+
+	    nodepath = new TreePath(dstRoot);
+	    dstTree.setSelectionPath(nodepath);
+            addItem.setEnabled(false);
+            delItem.setEnabled(true);
+
+	} else if (dstRoot.getChildCount() > 0) {
+
+	    child = (DblTreeNode)dstRoot.getFirstChild();
+	    nodepath = new TreePath(child.getPath());
+	    dstTree.setSelectionPath(nodepath);
+	    dstTree.scrollPathToVisible(nodepath);
+	    addItem.setEnabled(false);
+	    delItem.setEnabled(true);
+
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTreesConstraints.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,164 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.awt.*;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * This class provides the <code>DoubleTreesLayout</code> manager constraints.
+ *
+ */
+public class DoubleTreesConstraints implements Cloneable, java.io.Serializable {
+
+    /**
+     * Default <code>location</code> field value.
+     * Used to determine if the location
+     * field has not been set.
+     */
+    private static final int UNKNOWN = 0;
+
+    /**
+     * <code>location</code> field value for the left label
+     * above the left scrollpane.
+     */
+    public static final int LEFT_LABEL = 1;
+
+    /**
+     * <code>location</code> field value for the left scrollpane.
+     */
+    public static final int LEFT_SCROLLPANE = 2;
+
+    /**
+     * <code>location</code> field value for the right label above the right
+     * scrollpane.
+     */
+    public static final int RIGHT_LABEL = 3;
+
+    /**
+     * <code>location</code> field value for the right scrollpane.
+     */
+    public static final int RIGHT_SCROLLPANE = 4;
+
+    /**
+     * <code>location</code> field value for the central buttons between the
+     * left and right scrollpane.
+     */
+    public static final int BUTTONS = 5;
+
+    /**
+     * This field identifies which component within the
+     * <code>DoubleTreesLayout</code> the constraints belong to. If the
+     * location has not been set the value is undefined but will not
+     * default to any of the valid field values.
+     * <br>
+     * Valid field
+     * values are
+     * <code>LEFT_LABEL</code>,
+     * <code>RIGHT_LABEL</code>,
+     * <code>LEFT_SCROLLPANE</code>,
+     * <code>RIGHT_SCROLLPANE</code> and
+     * <code>BUTTONS</code>.
+     */
+    public int location;
+
+    /**
+     * This field specifies the external padding of the
+     * component, the minimum amount of space between the component and the
+     * edges of its display area.
+     * <br>
+     * The default value is
+     * <code>new Insets(0, 0, 0, 0)</code>.
+     */
+    public Insets insets;
+
+    /**
+     * This field specifies the internal padding of the component,
+     * how much space to add to the minimum width of the component.
+     * The width of the component is at least its minimum width plus
+     * (<code>ipadx</code> * 2) pixels.
+     * <br>
+     * The default value is 0.
+     */
+    public int ipadx;
+
+    /**
+     * This field specifies the internal padding of the component,
+     * how much space to add to the minimum height of the component.
+     * The height of the component is at least its minimum height plus
+     * (<code>ipadx</code> * 2) pixels.
+     * <br>
+     * The default value is 0.
+     */
+    public int ipady;
+
+    /**
+     * Creates a <code>DoubleTreesConstraint</code> object with all of
+     * the fields set to the default value.
+     */
+    public DoubleTreesConstraints() {
+	location = UNKNOWN;
+	insets = new Insets(0, 0, 0, 0);
+	ipadx = 0;
+	ipady = 0;
+    }
+
+    /**
+     * Creates a <code>DoubleTreesConstraints</code> object with all of the
+     * fields set to the passed-in arguments.
+     *
+     * @param location
+     *	<code>location</code> field value.
+     * @param insets
+     *	<code>insets</code> field value.
+     * @param ipadx
+     *	<code>ipadx</code> field value.
+     * @param ipady
+     *	<code>ipady</code> field value.
+     */
+    public DoubleTreesConstraints(
+	    int location,
+	    Insets insets,
+	    int ipadx, int ipady) {
+	this.location = location;
+	this.insets = insets;
+	this.ipadx = ipadx;
+	this.ipady = ipady;
+    }
+
+// ----------------------------------------------------------------------
+
+    public Object clone() {
+	try {
+	    return ((DoubleTreesConstraints)super.clone());
+	} catch (CloneNotSupportedException e) {
+	    // this shouldn't happen, since we are Cloneable
+	    throw new InternalError();
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTreesLayout.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,453 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.awt.*;
+import javax.swing.*;
+import java.util.*;
+
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * This class provides the <code>DoubleTreesLayout</code> manager used
+ * by the <code>DoubleTrees</code> component. The layout manager assumes
+ * that the <code>DoubleTrees</code> component contains the following
+ * interior components.
+ * <br>
+ * <code>
+ * +---------------------------------------------------+
+ * |  LEFT_LABEL                          RIGHT_LABEL  |
+ * |  +----------------+           +----------------+  |
+ * |  |LEFT_SCROLLPANE |           |RIGHT_SCROLLPANE|  |
+ * |  |                | +-------+ |                |  |
+ * |  |                | |BUTTONS| |                |  |
+ * |  |                | |       | |                |  |
+ * |  |                | |       | |                |  |
+ * |  |                | +-------+ |                |  |
+ * |  |                |           |                |  |
+ * |  +----------------+           +----------------+  |
+ * |                                                   |
+ * +---------------------------------------------------+
+ * </code>
+ * <br>
+ * Each component is laid out and sized with respect to its own
+ * <code>DoubleTreesConstraints</code> object.
+ *
+ */
+public class DoubleTreesLayout implements LayoutManager2, java.io.Serializable {
+
+    protected final static Dimension ZERO_SIZE = new Dimension(0, 0);
+    protected final static Dimension MAXIMUM_SIZE =
+			new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+    protected Dimension size;
+    protected Dimension minimumSize = new Dimension(400, 250);
+    protected Dimension preferredSize = minimumSize;
+    protected Dimension maximumSize;
+    protected DoubleTreesConstraints defaultConstraints;
+
+    /**
+     * Constraints location to component map. Location key is wrapped in an
+     * <code>Integer</code>.
+     */
+    protected HashMap<Integer, Component> componentsMap;
+
+    /**
+     * Component to constraints map.
+     */
+    protected HashMap<Component, DoubleTreesConstraints> constraintsMap;
+
+// ----------------------------------------------------------------------
+
+    /**
+     * Construct a <code>DoubleTreesLayout<code> manager with default values.
+     */
+    public DoubleTreesLayout() {
+	size = ZERO_SIZE;
+	maximumSize = MAXIMUM_SIZE;
+	defaultConstraints = new DoubleTreesConstraints();
+	componentsMap = new HashMap<Integer, Component>();
+	constraintsMap = new HashMap<Component, DoubleTreesConstraints>();
+    }
+
+// ----------------------------------------------------------------------
+
+    /**
+     * Set the constraints for a given component. If the component has
+     * not previously been added to the layout, setting the components
+     * constraints will add the component to the layout.
+     *
+     * @param component
+     *	Component.
+     * @param constraints
+     *	Components constraints.
+     */
+    public void setConstraints(
+	    Component component,
+	    DoubleTreesConstraints constraints) {
+	addLayoutComponent(component, constraints);
+    }
+
+    /**
+     * Get the constraints for a given component. If the component has
+     * not had previously added to the layout the default constraints
+     * are returned.
+     *
+     * @param component
+     *	Component.
+     * @param constraints
+     *	Components constraints.
+     */
+    public DoubleTreesConstraints getConstraints(Component component) {
+	if (constraintsMap.containsKey(component)) {
+	    return constraintsMap.get(component);
+	} else {
+	    return defaultConstraints;
+	}
+    }
+
+    public void addLayoutComponent(String name, Component component) {
+	// Copied from GridBayLayout.
+	throw new RuntimeException("Not used by this layout manager");
+    }
+
+    public void addLayoutComponent(Component component, Object object) {
+	if (object == null) {
+	    if (!constraintsMap.containsKey(component)) {
+		// No constraints for component.
+		object = defaultConstraints;
+	    } else {
+		// Don't add again.
+		return;
+	    }
+	}
+
+	// Can only deal with our own constraints objects.
+	if (!(object instanceof DoubleTreesConstraints)) {
+	    throw new RuntimeException(
+		    "Constraints not sub class of DoubleTreesConstraints");
+	}
+
+	/**
+	 * Clone constraints in case caller is re-using the same constraints
+	 * object.
+	 */
+	DoubleTreesConstraints constraints =
+	    (DoubleTreesConstraints) ((DoubleTreesConstraints) object).clone();
+
+	// Update maps.
+	componentsMap.put(new Integer(constraints.location), component);
+	constraintsMap.put(component, constraints);
+
+    }
+
+    public void removeLayoutComponent(Component component) {
+	DoubleTreesConstraints constraints =
+	    constraintsMap.get(component);
+
+	if (constraints != null) {
+	    componentsMap.remove(new Integer(constraints.location));
+	}
+
+	constraintsMap.remove(component);
+    }
+
+    public Dimension preferredLayoutSize(Container parent) {
+	return preferredSize;
+    }
+
+    public Dimension minimumLayoutSize(Container parent) {
+	return minimumSize;
+    }
+
+    public Dimension maximumLayoutSize(Container parent) {
+	return maximumSize;
+    }
+
+    public float getLayoutAlignmentX(Container parent) {
+	return 0.5f;
+    }
+
+    public float getLayoutAlignmentY(Container parent) {
+	return 0.5f;
+    }
+
+    public void invalidateLayout(Container target) {
+    }
+
+    public void layoutContainer(Container parent) {
+	synchronized (parent.getTreeLock()) {
+	    doLayoutContainer(parent);
+	}
+    }
+
+    /**
+     * Layout the components.
+     *
+     * @param parent
+     *	Container component where the <code>DoubleTrees</code> component
+     *  resides.
+     */
+    private void doLayoutContainer(Container parent) {
+	size = parent.getSize();
+
+	JComponent ll = (JComponent) componentsMap.get(
+		new Integer(DoubleTreesConstraints.LEFT_LABEL));
+	DoubleTreesConstraints llc =
+	    constraintsMap.get(ll);
+
+	JComponent rl = (JComponent) componentsMap.get(
+		new Integer(DoubleTreesConstraints.RIGHT_LABEL));
+	DoubleTreesConstraints rlc = constraintsMap.get(rl);
+
+	Component b = componentsMap.get(
+		new Integer(DoubleTreesConstraints.BUTTONS));
+	DoubleTreesConstraints bc = constraintsMap.get(b);
+
+	Component ls = componentsMap.get(
+		new Integer(DoubleTreesConstraints.LEFT_SCROLLPANE));
+	DoubleTreesConstraints lsc = constraintsMap.get(ls);
+
+	Component rs = componentsMap.get(
+		new Integer(DoubleTreesConstraints.RIGHT_SCROLLPANE));
+	DoubleTreesConstraints rsc = constraintsMap.get(rs);
+
+	double pw = parent.getSize().getWidth();
+	double ph = parent.getSize().getHeight();
+
+	double llw = ll.getPreferredSize().getWidth();
+	double llh = ll.getPreferredSize().getHeight();
+
+	double lsw = ls.getPreferredSize().getWidth();
+	double lsh = ls.getPreferredSize().getHeight();
+
+	double rlw = rl.getPreferredSize().getWidth();
+	double rlh = rl.getPreferredSize().getHeight();
+
+	double rsw = rs.getPreferredSize().getWidth();
+	double rsh = rs.getPreferredSize().getHeight();
+
+	double bw = b.getPreferredSize().getWidth();
+	double bh = b.getPreferredSize().getHeight();
+
+	// button w and h inc. insets
+
+	bw += bc.insets.left + bc.insets.right;
+	bh += bc.insets.top + bc.insets.bottom;
+
+	// leave button w fixed, give rest of parent w to scroll panes
+
+	lsw = rsw = (pw - bw) / 2.0;
+
+	// left label w must not exceed left scroll pane w
+
+	ls.setSize(new Dimension((int) lsw, (int) lsh));
+
+	ll.setMaximumSize(setDimensionAxis(ll.getMaximumSize(), lsw, true));
+
+	llw = lsw - llc.insets.left - llc.insets.right;
+
+	ll.setSize(setDimensionAxis(ll.getSize(), llw, true));
+
+	llw = ll.getPreferredSize().getWidth();
+	llh = ll.getPreferredSize().getHeight();
+
+	// right label w must not exceed right scroll pane w
+
+	rs.setSize(new Dimension((int) rsw, (int) rsh));
+
+	rl.setMaximumSize(setDimensionAxis(ll.getMaximumSize(), rsw, true));
+
+	llw = lsw - llc.insets.left - llc.insets.right;
+
+	rl.setSize(setDimensionAxis(rl.getSize(), rlw, true));
+
+	rlw = rl.getPreferredSize().getWidth();
+	rlh = rl.getPreferredSize().getHeight();
+
+	// both label h must be equal and accomodate both labels
+
+	double lh = Math.max(
+		llh + llc.insets.top + llc.insets.bottom,
+		rlh + rlc.insets.top + rlc.insets.bottom);
+
+	ll.setSize(new Dimension((int) lsw, (int) lh));
+
+	rl.setSize(new Dimension((int) rsw, (int) lh));
+
+	// both label w must not exceed scroll pane w
+
+	llw = lsw;
+	rlw = rsw;
+
+	// scroll pane h gets rest of parent h after label h allocated
+
+	lsh = rsh = ph - lh;
+
+	ls.setSize(new Dimension((int) lsw, (int) lsh));
+	rs.setSize(new Dimension((int) rsw, (int) rsh));
+	b.setSize(new Dimension((int) bw, (int) bh));
+
+	// see if we have a preferred size > minimum size
+
+	if (preferredSize == minimumSize) {
+	    int w = (int) (lsw + bw + rsw);
+	    int h = (int) (lh + lsh);
+
+	    w = Math.max(w, (int) minimumSize.getWidth());
+	    h = Math.max(h, (int) minimumSize.getHeight());
+
+	    preferredSize = new Dimension(w, h);
+	}
+
+	// set locations for labels, scroll panes and buttons
+
+	int llx = 0;
+	int lly = 0;
+
+	int lsx = 0;
+	int lsy = lly + (int) lh;
+
+	int bx = lsx + (int) lsw;
+	int by = (int) (lh + (lsh - bh) / 2);
+
+	int rlx = bx + (int) bw;
+	int rly = 0;
+
+	int rsx = bx + (int) bw;
+	int rsy = rly + (int) lh;
+
+	ll.setLocation(llx, lly);
+	ls.setLocation(lsx, lsy);
+	rs.setLocation(rsx, rsy);
+	rl.setLocation(rlx, rly);
+	b.setLocation(bx, by);
+
+	// adjust size and locations to accomodate insets
+
+	includeInsets(ll, llc.insets);
+	includeInsets(rl, rlc.insets);
+	includeInsets(ls, lsc.insets);
+	includeInsets(rs, rsc.insets);
+	includeInsets(b, bc.insets);
+    }
+
+    /**
+     * Adjust components size and location to accomodate an <code>Inset</code>.
+     *
+     * @param component
+     *	Component to be resized and relocated.
+     * @param insets
+     *	Inserts that must surround the component.
+     */
+    private void includeInsets(Component component, Insets insets) {
+	Point location = component.getLocation();
+	Dimension size = component.getSize();
+
+	double x = location.getX();
+	double y = location.getY();
+	double width = size.getWidth();
+	double height = size.getHeight();
+
+	component.setLocation(
+		(int) (x + insets.left),
+		(int) (y + insets.top));
+	component.setSize(
+		(int) (width - insets.left - insets.right),
+		(int) (height - insets.top - insets.bottom));
+    }
+
+// ----------------------------------------------------------------------
+
+    /**
+     * Get axis of a <code>Dimension</code>.
+     *
+     * @param dimension
+     *	<code>Dimension</code> being inspected.
+     * @param xAxis
+     *	True if the width (X axis) is required, otherwise false if the
+     *  height (Y axis) is required.
+     * @return
+     *	Required axis value.
+     */
+    private double getDimensionAxis(Dimension dimension, boolean xAxis) {
+	if (xAxis) {
+	    return dimension.getWidth();
+	} else {
+	    return dimension.getHeight();
+	}
+    }
+
+    /**
+     * Set axis of a <code>Dimension</code>.
+     *
+     * @param dimension
+     *	<code>Dimension</code> being modified.
+     * @param value
+     *	New axis value.
+     * @param xAxis
+     *	True if the width (X axis) is required, otherwise false if the
+     *  height (Y axis) is required.
+     * @return
+     *	The modified <code>Dimension</code>.
+     */
+    private Dimension setDimensionAxis(
+	    Dimension dimension,
+	    double value,
+	    boolean xAxis) {
+	if (xAxis) {
+	    dimension.setSize(value, dimension.getHeight());
+	} else {
+	    dimension.setSize(dimension.getWidth(), value);
+	}
+
+	return dimension;
+    }
+
+    /**
+     * Set axis of a <code>Dimension</code>.
+     *
+     * @param dimension
+     *	<code>Dimension</code> being modified.
+     * @param value
+     *	New axis value.
+     * @param xAxis
+     *	True if the width (X axis) is required, otherwise false if the
+     *  height (Y axis) is required.
+     * @return
+     *	The modified <code>Dimension</code>.
+     */
+    private Dimension setDimensionAxis(
+	    Dimension dimension,
+	    int value,
+	    boolean xAxis) {
+	return setDimensionAxis(dimension, (double) value, xAxis);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/ExtAttrObj.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,357 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.lang.*;
+import java.io.*;
+import java.util.*;
+
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * The ExtAttrObj class is the base class for all RBAC attribute objects
+ * stored in the RBAC "_attr" table data stores in a name service.
+ * It contains convenience methods for manipulating key/value sets;
+ * a comma separated set of string values with a specific keyword.
+ * All key/value sets are maintained in a hash table in this superclass.
+ *
+ */
+
+
+public class ExtAttrObj extends Object implements Cloneable {
+
+    // Private attributes backstopped by persistent storage
+
+    public Hashtable<String, AttrObj> attrSet;	    // Key-Value Attributes
+
+    /**
+     *	Null constructor creates an empty has table of key/values.
+     *
+     */
+    public ExtAttrObj() {
+
+	attrSet = new Hashtable<String, AttrObj>();
+
+    }
+
+    /**
+     * Return the values for a specified key name.
+     *
+     * @param A key name
+     *
+     * @return A vector of string values
+     *
+     */
+    public Vector getAttribute(String keyName) {
+
+        if (!attrSet.containsKey(keyName)) {
+	    return (null);
+        } else {
+            AttrObj attr = locate(keyName);
+            return (attr.getVector());
+        }
+
+    }
+
+    /**
+     * Set the value for a specified key name.  Any existing values
+     * for that key are replaced.
+     *
+     * @param A key name
+     * @param A string value
+     *
+     */
+    public void setAttribute(String keyName, String value) {
+
+	AttrObj attr = locate(keyName);
+	attr.set(value);
+
+    }
+
+    /**
+     * Set one or more values for a specified key name.
+     * Any existing values for that key are replaced.
+     *
+     * @param A key name
+     * @param A vector of string values
+     *
+     */
+    public void setAttribute(String keyName, Vector values) {
+
+	AttrObj attr = locate(keyName);
+	attr.set(values);
+
+    }
+
+    /**
+     * Return an array of string values for a specified key name.
+     *
+     * @param A key name
+     *
+     * @return An array of string values
+     *
+     */
+    public String [] getAttributeArray(String keyName) {
+
+        if (! attrSet.containsKey(keyName)) {
+	    return (null);
+        } else {
+	    AttrObj attr = locate(keyName);
+	    Vector v = attr.getVector();
+	    String [] star = new String[v.size()];
+	    v.copyInto(star);
+	    return (star);
+        }
+
+    }
+
+    /**
+     * Set one or more values for a specified key name.
+     * Any existing values for that key are replaced.
+     *
+     * @param A key name
+     * @param An array of string values
+     *
+     */
+    public void setAttribute(String keyName, String [] values) {
+
+	AttrObj attr = locate(keyName);
+	attr.set(values);
+
+    }
+
+    /**
+     * Add a string value to the set of values for a key name.
+     *
+     * @param A key name
+     * @param A string value
+     *
+     */
+    public void addAttribute(String keyName, String value) {
+
+        AttrObj attr = locate(keyName);
+        attr.add(value);
+
+    }
+
+    /**
+     * Add one or more string values to the set of values for a key name.
+     *
+     * @param A key name
+     * @param A vector of string values
+     *
+     */
+    public void addAttribute(String keyName, Vector values) {
+
+	AttrObj attr = locate(keyName);
+	attr.add(values);
+
+    }
+
+    /**
+     * Add one or more string values to the set of values for a key name.
+     *
+     * @param A key name
+     * @param An array of string values
+     *
+     */
+    public void addAttribute(String keyName, String [] values) {
+
+	AttrObj attr = locate(keyName);
+	attr.add(values);
+
+    }
+
+    /**
+     * Remove a string value from the set of values for a key name.
+     *
+     * @param A key name
+     * @param A string value
+     *
+     */
+    public void delAttribute(String keyName, String value) {
+
+	AttrObj attr = locate(keyName);
+	attr.del(value);
+
+    }
+
+    /**
+     * Remove one or more string values from the set of values
+     * for a key name.
+     *
+     * @param A key name
+     * @param A vector of string values
+     *
+     */
+    public void delAttribute(String keyName, Vector values) {
+
+	AttrObj attr = locate(keyName);
+	attr.del(values);
+
+    }
+
+    /**
+     * Remove one or more string values from the set of values
+     * for a key name.
+     *
+     * @param A key name
+     * @param An array of string values
+     *
+     */
+    public void delAttribute(String keyName, String [] values) {
+
+	AttrObj attr = locate(keyName);
+	attr.del(values);
+
+    }
+    /**
+     * Remove a key name and all its values.
+     *
+     * @param A key name
+     *
+     */
+    public void clearAttribute(String keyName) {
+
+	// Because KeyValue will do a merge, cannot remove the
+	// key/value from the hash table.  Rather, set its value
+	// to empty.
+	AttrObj attr = locate(keyName);
+	attr.set("");
+
+    }
+
+    /**
+     * Remove all key name and all their values; that is,
+     * reset the key/values attributes to a null set.
+     *
+     */
+    public void clearAttributes() {
+
+	// Because KeyValue will do a merge, cannot remove the
+	// key/values from the hash table.  Rather, set the values
+	// for all keys to empty.
+	Enumeration values = attrSet.elements();
+	while (values.hasMoreElements()) {
+	    AttrObj attr = (AttrObj) values.nextElement();
+	    attr.set("");
+	}
+
+    }
+
+    /**
+     * Update the key/value attributes from this object into
+     * another attribute object (clone the attributes).
+     *
+     * @param An attribute object
+     *
+     */
+    public void clone(ExtAttrObj newExtAttrObj) {
+
+	Enumeration values = attrSet.elements();
+	while (values.hasMoreElements()) {
+	    AttrObj attrObj = (AttrObj) values.nextElement();
+	    String key = attrObj.getKey();
+	    AttrObj newAttrObj = newExtAttrObj.locate(key);
+	    newAttrObj.set((attrObj.getVector()));
+	}
+
+    }
+
+    /**
+     * Find the attributes for a key name.  If not found, create
+     * a new key/value attribute with null values.
+     *
+     * @param A key name
+     *
+     */
+    public AttrObj locate(String key) {
+
+	AttrObj attrObj;
+	if (attrSet.containsKey(key)) {
+	    attrObj = attrSet.get(key);
+	} else {
+	    attrObj = new AttrObj(key);
+	    attrSet.put(key, attrObj);
+	}
+	return attrObj;
+
+    }
+
+    /**
+     * The equals method checks that all attributes of this user
+     * authorization attributes object equal the corresponding
+     * attributes of the specified user attributes object.
+     * If so, true is returned; otherwise, false is returned.
+     *
+     * @param	extAttr Specified user attr object to be compared
+     *
+     * @return	true if the specified object is identical
+     *
+     */
+    public boolean equals(ExtAttrObj extAttr) {
+
+	String [] s2;
+	String ts;
+	int i, j, k;
+
+	if (! (attrSet.size() == extAttr.attrSet.size()))
+	    return (false);
+
+	Enumeration values = attrSet.elements();
+	while (values.hasMoreElements()) {
+	    AttrObj attrObj = (AttrObj) values.nextElement();
+	    String key = attrObj.getKey();
+	    if (! (extAttr.attrSet.containsKey(key)))
+		return (false);
+
+	    AttrObj newAttrObj = extAttr.locate(key);
+
+	    if (! (attrObj.equals(newAttrObj)))
+		return (false);
+	}
+
+	// Everything matches, must be equal
+	return (true);
+
+    }
+
+    /**
+     * Display the contents of the key/values of this attribute
+     * object to sysout for debugging purposes.
+     *
+     */
+    public void debugPrint() {
+
+	Enumeration values = attrSet.elements();
+	while (values.hasMoreElements()) {
+	    AttrObj attrObj = (AttrObj) values.nextElement();
+	    attrObj.debugPrint();
+	}
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/FilterUserAction.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,313 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import java.util.List;
+import javax.swing.text.JTextComponent;
+import com.oracle.solaris.vp.panel.common.action.*;
+import com.oracle.solaris.vp.panel.common.control.*;
+import com.oracle.solaris.vp.panel.swing.action.SwingManagedObjectAction;
+import com.oracle.solaris.rad.usermgr.*;
+import com.oracle.solaris.vp.util.misc.ObjectUtil;
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+import com.oracle.solaris.vp.util.misc.property.*;
+import com.oracle.solaris.vp.util.swing.*;
+import com.oracle.solaris.vp.util.swing.layout.*;
+import com.oracle.solaris.vp.util.swing.property.*;
+
+/**
+ * Filter users based on the scope (files or ldap)
+ * and type (user or role). The search string provides
+ * additional filtering.
+ */
+@SuppressWarnings({"serial"})
+public class FilterUserAction extends SwingManagedObjectAction
+    <UserManagedObject, FilterUserAction.Data, UserManagedObject> {
+
+    private UserManagedObject umo = null;
+    private UserImpl user = null;
+
+    //
+    // Inner classes
+    //
+
+    protected class Data { // implements ActionListener
+	//
+	// Instance data
+	//
+
+	private ButtonGroup scopeGroup;
+	private ButtonGroup typeGroup;
+	private JTextField matchField;
+	private JOptionPane pane;
+	private JDialog dialog;
+
+	private UserMgrPanelDescriptor descriptor = null;
+
+	public MutableProperty<String> matchProperty = new StringProperty();
+	public MutableProperty<String> typeProperty = new StringProperty();
+
+
+	//
+	// Constructors
+	//
+
+	public Data()   {
+	    pane = new JOptionPane(CreateGui(),
+		JOptionPane.PLAIN_MESSAGE,
+		JOptionPane.OK_CANCEL_OPTION);
+	    UserMgrUtils.removeIcons(pane);
+
+	    dialog = pane.createDialog(getHasComponent().getComponent(),
+		Finder.getString("usermgr.filter.title"));
+	}
+
+        private JPanel CreateGui() {
+	    ActionListener listener =
+		new ActionListener() {
+		    @Override
+		    public void actionPerformed(ActionEvent e) {
+			pane.setValue(JOptionPane.OK_OPTION);
+		    }
+		};
+
+	ActionString actString = null;
+	JRadioButton scopeButton = null;
+	descriptor = control.getPanelDescriptor();
+	JPanel form = new JPanel(new GridBagLayout());
+	GridBagConstraints gbc = new GridBagConstraints();
+	int width = GUIUtil.getTextFieldWidth();
+
+	gbc.gridx = 0;
+	gbc.gridy = 0;
+	// gbc.weightx = 1.0;
+	gbc.fill = GridBagConstraints.REMAINDER;
+	gbc.anchor = GridBagConstraints.LINE_START;
+        int hGap = GUIUtil.getHalfGap();
+	gbc.insets = new Insets(0, 0, hGap, hGap);
+
+	// Label for the dialog
+	JLabel introLabel = new JLabel(
+	    Finder.getString("usermgr.filter.label"));
+	form.add(introLabel, gbc);
+
+	//
+	// Scope: files or ldap
+	//
+        JLabel scopeLabel = new JLabel(
+		Finder.getString("usermgr.filter.scope"));
+	JPanel scopePanel = new JPanel();
+
+	scopeGroup = new ButtonGroup();
+	List<String> scopes = descriptor.getScopes();
+	JRadioButton[] buttons = new JRadioButton[scopes.size()];
+	for (int i = 0; i < scopes.size(); i++) {
+		String scope = scopes.get(i);
+		scopeButton = new JRadioButton(scope);
+		scopeButton.setActionCommand(scope);
+		int mnemonic = scope.toUpperCase().charAt(0);
+		scopeButton.setMnemonic(mnemonic);
+		scopeGroup.add(scopeButton);
+		scopePanel.add(scopeButton);
+		buttons[i] = scopeButton;
+	}
+
+	// For single scope, disable the button
+	if (scopes.size() == 1) {
+	    buttons[0].setEnabled(false);
+	}
+
+	gbc.gridy++;
+	gbc.gridwidth = 1;
+	gbc.fill = GridBagConstraints.NONE;
+        form.add(scopeLabel, gbc);
+	gbc.fill = GridBagConstraints.REMAINDER;
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(scopePanel, gbc);
+
+	//
+	// Type: User or Role
+	//
+        JLabel typeLabel = new JLabel(
+		Finder.getString("usermgr.filter.type"));
+	JPanel typePanel = new JPanel();
+
+	typeGroup = new ButtonGroup();
+	actString = new ActionString("usermgr.filter.type.user");
+	JRadioButton userButton = new JRadioButton(actString.getString());
+	userButton.setMnemonic(actString.getMnemonic());
+        userButton.setSelected(true);
+        userButton.setActionCommand("normal");
+	typeGroup.add(userButton);
+	typePanel.add(userButton);
+
+	actString = new ActionString("usermgr.filter.type.role");
+	JRadioButton roleButton = new JRadioButton(actString.getString());
+	roleButton.setMnemonic(actString.getMnemonic());
+        roleButton.setActionCommand("role");
+	typeGroup.add(roleButton);
+	typePanel.add(roleButton);
+
+	gbc.gridy++;
+	gbc.gridwidth = 1;
+	gbc.fill = GridBagConstraints.NONE;
+        form.add(typeLabel, gbc);
+	gbc.fill = GridBagConstraints.REMAINDER;
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(typePanel, gbc);
+
+	// Match String
+	actString = new ActionString("usermgr.filter.match");
+	JLabel matchLabel = new JLabel(actString.getString());
+	matchLabel.setDisplayedMnemonic(actString.getMnemonic());
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(matchLabel, gbc);
+
+	matchField = GUIUtil.createTextField();
+	matchField.addActionListener(listener);
+	new TextComponentPropertySynchronizer<String, JTextComponent>
+		(matchProperty, matchField, false);
+
+	matchLabel.setLabelFor(matchField);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(matchField, gbc);
+
+	//
+	// Start with previously selected filter entries
+	//
+	if (userButton.getActionCommand().equals(descriptor.getType())) {
+	    userButton.setSelected(true);
+	} else {
+	    roleButton.setSelected(true);
+	}
+	matchField.setText(descriptor.getMatch());
+
+	for (int j = 0; j < buttons.length; j++) {
+	    if (buttons[j].getActionCommand().equals(descriptor.getScope())) {
+		buttons[j].setSelected(true);
+		break;
+	    }
+	}
+
+	return form;
+    }
+
+    public String getScope() {
+    	ButtonModel bm = scopeGroup.getSelection();
+	return bm.getActionCommand();
+    }
+
+    public String getType() {
+    	ButtonModel bm = typeGroup.getSelection();
+	return bm.getActionCommand();
+    }
+
+    public String getString() {
+	return matchField.getText();
+    }
+    }
+
+    //
+    // Static data
+    //
+
+    private static final String FILTER_TEXT = Finder.getString(
+	"usermgr.action.filter.button");
+
+    //
+    // Instance data
+    //
+
+    private MainControl control;
+
+    //
+    // Constructors
+    //
+
+    public FilterUserAction(MainControl control) {
+	super(FILTER_TEXT, null, control);
+        ActionString actStr = new ActionString(
+	    "usermgr.action.filter.button");
+	putValue(Action.NAME, actStr.getString());
+	putValue(Action.MNEMONIC_KEY, actStr.getMnemonic());
+	// putValue(Action.MNEMONIC_KEY, KeyEvent.VK_F);
+	this.control = control;
+	setLoops(true);
+    }
+
+    //
+    // StructuredAction methods
+    //
+
+    // @Override
+    public Data getRuntimeInput(List<UserManagedObject> selection,
+    	Data uData) throws ActionAbortedException {
+
+	// Since this action navigates to the new object once created, we must
+	// first navigate to control so that any outstanding changes in the
+	// current Control are handled.
+	try {
+	    control.getNavigator().goToAsyncAndWait(false, control);
+	} catch (NavigationException e) {
+	    throw new ActionAbortedException(e);
+	}
+
+	if (uData == null) {
+	    uData = new Data();
+	}
+
+	// Blocks until dismissed
+	uData.dialog.setVisible(true);
+
+	if (!ObjectUtil.equals(uData.pane.getValue(), JOptionPane.OK_OPTION)) {
+	    throw new ActionAbortedException();
+	}
+
+	return uData;
+    }
+
+    //
+    // DefaultStructuredAction methods
+    //
+
+    // @Override
+    public UserManagedObject workBusy(List<UserManagedObject> selection,
+	Data uData) throws ActionFailedException,
+		ActionAbortedException,
+		ActionUnauthorizedException {
+
+	UserMgrPanelDescriptor descriptor = control.getPanelDescriptor();
+	descriptor.initUsers(uData.getScope(),
+		uData.getType(), uData.getString());
+
+	return null; // umo;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/GroupsPanel.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,345 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.tree.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * Groups Panel for Groups settings
+ */
+public class GroupsPanel extends JPanel {
+
+    public static SelPanel groupPanel;
+    private static DblTreeNode srcRoot;
+    private static DblTreeNode dstRoot;
+    private DefaultTreeModel srcModel, dstModel;
+    private DblTreeNode[] groupNodes;
+    private GroupTreeNode[] groupTreeNodes;
+
+    private UserManagedObject userObj = null;
+    private UserMgrPanelDescriptor panelDesc = null;
+
+    private boolean isGroupListOK = true;
+
+    /**
+     * Creates the Group Tab for the User.
+     */
+    public GroupsPanel(UserMgrPanelDescriptor panelDesc,
+		UserManagedObject userObj) {
+
+	super();
+	this.panelDesc = panelDesc;
+	this.userObj = userObj;
+
+	createGui();
+	loadGroupTrees();
+
+    } // end constructor
+
+    private void createGui() {
+
+	GridBagLayout gbl = new GridBagLayout();
+	GridBagConstraints gbc = new GridBagConstraints();
+	setLayout(gbl);
+
+        // Excluded and Included rights panel
+        groupPanel = new SelPanel("usermgr.advanced.groups.available",
+		"usermgr.advanced.groups.assigned");
+
+        groupPanel.srcTree.setCellRenderer(new GroupRenderer(this));
+        groupPanel.dstTree.setCellRenderer(new GroupRenderer(this));
+
+        Constraints.constrain(this, groupPanel,
+            0, 0, 1, 1, gbc.BOTH, gbc.CENTER, 1.0, 1.0, 10, 10, 10, 10);
+
+    } // end of CreateGui
+
+    /**
+     * Load the Source and Destination trees for rights excluded and
+     * included lists.
+     */
+    private void loadGroupTrees() {
+
+    	Vector<String> vAllGroupObjs = getAvailableGroups();
+
+	groupPanel.resetModels();
+	// For modifying a user:
+	// Initialize the excluded rights list with all groups
+
+	srcModel = (DefaultTreeModel) groupPanel.srcTree.getModel();
+	srcRoot = (DblTreeNode) srcModel.getRoot();
+
+	dstModel = (DefaultTreeModel) groupPanel.dstTree.getModel();
+	dstRoot = (DblTreeNode) dstModel.getRoot();
+
+	groupNodes = new DblTreeNode[vAllGroupObjs.size()];
+	groupTreeNodes = new GroupTreeNode[vAllGroupObjs.size()];
+
+	int n = 0;
+	Enumeration e = vAllGroupObjs.elements();
+
+	// Build an array of tree nodes that can be used for sorting.
+	while (e.hasMoreElements()) {
+	    String groupObj =  (String)e.nextElement();
+	    String groupName = groupObj;
+	    groupTreeNodes[n] = new GroupTreeNode(groupObj);
+	    n++;
+	}
+
+	// Sort the list of GroupTreeNode objects.
+
+	if (groupTreeNodes.length > 1) {
+	    NodeCompare comp = new NodeCompare();
+	    Sort.sort(groupTreeNodes, comp);
+	}
+
+	// With the sorted tree nodes, now we build the src tree.
+	for (int i = 0; i < groupTreeNodes.length; i++) {
+
+	    groupNodes[i] = new DblTreeNode((Object) groupTreeNodes[i]);
+
+	    srcModel.insertNodeInto(groupNodes[i], srcRoot, i);
+	    TreePath nodepath = new TreePath(groupNodes[i].getPath());
+
+	    // Make initial display of excluded list
+	    groupPanel.srcTree.scrollPathToVisible(nodepath);
+	}
+
+        String groupsStr = userObj.getGroups();
+	if (groupsStr == null)
+		return;
+
+        String[] assignedGroups = userObj.getGroups().split(",");
+        if (assignedGroups.length == 0) {
+            return;
+        }
+
+        // Move groups of current user from excluded list
+        // to included list.
+        // Note that a dimmed group will stay dimmed after the move.
+        // Therefore, a user can not "unassign" a dimmed group on the
+        // included list.
+
+        for (int i = 0; i < groupNodes.length; i++) {
+            boolean foundGroup = false;
+            String groupString = groupNodes[i].toString();
+
+            for (int j = 0; j < assignedGroups.length; j++) {
+                if (groupString.equals(assignedGroups[j])) {
+                    foundGroup = true;
+                    break;
+                }
+            }
+
+            if (foundGroup) {
+                groupPanel.initLeaf(groupPanel.srcTree,
+                    groupPanel.dstTree, groupNodes[i]);
+            }
+        }
+
+    } // end loadGroupTrees
+
+    private Vector<String> getAvailableGroups() {
+        Vector<String> groups = new Vector<String>();
+	for (String s : panelDesc.getSupplGroups()) {
+	    groups.add(s);
+
+	}
+    	return (groups);
+    }
+
+    public void setUser(UserManagedObject userObj) {
+    	this.userObj = userObj;
+	loadGroupTrees();
+    }
+
+    public UserManagedObject updateUser() {
+        Vector<String> vGroups = getAssignedGroups();
+	String groupsStr;
+
+	if (vGroups.size() > 0) {
+		groupsStr = vGroups.elementAt(0);
+	} else {
+		groupsStr = "";
+	}
+
+	for (int i = 1; i < vGroups.size(); i++) {
+	    groupsStr = groupsStr.concat(",");
+	    groupsStr = groupsStr.concat(vGroups.elementAt(i));
+        }
+	userObj.getGroupsProperty().setValue(groupsStr);
+	return (userObj);
+    }
+
+    /**
+     */
+    public Vector<String> getAssignedGroups() {
+	Vector<String> newGroups = new Vector<String>();
+
+	if (isGroupListOK == false) {
+	    return newGroups;
+	}
+
+        DblTreeNode root = (DblTreeNode) dstModel.getRoot();
+        Enumeration kids;
+        kids = root.children();
+
+        while (kids.hasMoreElements()) {
+            DblTreeNode childNode;
+            childNode = (DblTreeNode)kids.nextElement();
+            newGroups.addElement(childNode.toString());
+        }
+
+	return newGroups;
+    }
+
+
+    class GroupTreeNode {
+
+        String name;
+        String groupObj = null;
+
+        public GroupTreeNode(String groupObj) {
+            this.groupObj = groupObj;
+            this.name = groupObj;
+        }
+
+        public String getGroupObj() {
+            return groupObj;
+        }
+
+        public String toString() {
+            return name;
+        }
+    }
+
+
+    class NodeCompare implements Compare {
+
+	/**
+	 * The compare method compares two GroupTreeNode objects by comparing
+	 * their group names.  The parameters are specified as Object class
+	 * objects for QuickSort.
+	 *
+	 * @param a - The first Node.
+	 * @param b - The second Node.
+	 *
+	 */
+        public final int doCompare(Object a, Object b) {
+
+            GroupTreeNode e1, e2;
+            String e1Name, e2Name;
+
+            e1 = (GroupTreeNode) a;
+            e2 = (GroupTreeNode)b;
+            e1Name = e1.toString();
+            e2Name = e2.toString();
+            return (e1Name.compareTo(e2Name));
+
+        }
+
+    }
+
+
+    class GroupRenderer extends DefaultTreeCellRenderer {
+
+        private boolean selected;
+        GroupsPanel rightSubProps;
+
+        public GroupRenderer(GroupsPanel rightSubProps) {
+
+	    this.rightSubProps = rightSubProps;
+            setClosedIcon(null);
+            setOpenIcon(null);
+            setLeafIcon(null);
+
+        }
+
+        public Component getTreeCellRendererComponent(
+            JTree tree,
+            Object value,
+            boolean selected,
+            boolean expanded,
+            boolean leaf,
+            int row,
+            boolean hasFocus) {
+
+            this.selected = selected;
+
+            DefaultTreeCellRenderer cr =
+                (DefaultTreeCellRenderer) tree.getCellRenderer();
+            cr.setLeafIcon(null);
+            DblTreeNode node = (DblTreeNode) value;
+
+            if (node.getParent() == null) {
+                // maybe the same as row == 0
+                setText(node.toString());
+
+            } else if (node.getUserObject() instanceof GroupTreeNode) {
+                GroupTreeNode groupsdef = (GroupTreeNode) node.getUserObject();
+                setText(groupsdef.toString());
+
+                if (selected) {
+                    if (node.isEnabled()) {
+                        cr.setTextSelectionColor(SystemColor.textText);
+                    } else {
+                        cr.setTextSelectionColor(
+			    SystemColor.inactiveCaptionText);
+		    }
+
+                } else {
+                    if (node.isEnabled()) {
+                        cr.setTextNonSelectionColor(SystemColor.textText);
+                    } else {
+
+                        cr.setTextNonSelectionColor(
+                        SystemColor.inactiveCaptionText);
+                    }
+                }
+            }
+
+            super.getTreeCellRendererComponent(tree, value, selected, expanded,
+                leaf, row, hasFocus);
+
+            return this;
+
+        } // end getTreeCellRendererComponent
+
+    } // GroupRenderer
+
+} // GroupsPanel
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/GroupsSettings.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,76 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+
+/**
+ * Implements Groups Settings in Advanced Settings
+ */
+public class GroupsSettings extends AdvancedSettings {
+
+    private static final String NAME =
+    	Finder.getString("usermgr.advanced.groups");
+    private static final Icon ICON = Finder.getIcon(
+	"images/group-24.png");
+
+    private UserMgrPanelDescriptor panelDesc = null;
+    private UserManagedObject userObj = null;
+    private GroupsPanel panel = null;
+
+    public GroupsSettings() {
+	super(NAME, ICON);
+    }
+
+    public void setUser(UserManagedObject userObj) {
+	if (panel == null) {
+		panel = new GroupsPanel(panelDesc, userObj);
+	}
+	panel.setUser(userObj);
+    }
+
+    public void updateUser() {
+	userObj = panel.updateUser();
+    }
+
+    public boolean isChanged() {
+        if (userObj != null) {
+	    return (userObj.getGroupsProperty().isChanged());
+	} else {
+	    return false;
+	}
+    }
+
+    public void init(UserMgrPanelDescriptor panelDesc) {
+	this.panelDesc = panelDesc;
+    }
+
+    public JPanel getPanel() {
+    	return panel;
+    }
+}
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/HintTextPropertySynchronizer.java	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/HintTextPropertySynchronizer.java	Fri Apr 27 00:52:26 2012 -0400
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  */
 
 package com.oracle.solaris.vp.panels.usermgr.client.swing;
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/MainControl.java	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/MainControl.java	Fri Apr 27 00:52:26 2012 -0400
@@ -26,7 +26,10 @@
 package com.oracle.solaris.vp.panels.usermgr.client.swing;
 
 import java.util.List;
+import java.util.Map;
 import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
 import javax.swing.border.Border;
 import com.oracle.solaris.vp.panel.common.action.*;
 import com.oracle.solaris.vp.panel.common.control.*;
@@ -36,6 +39,9 @@
 import com.oracle.solaris.vp.util.misc.finder.Finder;
 import com.oracle.solaris.vp.util.swing.ClippedBorder;
 
+/**
+ * Main User Manager Control
+ */
 public class MainControl extends ListSelectorControl
     <UserMgrPanelDescriptor, ListSelectorPanel, UserManagedObject> {
 
@@ -50,6 +56,8 @@
     //
 
     private ManagedObjectTableModel model;
+    private ListSelectorPanel panel;
+    private UserMgrBasicControl control = null;
 
     //
     // Constructors
@@ -64,6 +72,11 @@
     //
 
     @Override
+    public String getHelpMapID() {
+        return "usermgr-mainpanel";
+    }
+
+    @Override
     protected void save() throws ActionAbortedException, ActionFailedException,
 	ActionUnauthorizedException {
 
@@ -73,11 +86,9 @@
 	getPanelDescriptor().saveAddedUsers();
 
 	getPanelDescriptor().saveModifiedUsers();
+	control.clearChanges();
 
 	super.save();
-
-	// update status counts
-	getPanelDescriptor().setStatusText();
     }
 
     //
@@ -87,7 +98,7 @@
     @Override
     protected void ensureChildrenCreated() {
 	if (children.size() == 0) {
-	    SwingControl control = new UserMgrControl(getPanelDescriptor());
+	    control = new UserMgrBasicControl(getPanelDescriptor());
 	    addChildren(control);
 	    addToLayout(control);
 	}
@@ -98,8 +109,8 @@
     //
     @Override
     protected ListSelectorPanel createComponent() {
-	ListSelectorPanel panel = new ListSelectorPanel();
-	panel.setSelectionTitle(Finder.getString("usermgr.list.title"));
+	panel = new ListSelectorPanel();
+	panel.setSelectionTitle(Finder.getString("usermgr.list.title.user"));
 
 	Border border = panel.getBorder();
 	panel.setBorder(new ClippedBorder(border, false, true, true, true));
@@ -114,9 +125,10 @@
 	panel.getChangeableAggregator().addChangeables(
 	    getPanelDescriptor().getChangeableAggregator());
 
-	// Add actions to create/delete users
+	// Add actions to create/delete/filter users
 	addAction(panel, new AddUserAction(this), true, true);
 	addAction(panel, new DeleteUserAction(this), true, true);
+	addAction(panel, new FilterUserAction(this), true, true);
 
 	setDefaultContentView(new UserMgrEmptyPanel());
 
@@ -129,6 +141,7 @@
 	addDefaultApplyAction();
 	addDefaultCancelAction(true);
 	addDefaultOkayAction(true);
+	addDefaultHelpAction();
     }
 
     @Override
@@ -180,8 +193,8 @@
 	    return null;
 	}
 	UserManagedObject uobj = selection.get(0);
-	Navigable navigable = new SimpleNavigable(UserMgrControl.ID,
-	    uobj.getName(), UserMgrControl.PARAM_USER, uobj.getId());
+	Navigable navigable = new SimpleNavigable(UserMgrBasicControl.ID,
+	    uobj.getName(), UserMgrBasicControl.PARAM_USER, uobj.getId());
  	return new Navigable[] {navigable};
     }
 
@@ -194,7 +207,8 @@
      */
     @Override
     protected int getListIndexOf(Control child) {
-   	UserManagedObject umo = ((UserMgrControl)child).getUserManagedObject();
+   	UserManagedObject umo =
+		((UserMgrBasicControl)child).getUserManagedObject();
   	int uIndex = getPanelDescriptor().indexOf(umo);
 
  	UserManagedObject utemp = (UserManagedObject) getComponent().
@@ -216,4 +230,40 @@
 	return model;
     }
 
+    /**
+     * Get the model to use in the Users list
+     */
+    public void setListTitle(String listTitle) {
+        if (panel != null)
+	    panel.setSelectionTitle(listTitle);
+    }
+
+
+    @Override
+    protected void addDefaultCancelAction(final boolean quit) {
+	getComponent().getButtonBar().getCancelButton().addActionListener(
+	    new ActionListener() {
+		@Override
+		public void actionPerformed(ActionEvent e) {
+		    Control.UnsavedChangesAction action;
+		    ChangeableAggregator aggregator =
+			getComponent().getChangeableAggregator();
+		    if (aggregator != null && aggregator.isChanged()) {
+			action = getUnsavedChangesAction();
+		    } else {
+			action = Control.UnsavedChangesAction.DISCARD;
+		    }
+		    switch (action) {
+		    case SAVE:
+			doSaveAndQuit();
+			break;
+		    case DISCARD:
+			doQuit();
+			break;
+		    case CANCEL:
+			break;
+		    }
+		}
+	    });
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/QuickVector.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,123 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.util.Vector;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * The <code>QuickVector</code> class extends the Vector class,
+ * providing additional methods which allow faster
+ * access to elements of the array.
+ *
+ */
+public
+class QuickVector extends Vector {
+
+    /**
+     * Constructs an empty vector with the specified initial capacity and
+     * capacity increment.
+     *
+     * @param   initialCapacity	    the initial capacity of the vector.
+     * @param   capacityIncrement   the amount by which the capacity is
+     *				    increased when the vector overflows.
+     */
+    public QuickVector(int initialCapacity, int capacityIncrement) {
+        super(initialCapacity, capacityIncrement);
+    }
+
+    /**
+     * Constructs an empty vector with the specified initial capacity.
+     *
+     * @param   initialCapacity   the initial capacity of the vector.
+     */
+    public QuickVector(int initialCapacity) {
+        super(initialCapacity);
+    }
+
+    /**
+     * Constructs an empty vector.
+     *
+     */
+    public QuickVector() {
+        super();
+    }
+
+    /**
+     * Returns the component at the specified index.
+     *
+     * @param	index   an index into this vector.
+     * @return	the component at the specified index.
+     * @exception  ArrayIndexOutOfBoundsException  if an invalid index was
+     * given.
+     */
+    public final Object quickElementAt(int index) {
+        if (index >= elementCount) {
+            throw new ArrayIndexOutOfBoundsException(
+		index + " >= " + elementCount);
+        }
+        return elementData[index];
+    }
+
+    /**
+     * Sets the component at the specified <code>index</code> of this
+     * vector to be the specified object. The previous component at that
+     * position is discarded.
+     * <p>
+     * The index must be a value greater than or equal to <code>0</code>
+     * and less than the current size of the vector.
+     *
+     * @param	obj	what the component is to be set to.
+     * @param	index	the specified index.
+     * @exception  ArrayIndexOutOfBoundsException  if the index was invalid.
+     */
+    public final void quickSetElementAt(Object obj, int index) {
+        if (index >= elementCount) {
+            throw new ArrayIndexOutOfBoundsException(
+		index + " >= " + elementCount);
+        }
+        elementData[index] = obj;
+    }
+
+    public final void quickSwapElementsAt(int element1, int element2) {
+        Object obj = null;
+
+        if (element1 >= elementCount) {
+            throw new ArrayIndexOutOfBoundsException(
+		element1 + " >= " + elementCount);
+        }
+        if (element2 >= elementCount) {
+            throw new ArrayIndexOutOfBoundsException(
+		element2 + " >= " + elementCount);
+        }
+        obj =  elementData[element1];
+        elementData[element1] = elementData[element2];
+        elementData[element2] = obj;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RightsPanel.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,630 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.tree.*;
+import javax.swing.border.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * Rights Profiles Panel for Rights Settings
+ */
+public class RightsPanel extends JPanel {
+
+
+    public static Arranger profPanel;
+    private static DblTreeNode srcRoot;
+    private static DblTreeNode dstRoot;
+    private DefaultTreeModel srcModel, dstModel;
+
+    private DblTreeNode [] profNodes;
+    private ProfTreeNode [] profTreeNodes;
+
+    private ProfTreeNode currProfTreeNode;
+    private DblTreeNode currDblTreeNode;
+
+    private String targetRightName;
+    private String targetRight;
+    private JPanel securityPanel;
+
+    private UserManagedObject userObj = null;
+    private UserMgrPanelDescriptor panelDesc = null;
+
+    private Vector vAllRightObjs = null;
+
+    private boolean isProfListOK = true;
+
+    /**
+     * Constructs a panel to contain supplementary rights properties for
+     * the right object.
+     */
+    public RightsPanel(UserMgrPanelDescriptor panelDesc,
+        UserManagedObject userObj) {
+
+	super();
+	this.panelDesc = panelDesc;
+	this.userObj = userObj;
+
+	createGui();
+	loadProfiles();
+    } // constructor
+
+
+    /**
+     * Method for creating GUI
+     */
+    private void createGui() {
+
+	// Set the panel layout
+	GridBagConstraints gbc = new GridBagConstraints();
+	this.setLayout(new GridBagLayout());
+
+	// Excluded and Included rights panel
+   	securityPanel = null;
+
+	profPanel = new Arranger("usermgr.advanced.rights.available",
+		"usermgr.advanced.rights.granted");
+
+	Dimension dimension = new Dimension(200, 300);
+	profPanel.srcTree.setCellRenderer(new ProfileRenderer(this));
+	profPanel.srcTree.setVisibleRowCount(10);
+	profPanel.srcTree.setSize(dimension);
+
+	profPanel.dstTree.setCellRenderer(new ProfileRenderer(this));
+	profPanel.dstTree.setVisibleRowCount(10);
+	profPanel.dstTree.setSize(dimension);
+
+	Constraints.constrain(this, profPanel,
+		0, 0, 1, 1,
+		gbc.BOTH, gbc.CENTER,
+		1.0, 1.0, 10, 10, 10, 10);
+
+    } // end createGui
+
+
+    /**
+     * Load the Source and Destination trees for rights excluded and
+     * included lists.
+     */
+    private void loadProfiles() {
+
+	// Reset the data models. So old data is discarded
+	profPanel.resetModels();
+
+
+	// Initialize the excluded rights list with all profiles
+	// except for the current one, since a profile can not be
+	// assigned to itself. Note that all profiles are created
+	// as top-level profiles.
+
+	vAllRightObjs = getAvailableProfs();
+
+	srcModel = (DefaultTreeModel) profPanel.srcTree.getModel();
+	srcRoot = (DblTreeNode) srcModel.getRoot();
+
+	dstModel = (DefaultTreeModel) profPanel.dstTree.getModel();
+	dstRoot = (DblTreeNode) dstModel.getRoot();
+
+	profNodes = new DblTreeNode[vAllRightObjs.size()];
+	profTreeNodes = new ProfTreeNode[vAllRightObjs.size()];
+
+	int n = 0;
+	Enumeration e = vAllRightObjs.elements();
+
+	// Build an array of tree nodes that can be used for sorting.
+
+	while (e.hasMoreElements()) {
+	    String rightObj = (String)e.nextElement();
+	    String rightName = rightObj;
+
+	    profTreeNodes[n] = new ProfTreeNode(rightObj);
+
+	    n++;
+	}
+
+	// Sort the list of ProfTreeNode objects.
+
+	if (profTreeNodes.length > 1) {
+	    NodeCompare comp = new NodeCompare();
+	    Sort.sort(profTreeNodes, comp);
+	}
+
+	// With the sorted tree nodes, now we build the src tree.
+	for (int i = 0; i < profTreeNodes.length; i++) {
+	    profNodes[i] = new DblTreeNode((Object)profTreeNodes[i]);
+
+	    srcModel.insertNodeInto(profNodes[i], srcRoot, i);
+	    TreePath nodepath = new TreePath(profNodes[i].getPath());
+	    // Make initial display of excluded list
+	    profPanel.srcTree.scrollPathToVisible(nodepath);
+	}
+
+
+	// Set TreeModel listeners
+	srcModel.addTreeModelListener(new TreeModelListener() {
+
+	    public void treeNodesInserted(TreeModelEvent e) {
+		enableProfileChoices(e);
+	    }
+
+	    public void treeNodesRemoved(TreeModelEvent e) {
+		disableProfileChoices(e);
+	    }
+
+	    public void treeNodesChanged(TreeModelEvent e) {}
+
+	    public void treeStructureChanged(TreeModelEvent e) {}
+
+	});
+
+	dstModel.addTreeModelListener(new TreeModelListener() {
+
+	    public void treeNodesInserted(TreeModelEvent e) {
+		updateDstTree(e);
+	    }
+
+	    public void treeNodesRemoved(TreeModelEvent e) {
+		updateDstTree(e);
+	    }
+
+	    public void treeNodesChanged(TreeModelEvent e) {}
+
+	    public void treeStructureChanged(TreeModelEvent e) {}
+
+	});
+
+	// Build subprofiles recursively
+	for (int i = 0; i < profNodes.length; i++) {
+	    rebuildSubProfiles(profNodes[i], profNodes[i]);
+	}
+
+	String [] subProfList = null;
+
+	// Get the list of profiles that are assigned to current user/role
+	// (in user_attr entry).
+	String rights = userObj.getRights();
+	if (rights != null) {
+	    subProfList = userObj.getRights().split(",");
+	}
+
+	profPanel.setInitSelection();
+	if (rights == null || subProfList == null) {
+	    return;
+	}
+
+	// Move subprofiles of current profile from excluded list
+	// to included list.
+	// Note that a dimmed profile will stay dimmed after the move.
+	// Therefore, a user can not "unassign" a dimmed profile on the
+	// included list.
+
+
+	for (int j = 0; j < subProfList.length; j++) {
+	    boolean foundSubProf = false;
+
+	    int count = 0;
+	    for (int i = 0; i < profNodes.length; i++) {
+		String profString = profNodes[i].toString();
+
+		if (profString.equals(subProfList[j])) {
+		    foundSubProf = true;
+		    count = i;
+		    break;
+		}
+
+	    }
+
+	    if (foundSubProf) {
+		profPanel.initLeaf(profPanel.srcTree,
+		    profPanel.dstTree, profNodes[count]);
+	    }
+	}
+
+	profPanel.setInitSelection();
+
+    } // end loadProfiles
+
+
+    private void updateDstTree(TreeModelEvent e) {
+
+	Vector<DblTreeNode> inclProfsVec = new Vector<DblTreeNode>();
+	Enumeration inclProfsEnum = dstRoot.breadthFirstEnumeration();
+
+	while (inclProfsEnum.hasMoreElements()) {
+	    DblTreeNode node = (DblTreeNode)inclProfsEnum.nextElement();
+	    inclProfsVec.addElement(node);
+	    node.setConflict(false);
+	}
+
+	// Maintain included names as array as optimization
+
+	DblTreeNode [] inclProfs = new DblTreeNode[inclProfsVec.size()];
+	inclProfsVec.copyInto(inclProfs);
+
+	if (inclProfs.length < 2)
+	    return;
+
+	for (int i = 0; i < inclProfs.length; i++) {
+	    String testString = inclProfs[i].toString();
+
+	    for (int j = i + 1; j < inclProfs.length; j++) {
+		if (testString.equals(inclProfs[j].toString())) {
+		    inclProfs[j].setConflict(true);
+		    inclProfs[i].setConflict(true);
+		    TreeNode [] nodes = inclProfs[j].getPath();
+		    DblTreeNode parentProf = (DblTreeNode)nodes[1];
+		    parentProf.setConflict(true);
+		}
+	    }
+	}
+
+    } // end updateDstTree
+
+
+    private void enableProfileChoices(TreeModelEvent e) {
+
+	// Get names of currently included profiles
+	if (e.getPath().length > 1)
+	    return;
+
+	Vector<String> inclProfsVec = new Vector<String>();
+	Enumeration inclProfs = dstRoot.depthFirstEnumeration();
+
+	while (inclProfs.hasMoreElements()) {
+	    inclProfsVec.addElement(inclProfs.nextElement().toString());
+	}
+
+	// Maintain included names as array as optimization
+
+	String [] inclProfNames = new String[inclProfsVec.size()];
+	inclProfsVec.copyInto(inclProfNames);
+
+	// Look for excluded list items needing updating
+
+	Enumeration topProfs = srcRoot.children();
+	while (topProfs.hasMoreElements()) {
+	    DblTreeNode nextTop = (DblTreeNode)topProfs.nextElement();
+	    boolean matchFound = false;
+	    Enumeration exclProfs = nextTop.depthFirstEnumeration();
+
+	    while (exclProfs.hasMoreElements()) {
+		String testString = exclProfs.nextElement().toString();
+		for (int i = 0; i < inclProfNames.length; i++) {
+		    if (testString.equals(inclProfNames[i])) {
+			matchFound = true;
+			break;
+		    }
+		}
+		if (matchFound)
+		    break;
+	    }
+
+	    // A Profile hierarchy needs to be enabled
+
+	    if (!matchFound) {
+		exclProfs = nextTop.depthFirstEnumeration();
+		while (exclProfs.hasMoreElements()) {
+		    DblTreeNode onNode =
+			(DblTreeNode) exclProfs.nextElement();
+		    onNode.setConflict(false);
+		}
+		nextTop.setConflict(false);
+	    }
+	}
+
+    } // end enableProfileChoices
+
+
+    private void disableProfileChoices(TreeModelEvent e) {
+
+	if (e.getPath().length > 1)
+	    return;
+
+	Object[] children = e.getChildren();
+	DblTreeNode node = (DblTreeNode)children[0];
+	Enumeration kids = node.breadthFirstEnumeration();
+	while (kids.hasMoreElements()) {
+	    disableRecursively((DblTreeNode)kids.nextElement());
+	}
+
+    } // end disableProfileChoices
+
+
+    private void disableRecursively(DblTreeNode node) {
+
+	String testString = node.toString();
+	Enumeration exclProfs = srcRoot.breadthFirstEnumeration();
+	while (exclProfs.hasMoreElements()) {
+	    DblTreeNode exclNode = (DblTreeNode)exclProfs.nextElement();
+	    if (testString.equals(exclNode.toString())) {
+		TreeNode [] nodes = exclNode.getPath();
+
+		DblTreeNode parentProf = (DblTreeNode)nodes[1];
+		if (!parentProf.isConflict()) {
+		    parentProf.setConflict(true);
+		    exclNode.setConflict(true);
+    		}
+	    }
+	}
+
+    } // end disableRecursively
+
+
+    private void rebuildSubProfiles(DblTreeNode profNode, DblTreeNode topNode) {
+
+	// First unlink the old children
+	int childCount = profNode.getChildCount();
+	for (int i = 0; i < childCount; i++) {
+	    DblTreeNode child = (DblTreeNode) srcModel.getChild(profNode, 0);
+	    srcModel.removeNodeFromParent(child);
+	}
+
+	// Then recursively construct new nodes for all the children
+	DblTreeNode childNode;
+	int i = 0;
+	Enumeration topList = topNode.breadthFirstEnumeration();
+
+	// Find sub-profile list in RightObj of cached tree node
+	ProfTreeNode pTreeNode = (ProfTreeNode)profNode.getUserObject();
+	String rObj = pTreeNode.getRightObj();
+	// ProfAttrObj targetProfAttr = rObj.getProfAttr();
+
+	String [] profList = null; // targetProfAttr.getProfNames();
+
+	if (profList == null)
+	    return;
+
+	for (int k = 0; k < profList.length; k++) {
+	    String name = profList[k];
+
+	    // Prevent infinite recursive loops
+	    boolean cyclic = false;
+	    while (topList.hasMoreElements()) {
+		if (name.equals(topList.nextElement().toString())) {
+		    cyclic = true;
+		    // Mark the parent as cyclic
+		    topNode.setCyclic(true);
+		    Enumeration dupNodes = topNode.breadthFirstEnumeration();
+		    while (dupNodes.hasMoreElements()) {
+			childNode = (DblTreeNode)dupNodes.nextElement();
+			if (name.equals(childNode.toString())) {
+			    childNode.setCyclic(true);
+			}
+		    }
+		    break;
+		}
+	    }
+
+	    for (int j = 0; j < profTreeNodes.length; j++) {
+		if (name.equals(profTreeNodes[j].toString())) {
+		    childNode = new DblTreeNode((Object)profTreeNodes[j]);
+
+		    srcModel.insertNodeInto(childNode, profNode, i++);
+		    childNode.setEnabled(false);
+		    if (cyclic)
+			childNode.setCyclic(true);
+		    else
+			rebuildSubProfiles(childNode, topNode);
+		}
+	    }
+	}
+
+    } // end rebuildSubProfiles
+
+
+    public String updateRightSubProps(String rightObj) {
+
+	if (isProfListOK) {
+	    Vector<String> vAssignedProfs = new Vector<String>();
+
+	    // Get the first generation children that are assigned to
+	    // current profile.
+	    DblTreeNode root = (DblTreeNode)dstModel.getRoot();
+	    Enumeration kids;
+	    kids = root.children();
+
+	    while (kids.hasMoreElements()) {
+		DblTreeNode childNode;
+		childNode = (DblTreeNode)kids.nextElement();
+		vAssignedProfs.addElement(childNode.toString());
+	    }
+
+	    // ProfAttrObj profAttr = rightObj.getProfAttr();
+	    // profAttr.setProfNamesVector(vAssignedProfs);
+	}
+	return (rightObj);
+
+    } // end updateRightSubProps
+
+    public Vector<String> getAssignedProfs() {
+	Vector<String> vAssignedProfs = new Vector<String>();
+
+	if (!isProfListOK) {
+	    return vAssignedProfs;
+	}
+
+	// Get the first generation children that are assigned to
+	// current profile.
+	DblTreeNode root = (DblTreeNode)dstModel.getRoot();
+	Enumeration kids;
+	kids = root.children();
+	while (kids.hasMoreElements()) {
+	    DblTreeNode childNode;
+	    childNode = (DblTreeNode)kids.nextElement();
+	    vAssignedProfs.addElement(childNode.toString());
+	}
+
+	return vAssignedProfs;
+    }
+
+    private Vector<String> getAvailableProfs() {
+        Vector<String> rights = new Vector<String>();
+	for (String s : panelDesc.getProfiles()) {
+	    rights.add(s);
+
+	}
+    	return (rights);
+    }
+
+    public void setUser(UserManagedObject userObj) {
+    	this.userObj = userObj;
+	loadProfiles();
+    }
+
+    public UserManagedObject updateUser() {
+        Vector<String> vProfs = getAssignedProfs();
+	String profStr;
+
+	if (vProfs.size() > 0) {
+		profStr = vProfs.elementAt(0);
+	} else {
+		profStr = "";
+	}
+
+	for (int i = 1; i < vProfs.size(); i++) {
+	    profStr = profStr.concat(",");
+	    profStr = profStr.concat(vProfs.elementAt(i));
+        }
+
+	userObj.getRightsProperty().setValue(profStr);
+
+	return (userObj);
+    }
+}
+
+
+class ProfileRenderer extends DefaultTreeCellRenderer {
+
+    private boolean selected;
+    Icon warningIcon;
+    static RightsPanel rightsPanel;
+
+    public ProfileRenderer(RightsPanel rightsPanel) {
+
+	this.rightsPanel = rightsPanel;
+	setClosedIcon(null);
+	setOpenIcon(null);
+	setLeafIcon(null);
+    	warningIcon = Finder.getIcon("images/warning.gif");
+
+    }
+
+
+    public Component getTreeCellRendererComponent(
+	JTree tree,
+	Object value,
+	boolean selected,
+	boolean expanded,
+	boolean leaf,
+	int row,
+	boolean hasFocus) {
+
+	FocusEvent e = null;
+
+	this.selected = selected;
+
+	DefaultTreeCellRenderer cr =
+	    (DefaultTreeCellRenderer)tree.getCellRenderer();
+	cr.setLeafIcon(null);
+	DblTreeNode node = (DblTreeNode)value;
+
+	if (node.getParent() == null) {
+	    // maybe the same as row == 0
+	    setText(node.toString());
+
+	} else if (node.getUserObject() instanceof ProfTreeNode) {
+	    ProfTreeNode profsdef = (ProfTreeNode)node.getUserObject();
+	    setText(profsdef.toString());
+	    // setIcon(actionIcon);
+
+	    if (node.isConflict())
+		if (tree == rightsPanel.profPanel.dstTree)
+		    cr.setLeafIcon(warningIcon);
+	}
+
+	super.getTreeCellRendererComponent(tree, value, selected, expanded,
+	    leaf, row, hasFocus);
+
+	return this;
+
+    } // end getTreeCellRendererComponent
+
+}
+
+class ProfTreeNode {
+
+    String name;
+    String rightObj = null;
+
+    public ProfTreeNode(String rightObj) {
+	this.rightObj = rightObj;
+	this.name = rightObj;
+    }
+
+    public String getRightObj() {
+	return rightObj;
+    }
+
+    public String toString() {
+	return name;
+    }
+
+}
+
+class NodeCompare implements Compare {
+
+    /**
+     * The compare method compares two ProfTreeNode objects by comparing
+     * their profile names.  The parameters are specified as Object class
+     * objects for QuickSort.
+     *
+     * @param   a	The first Node.
+     * @param   b	The second Node.
+     *
+     */
+    public final int doCompare(Object a, Object b) {
+
+	ProfTreeNode e1, e2;
+	String e1Name, e2Name;
+
+	e1 = (ProfTreeNode)a;
+	e2 = (ProfTreeNode)b;
+	e1Name = e1.toString();
+	e2Name = e2.toString();
+	return (e1Name.compareTo(e2Name));
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RightsSettings.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+import com.oracle.solaris.vp.util.misc.property.*;
+
+/**
+ * Implements Advanced Settings for Rights profiles
+ */
+public class RightsSettings extends AdvancedSettings {
+
+    private static final String NAME =
+    	Finder.getString("usermgr.advanced.rights");
+    private static final Icon ICON = Finder.getIcon(
+	"images/rights-24.png");
+
+    private UserMgrPanelDescriptor panelDesc = null;
+    private UserManagedObject userObj = null;
+    private RightsPanel panel = null;
+
+    public RightsSettings() {
+	super(NAME, ICON);
+    }
+
+    public void setUser(UserManagedObject userObj) {
+	if (panel == null) {
+		panel = new RightsPanel(panelDesc, userObj);
+	}
+	panel.setUser(userObj);
+	getProperty().update(userObj.getRights(), false);
+    }
+
+    public void updateUser() {
+	userObj = panel.updateUser();
+	getProperty().update(userObj.getRights(), false);
+    }
+
+    public boolean isChanged() {
+        if (userObj != null) {
+	    return (userObj.getRightsProperty().isChanged());
+	} else {
+	    return false;
+	}
+    }
+
+    public void init(UserMgrPanelDescriptor panelDesc) {
+	this.panelDesc = panelDesc;
+    }
+
+    public JPanel getPanel() {
+    	return panel;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RolesPanel.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,348 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.tree.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * Roles Panels for Roles settings
+ *
+ */
+public class RolesPanel extends JPanel {
+
+    public static SelPanel rolePanel;
+    private static DblTreeNode srcRoot;
+    private static DblTreeNode dstRoot;
+    private DefaultTreeModel srcModel, dstModel;
+    private DblTreeNode[] roleNodes;
+    private RoleTreeNode[] roleTreeNodes;
+
+    private UserManagedObject userObj = null;
+    private UserMgrPanelDescriptor panelDesc = null;
+
+    private boolean isRoleListOK = true;
+
+    /**
+     * Creates the Role Tab for the User.
+     */
+    public RolesPanel(UserMgrPanelDescriptor panelDesc,
+		UserManagedObject userObj) {
+
+	super();
+	this.panelDesc = panelDesc;
+	this.userObj = userObj;
+
+	createGui();
+	loadRoleTrees();
+
+    } // end constructor
+
+    private void createGui() {
+
+	GridBagLayout gbl = new GridBagLayout();
+	GridBagConstraints gbc = new GridBagConstraints();
+	setLayout(gbl);
+
+        // Excluded and Included rights panel
+        rolePanel = new SelPanel("usermgr.advanced.roles.available",
+		"usermgr.advanced.roles.assigned");
+
+        rolePanel.srcTree.setCellRenderer(new RoleRenderer(this));
+        rolePanel.dstTree.setCellRenderer(new RoleRenderer(this));
+
+        Constraints.constrain(this, rolePanel,
+            0, 0, 1, 1, gbc.BOTH, gbc.CENTER, 1.0, 1.0, 10, 10, 10, 10);
+
+    } // end of CreateGui
+
+    /**
+     * Load the Source and Destination trees for rights excluded and
+     * included lists.
+     */
+    private void loadRoleTrees() {
+
+    	Vector<String> vAllRoleObjs = getAvailableRoles();
+
+	rolePanel.resetModels();
+	// For modifying a user:
+	// Initialize the excluded rights list with all roles
+
+	srcModel = (DefaultTreeModel) rolePanel.srcTree.getModel();
+	srcRoot = (DblTreeNode) srcModel.getRoot();
+
+	dstModel = (DefaultTreeModel) rolePanel.dstTree.getModel();
+	dstRoot = (DblTreeNode) dstModel.getRoot();
+
+	roleNodes = new DblTreeNode[vAllRoleObjs.size()];
+	roleTreeNodes = new RoleTreeNode[vAllRoleObjs.size()];
+
+	int n = 0;
+	Enumeration e = vAllRoleObjs.elements();
+
+	// Build an array of tree nodes that can be used for sorting.
+	while (e.hasMoreElements()) {
+	    String roleObj =  (String)e.nextElement();
+	    String roleName = roleObj;
+	    roleTreeNodes[n] = new RoleTreeNode(roleObj);
+	    n++;
+	}
+
+	// Sort the list of RoleTreeNode objects.
+
+	if (roleTreeNodes.length > 1) {
+	    NodeCompare comp = new NodeCompare();
+	    Sort.sort(roleTreeNodes, comp);
+	}
+
+	// With the sorted tree nodes, now we build the src tree.
+	for (int i = 0; i < roleTreeNodes.length; i++) {
+
+	    roleNodes[i] = new DblTreeNode((Object) roleTreeNodes[i]);
+
+	    srcModel.insertNodeInto(roleNodes[i], srcRoot, i);
+	    TreePath nodepath = new TreePath(roleNodes[i].getPath());
+
+	    // Make initial display of excluded list
+	    rolePanel.srcTree.scrollPathToVisible(nodepath);
+	}
+
+        String rolesStr = userObj.getRoles();
+	if (rolesStr == null)
+		return;
+
+        String[] assignedRoles = userObj.getRoles().split(",");
+        if (assignedRoles.length == 0) {
+            return;
+        }
+
+        // Move roles of current user from excluded list
+        // to included list.
+        // Note that a dimmed role will stay dimmed after the move.
+        // Therefore, a user can not "unassign" a dimmed role on the
+        // included list.
+
+        for (int i = 0; i < roleNodes.length; i++) {
+            boolean foundRole = false;
+            String roleString = roleNodes[i].toString();
+
+            for (int j = 0; j < assignedRoles.length; j++) {
+                if (roleString.equals(assignedRoles[j])) {
+                    foundRole = true;
+                    break;
+                }
+            }
+
+            if (foundRole) {
+                rolePanel.initLeaf(rolePanel.srcTree,
+                    rolePanel.dstTree, roleNodes[i]);
+            }
+        }
+
+    } // end loadRoleTrees
+
+    private Vector<String> getAvailableRoles() {
+        Vector<String> roles = new Vector<String>();
+	for (String s : panelDesc.getRoles()) {
+	    roles.add(s);
+
+	}
+    	return (roles);
+    }
+
+    public void setUser(UserManagedObject userObj) {
+    	this.userObj = userObj;
+	loadRoleTrees();
+    }
+
+    public UserManagedObject updateUser() {
+        Vector<String> vRoles = getAssignedRoles();
+	String rolesStr;
+
+	if (vRoles.size() > 0) {
+		rolesStr = vRoles.elementAt(0);
+	} else {
+		rolesStr = "";
+	}
+
+	for (int i = 1; i < vRoles.size(); i++) {
+	    rolesStr = rolesStr.concat(",");
+	    rolesStr = rolesStr.concat(vRoles.elementAt(i));
+        }
+	userObj.getRolesProperty().setValue(rolesStr);
+
+	return (userObj);
+    }
+
+    /**
+     * Get list of roles assigned to a user
+     */
+    public Vector<String> getAssignedRoles() {
+	Vector<String> newRoles = new Vector<String>();
+
+	if (isRoleListOK == false) {
+	    return newRoles;
+	}
+
+        DblTreeNode root = (DblTreeNode) dstModel.getRoot();
+        Enumeration kids;
+        kids = root.children();
+
+        while (kids.hasMoreElements()) {
+            DblTreeNode childNode;
+            childNode = (DblTreeNode)kids.nextElement();
+            newRoles.addElement(childNode.toString());
+        }
+
+	return newRoles;
+    }
+
+
+    class RoleTreeNode {
+
+        String name;
+        String roleObj = null;
+
+        public RoleTreeNode(String roleObj) {
+            this.roleObj = roleObj;
+            this.name = roleObj;
+        }
+
+        public String getRoleObj() {
+            return roleObj;
+        }
+
+        public String toString() {
+            return name;
+        }
+    }
+
+
+    class NodeCompare implements Compare {
+
+	/**
+	 * The compare method compares two RoleTreeNode objects by comparing
+	 * their role names.  The parameters are specified as Object class
+	 * objects for QuickSort.
+	 *
+	 * @param a - The first Node.
+	 * @param b - The second Node.
+	 *
+	 */
+        public final int doCompare(Object a, Object b) {
+
+            RoleTreeNode e1, e2;
+            String e1Name, e2Name;
+
+            e1 = (RoleTreeNode) a;
+            e2 = (RoleTreeNode)b;
+            e1Name = e1.toString();
+            e2Name = e2.toString();
+            return (e1Name.compareTo(e2Name));
+
+        }
+
+    }
+
+
+    class RoleRenderer extends DefaultTreeCellRenderer {
+
+        private boolean selected;
+        RolesPanel rightSubProps;
+
+        public RoleRenderer(RolesPanel rightSubProps) {
+
+	    this.rightSubProps = rightSubProps;
+            setClosedIcon(null);
+            setOpenIcon(null);
+            setLeafIcon(null);
+
+        }
+
+        public Component getTreeCellRendererComponent(
+            JTree tree,
+            Object value,
+            boolean selected,
+            boolean expanded,
+            boolean leaf,
+            int row,
+            boolean hasFocus) {
+
+            this.selected = selected;
+
+            DefaultTreeCellRenderer cr =
+                (DefaultTreeCellRenderer) tree.getCellRenderer();
+            cr.setLeafIcon(null);
+            DblTreeNode node = (DblTreeNode) value;
+
+            if (node.getParent() == null) {
+                // maybe the same as row == 0
+                setText(node.toString());
+
+            } else if (node.getUserObject() instanceof RoleTreeNode) {
+                RoleTreeNode rolesdef = (RoleTreeNode) node.getUserObject();
+                setText(rolesdef.toString());
+
+                if (selected) {
+                    if (node.isEnabled()) {
+                        cr.setTextSelectionColor(SystemColor.textText);
+                    } else {
+                        cr.setTextSelectionColor(
+			    SystemColor.inactiveCaptionText);
+		    }
+
+                } else {
+                    if (node.isEnabled()) {
+                        cr.setTextNonSelectionColor(SystemColor.textText);
+                    } else {
+
+                        cr.setTextNonSelectionColor(
+                        SystemColor.inactiveCaptionText);
+                    }
+                }
+            }
+
+            super.getTreeCellRendererComponent(tree, value, selected, expanded,
+                leaf, row, hasFocus);
+
+            return this;
+
+        } // end getTreeCellRendererComponent
+
+    } // RoleRenderer
+
+} // RolesPanel
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RolesSettings.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * Implements Advanced Settings for Roles
+ */
+public class RolesSettings extends AdvancedSettings {
+
+    private static final String NAME =
+    	Finder.getString("usermgr.advanced.roles");
+    private static final Icon ICON = Finder.getIcon(
+	"images/roles-24.png");
+
+    private UserMgrPanelDescriptor panelDesc = null;
+    private UserManagedObject userObj = null;
+    private RolesPanel panel = null;
+
+    public RolesSettings() {
+	super(NAME, ICON);
+    }
+
+    public void setUser(UserManagedObject userObj) {
+	if (panel == null) {
+		panel = new RolesPanel(panelDesc, userObj);
+	}
+	panel.setUser(userObj);
+	String roleStr = userObj.getRoles();
+	if (roleStr == null) {
+	    roleStr = "";
+	}
+	getProperty().update(roleStr, true);
+    }
+
+    public void updateUser() {
+	userObj = panel.updateUser();
+	String roleStr = userObj.getRoles();
+	if (roleStr == null) {
+	    roleStr = "";
+	}
+	getProperty().setValue(roleStr);
+    }
+
+    public boolean isChanged() {
+        if (userObj != null) {
+	    return (userObj.getRolesProperty().isChanged());
+	} else {
+	    return false;
+	}
+    }
+
+    public void init(UserMgrPanelDescriptor panelDesc) {
+	this.panelDesc = panelDesc;
+    }
+
+    public JPanel getPanel() {
+    	return panel;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/SelPanel.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,646 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.tree.*;
+import javax.accessibility.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.beans.*;
+import java.util.*;
+import java.io.*;
+
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * Selection Panel incorpoarting exclude/include trees
+ */
+public class SelPanel extends DoubleTrees {
+
+    public SelPanel() {
+
+	setListeners();
+
+    }
+
+    public SelPanel(String srcHeader, String dstHeader) {
+
+	super(srcHeader, dstHeader);
+	setListeners();
+
+    }
+
+    /**
+     * Create any dynamic images we need.
+     */
+    public void addNotify() {
+
+	super.addNotify();
+
+	delItem.setIcon(Finder.getIcon("images/remove.png"));
+	delItem.setHorizontalTextPosition(JButton.RIGHT);
+
+	delAllItem.setIcon(Finder.getIcon("images/remove_all.png"));
+	delAllItem.setHorizontalTextPosition(JButton.RIGHT);
+
+	addItem.setIcon(Finder.getIcon("images/add.png"));
+	addItem.setHorizontalTextPosition(JButton.LEFT);
+
+	addAllItem.setIcon(Finder.getIcon("images/add_all.png"));
+	addAllItem.setHorizontalTextPosition(JButton.LEFT);
+
+    } // addNotify
+
+
+    public void setListeners() {
+
+	addItem.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		move(srcTree, dstTree);
+	    }
+	});
+
+	delItem.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		move(dstTree, srcTree);
+	    }
+	});
+
+	addAllItem.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		moveAll(srcTree, dstTree);
+	    }
+	});
+
+	delAllItem.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		moveAll(dstTree, srcTree);
+	    }
+	});
+
+	MouseListener ml = new MouseAdapter() {
+	    public void mouseClicked(MouseEvent e) {
+		handleMouse(e);
+	    }
+	    public void mousePressed(MouseEvent e) {
+		handleMouse(e);
+	    }
+	};
+
+	srcTree.addMouseListener(ml);
+	dstTree.addMouseListener(ml);
+
+    }
+
+    private void handleMouse(MouseEvent e) {
+
+	JTree  tree1, tree2;
+
+	if (e.getSource() == srcTree) {
+	    tree1 = srcTree;
+	    tree2 = dstTree;
+	    addItem.setEnabled(true);
+	    delItem.setEnabled(false);
+	} else {
+	    tree1 = dstTree;
+	    tree2 = srcTree;
+	    addItem.setEnabled(false);
+	    delItem.setEnabled(true);
+	}
+	TreePath selPath = tree1.getPathForLocation(e.getX(), e.getY());
+
+	if (selPath != null) {
+	    tree2.clearSelection();
+	    int selCount = selPath.getPathCount();
+	    DblTreeNode node = (DblTreeNode)selPath.getLastPathComponent();
+	    if (e.getClickCount() == 1) {
+		// mySingleClick(tree1, selPath);
+	    } else if (e.getClickCount() == 2) {
+		if (node.isLeaf())
+		    move(tree1, tree2);
+	    }
+	}
+
+    }
+
+
+    public void move(JTree src, JTree dst) {
+
+	DblTreeNode node;
+
+	TreePath selPath = src.getSelectionPath();
+	if (selPath == null) // nothing selected (should be disabled)
+	    return;
+	else if (selPath.getPathCount() == 1)
+	    moveAll(src, dst);
+	else {
+	    node = (DblTreeNode)selPath.getLastPathComponent();
+
+	    if (node.isLeaf()) {
+		moveLeaf(src, dst, node);
+	    } else {  // node is branch
+		moveBranch(src, dst, node, true, true);
+	    }
+
+	    if (src == srcTree) {
+		addItem.setEnabled(false);
+		delItem.setEnabled(true);
+	    } else {
+		addItem.setEnabled(true);
+		delItem.setEnabled(false);
+	    }
+	}
+
+    }
+
+
+    private SelPTreeNode matchParent(
+	DblTreeNode parent,
+	DblTreeNode root,
+	DefaultTreeModel dstModel) {
+
+	Enumeration kids;
+	SelPTreeNode treeNode = new SelPTreeNode();
+	int level = parent.getLevel();
+	if (level == 0) {
+	    treeNode.newparent = root;
+	    return treeNode;
+	}
+
+	DblTreeNode [] nodes = new DblTreeNode[level];
+	nodes[level - 1] = parent;
+	for (int i = nodes.length; i > 1; i--) {
+	    nodes [i - 2] = (DblTreeNode) nodes[i - 1].getParent();
+	}
+
+	for (int i = 0; i < nodes.length; i++) {
+	    treeNode.newparent = null;
+	    treeNode.index = 0;
+	    String parentString = nodes[i].toString();
+	    kids = root.children();
+	    while (kids.hasMoreElements()) {
+		DblTreeNode testnode;
+		String teststring;
+		int diff;
+
+		testnode = (DblTreeNode)kids.nextElement();
+
+		diff = testnode.compareTo(nodes[i]);
+
+		if (diff == 0) { // matching branch
+		    treeNode.newparent = testnode;
+		    break;
+		} else if (testnode.isLeaf()) {
+		    treeNode.index++;
+		    continue;
+		} else if (diff < 0) {
+		    treeNode.index++;
+		    continue;
+		} else {
+		    break;
+		}
+	    }
+
+	    if (treeNode.newparent != null) {
+		root = treeNode.newparent;
+	    } else {
+		DblTreeNode newNode = (DblTreeNode)nodes[i].clone();
+		dstModel.insertNodeInto(newNode, root, treeNode.index);
+		treeNode.newparent = newNode;
+		root = newNode;
+	    }
+	}
+	return treeNode;
+
+    }
+
+
+    private int matchChild(JTree src,
+	JTree dst,
+	DblTreeNode srcNode,
+	DblTreeNode newparent,
+	Enumeration dstKids,
+	int index) {
+
+	DefaultTreeModel    srcModel = (DefaultTreeModel)src.getModel();
+	DefaultTreeModel    dstModel = (DefaultTreeModel)dst.getModel();
+
+	DblTreeNode dstNode = null;
+	String srcString = srcNode.toString();
+	while (dstKids.hasMoreElements()) {
+	    String teststring;
+
+	    dstNode = (DblTreeNode)dstKids.nextElement();
+	    if (dstNode.isLeaf() == false)
+		break;  // leaves come first
+	    teststring = dstNode.toString();
+	    if (teststring.compareTo(srcString) < 0) {
+		index++;
+		continue;
+	    } else {
+		break;
+	    }
+	}
+
+	srcModel.removeNodeFromParent(srcNode);
+	dstModel.insertNodeInto(srcNode, newparent, index);
+	index++;
+	return index;
+
+    }
+
+    public void moveBranch(JTree src, JTree dst, DblTreeNode parent,
+      boolean top, boolean select) {
+	initBranch(src, dst, parent, top, select, false);
+    }
+
+    public void initBranch(JTree src, JTree dst, DblTreeNode parent,
+	boolean top, boolean select, boolean force) {
+
+	DefaultTreeModel    srcModel = (DefaultTreeModel)src.getModel();
+	DefaultTreeModel    dstModel = (DefaultTreeModel)dst.getModel();
+	DblTreeNode newparent, clonedParent, root;
+
+	root = (DblTreeNode)dstModel.getRoot();
+
+	DblTreeNode [] kidsArray = new DblTreeNode[parent.getChildCount()];
+	Enumeration kids = parent.children();
+	int i = 0;
+	while (kids.hasMoreElements()) {
+	    kidsArray[i++] = (DblTreeNode)kids.nextElement();
+	}
+	int index = 0;
+
+	// find same branch in destination tree
+	SelPTreeNode treeNode = matchParent(parent, root, dstModel);
+	newparent = treeNode.newparent;
+
+	// add all the kids
+	// At this point we know there is at least one child of dst parent
+
+	for (i = 0; i < kidsArray.length; i++) {
+	    DblTreeNode srcNode = kidsArray[i];
+
+	    if (srcNode.isLeaf() == false) {
+		initBranch(src, dst, srcNode, false, false, force);
+		continue;
+	    }
+	    if (force == false && srcNode.isEnabled() == false)
+		continue;
+
+	    Enumeration dstKids = newparent.children();
+	    index = matchChild(src, dst, srcNode, newparent, dstKids, 0);
+	}
+
+	if (parent.isRoot() == false)
+	    while (parent.getChildCount() == 0) {
+		DblTreeNode grandParent;
+		grandParent = (DblTreeNode) parent.getParent();
+		srcModel.removeNodeFromParent(parent);
+		if (grandParent == null || grandParent.isRoot())
+		    break;
+		else
+		    parent = grandParent;
+	    }
+
+	if (newparent.getChildCount() == 0) {
+	    if (top)
+		while (newparent.getChildCount() == 0) {
+		    DblTreeNode grandParent;
+		    grandParent = (DblTreeNode) newparent.getParent();
+		    dstModel.removeNodeFromParent(newparent);
+		    if (grandParent == null || grandParent.isRoot())
+			break;
+		    else
+			newparent = grandParent;
+		}
+	    else
+		dstModel.removeNodeFromParent(newparent);
+	} else if (select) {
+	    TreePath nodepath = new TreePath(newparent.getPath());
+
+	    dst.expandPath(nodepath);
+	    // dst.makeVisible(nodepath);
+	    dst.setSelectionPath(nodepath);
+	    dst.scrollPathToVisible(nodepath);
+	}
+
+    }
+
+
+    public void moveLeaf(JTree src, JTree dst, DblTreeNode node) {
+
+	if (node.isEnabled())
+	    initLeaf(src, dst, node);
+	TreePath nodepath = new TreePath(node.getPath());
+	dst.setSelectionPath(nodepath);
+
+    }
+
+
+    public void initLeaf(JTree src, JTree dst, DblTreeNode node) {
+
+	DefaultTreeModel    srcModel = (DefaultTreeModel)src.getModel();
+	DefaultTreeModel    dstModel = (DefaultTreeModel)dst.getModel();
+	DblTreeNode parent, newparent, clonedParent, root;
+	int index = 0;
+	root = (DblTreeNode)dstModel.getRoot();
+
+	// find parent
+	parent = (DblTreeNode)node.getParent();
+
+	// find same branch in destination tree
+
+	SelPTreeNode treeNode = matchParent(parent, root, dstModel);
+	newparent = treeNode.newparent;
+
+	Enumeration kids = newparent.children();
+	index = matchChild(src, dst, node, newparent, kids, index);
+	TreePath nodepath = new TreePath(node.getPath());
+
+	dst.expandPath(nodepath);
+	dst.scrollPathToVisible(nodepath);
+
+	// check for last child
+	while ((parent.isRoot() == false)
+	    && parent.getChildCount() == 0) {
+	    DblTreeNode grandParent;
+	    grandParent = (DblTreeNode) parent.getParent();
+	    srcModel.removeNodeFromParent(parent);
+	    if (grandParent == null)
+		break;
+	    else
+		parent = grandParent;
+	}
+
+    }
+
+
+    public void moveAll(JTree src, JTree dst) {
+
+	DefaultTreeModel    srcModel = (DefaultTreeModel)src.getModel();
+	DblTreeNode srcRoot = (DblTreeNode)srcModel.getRoot();
+
+	src.clearSelection();
+	Enumeration kids = srcRoot.children();
+	DblTreeNode [] kidsArray = new DblTreeNode[srcRoot.getChildCount()];
+	int i = 0;
+	while (kids.hasMoreElements()) {
+	    kidsArray[i++] = (DblTreeNode)kids.nextElement();
+	}
+
+	for (i = 0; i < kidsArray.length; i++) {
+	    if (kidsArray[i].isLeaf())
+		moveLeaf(src, dst, kidsArray[i]);
+	    else
+		moveBranch(src, dst, kidsArray[i], true, false);
+
+	}
+	DblTreeNode dstRoot = (DblTreeNode)dst.getModel().getRoot();
+	if (dstRoot.getChildCount() > 0) {
+	    DblTreeNode child = (DblTreeNode)dstRoot.getFirstChild();
+	    TreePath nodepath = new TreePath(child.getPath());
+	    dst.setSelectionPath(nodepath);
+	    dst.scrollPathToVisible(nodepath);
+	}
+
+	if (src == srcTree) {
+	    addItem.setEnabled(false);
+	    delItem.setEnabled(true);
+	} else {
+	    addItem.setEnabled(true);
+	    delItem.setEnabled(false);
+	}
+    }
+
+
+    public boolean findNode(String findStr) {
+
+	DblTreeNode root;
+	DblTreeNode otherRoot;
+	DblTreeNode currentNode;
+	JTree currentTree;
+	JTree otherTree;
+	Enumeration searchNodes;
+	DefaultTreeModel    srcModel = (DefaultTreeModel)srcTree.getModel();
+	DefaultTreeModel    dstModel = (DefaultTreeModel)dstTree.getModel();
+
+	TreePath selPath = srcTree.getSelectionPath();
+	if (selPath == null) { // Try the other tree
+	    selPath = dstTree.getSelectionPath();
+	    if (selPath == null) { // Start at the upper left
+		return false;
+	    }
+	    currentTree = dstTree;
+	    otherTree = srcTree;
+	    root = (DblTreeNode)dstModel.getRoot();
+	    otherRoot = (DblTreeNode)srcModel.getRoot();
+
+	} else {
+	    currentTree = srcTree;
+	    otherTree = dstTree;
+	    root = (DblTreeNode)srcModel.getRoot();
+	    otherRoot = (DblTreeNode)dstModel.getRoot();
+	}
+
+	currentNode = (DblTreeNode)selPath.getLastPathComponent();
+
+	searchNodes = myRowFirstEnumeration(root, null);
+	Vector<DblTreeNode> fromTop = new Vector<DblTreeNode>();
+	while (searchNodes.hasMoreElements()) {
+	    DblTreeNode node = (DblTreeNode) searchNodes.nextElement();
+
+	    if (node == currentNode) {
+		while (searchNodes.hasMoreElements()) {
+		    node = (DblTreeNode) searchNodes.nextElement();
+		    String nodeStr = node.toString();
+		    if (nodeStr.lastIndexOf(findStr) != -1) {
+			TreePath nodepath = new TreePath(node.getPath());
+			currentTree.expandPath(nodepath);
+			currentTree.setSelectionPath(nodepath);
+			currentTree.scrollPathToVisible(nodepath);
+			return true;
+		    }
+		}
+	    } else {
+		fromTop.addElement(node);
+		continue;
+	    }
+	}
+
+	// Not found in remainder of current tree...
+
+	searchNodes = myRowFirstEnumeration(otherRoot, null);
+	while (searchNodes.hasMoreElements()) {
+	    DblTreeNode node = (DblTreeNode) searchNodes.nextElement();
+	    String nodeStr = node.toString();
+	    if (nodeStr.lastIndexOf(findStr) != -1) {
+		currentTree.clearSelection();
+		TreePath nodepath = new TreePath(node.getPath());
+		otherTree.expandPath(nodepath);
+		otherTree.setSelectionPath(nodepath);
+		otherTree.scrollPathToVisible(nodepath);
+
+		// Switch buttons
+
+		if (otherTree == srcTree) {
+		    addItem.setEnabled(true);
+		    delItem.setEnabled(false);
+		} else {
+		    addItem.setEnabled(false);
+		    delItem.setEnabled(true);
+		}
+	    return true;
+	    }
+	}
+
+	// Not found in other tree
+	// Try from top of current tree...
+
+	searchNodes = fromTop.elements();
+	while (searchNodes.hasMoreElements()) {
+	    DblTreeNode node = (DblTreeNode) searchNodes.nextElement();
+	    String nodeStr = node.toString();
+	    if (nodeStr.lastIndexOf(findStr) != -1) {
+		TreePath nodepath = new TreePath(node.getPath());
+		currentTree.expandPath(nodepath);
+		currentTree.setSelectionPath(nodepath);
+		currentTree.scrollPathToVisible(nodepath);
+		return true;
+	    } else
+		continue;
+	}
+	// Not found in current tree...
+	return false;
+
+    }
+
+    private Enumeration myRowFirstEnumeration(DblTreeNode root,
+    	Vector<DblTreeNode> v) {
+
+	if (v == null)
+	    v = new Vector<DblTreeNode>();
+	Enumeration kids = root.children();
+	while (kids.hasMoreElements()) {
+	    DblTreeNode node = (DblTreeNode)kids.nextElement();
+	    v.addElement(node);
+	    Enumeration gkids = myRowFirstEnumeration(node, v);
+	}
+	return v.elements();
+
+    }
+
+
+    public void refreshTrees() {
+
+	JTree currentTree;
+	JTree dummyTree;
+	TreePath selPath = srcTree.getSelectionPath();
+	if (selPath == null) {
+	    selPath = dstTree.getSelectionPath();
+	    if (selPath == null)
+		return;
+	    currentTree = dstTree;
+	} else {
+	    currentTree = srcTree;
+	}
+
+	DefaultTreeModel treeModel =
+	    new DefaultTreeModel(new DblTreeNode("dummy"));
+	dummyTree = new JTree(treeModel);
+
+	moveAll(srcTree, dummyTree);
+	moveAll(dummyTree, srcTree);
+	moveAll(dstTree, dummyTree);
+	moveAll(dummyTree, dstTree);
+
+	if (currentTree == srcTree) {
+	    addItem.setEnabled(true);
+	    delItem.setEnabled(false);
+	    dstTree.setSelectionPath(selPath);
+	} else {
+	    addItem.setEnabled(false);
+	    delItem.setEnabled(true);
+	    srcTree.setSelectionPath(selPath);
+	}
+
+    }
+
+    public void resetAll() {
+
+	DblTreeNode srcRoot = (DblTreeNode)srcTree.getModel().getRoot();
+	DblTreeNode dstRoot = (DblTreeNode)dstTree.getModel().getRoot();
+
+	dstTree.clearSelection();
+	Enumeration kids = dstRoot.children();
+	DblTreeNode [] kidsArray = new DblTreeNode[dstRoot.getChildCount()];
+	int i = 0;
+	while (kids.hasMoreElements()) {
+	    kidsArray[i++] = (DblTreeNode)kids.nextElement();
+	}
+
+	for (i = 0; i < kidsArray.length; i++) {
+	    if (kidsArray[i].isLeaf())
+		initLeaf(dstTree, srcTree, kidsArray[i]);
+	    else
+		initBranch(dstTree, srcTree, kidsArray[i], true, false, true);
+
+	}
+	if (srcRoot.getChildCount() > 0) {
+	    DblTreeNode child = (DblTreeNode)srcRoot.getFirstChild();
+	    TreePath nodepath = new TreePath(child.getPath());
+	    srcTree.setSelectionPath(nodepath);
+	    srcTree.scrollPathToVisible(nodepath);
+	}
+
+	addItem.setEnabled(true);
+	delItem.setEnabled(false);
+    }
+
+    public void resetModels() {
+	srcTree.setModel(new DefaultTreeModel(new DblTreeNode("All Items")));
+	dstTree.setModel(new DefaultTreeModel(new DblTreeNode("All Items")));
+    }
+}
+
+class SelPTreeNode {
+
+    DblTreeNode newparent;
+    int index;
+
+    public SelPTreeNode() {
+	newparent = null;
+	index = 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Sort.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,384 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * Sort: a class that uses the quicksort algorithm to sort an
+ *         array of objects.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.util.Vector;
+import java.util.Random;
+import java.lang.Math;
+
+@SuppressWarnings("unchecked")
+public class Sort {
+
+    private static Random rn = null;
+
+    private static int MAX_ELEMENTS_FOR_COPY = 15000;
+
+    static final int ASCENDING_SORT = 0;
+    static final int DESCENDING_SORT = 0;
+
+    private static void swap(Object arr[], int i, int j) {
+        Object tmp;
+
+        tmp = arr[i];
+        arr[i] = arr[j];
+        arr[j] = tmp;
+    }
+
+    /**
+     * quicksort the array of objects.
+     *
+     * @param arr[] - an array of objects
+     * @param left - the start index - from where to begin sorting
+     * @param right - the last index
+     * @param comp - object that implemnts the Compare interface
+     */
+    private static void quicksort(Object arr[], int left, int right,
+	Compare comp) {
+
+        int i, last;
+
+        if (left >= right) { /* do nothing if array contains fewer than two */
+	    return;    /* two elements */
+        }
+
+        swap(arr, left, left+(Math.abs(rn.nextInt())%(right-left)+1));
+        last = left;
+        for (i = left+1; i <= right; i++) {
+            if (comp.doCompare(arr[i], arr[left]) < 0) {
+                swap(arr, ++last, i);
+            }
+        }
+        swap(arr, left, last);
+
+        quicksort(arr, left, last-1, comp);
+        quicksort(arr, last+1, right, comp);
+    }
+
+    /**
+     * quicksort the array of strings.
+     *
+     * @param arr[] - an array of strings
+     * @param left - the start index - from where to begin sorting
+     * @param right - the last index.
+     * @param order - ASCENDING_SORT or DESCENDING_SORT
+     */
+    private static void quicksort(String arr[], int left, int right,
+	int order) {
+
+        int i, last;
+
+        if (left >= right) { /* do nothing if array contains fewer than two */
+	    return;	/* two elements */
+        }
+        swap(arr, left, left+(Math.abs(rn.nextInt())%(right-left)+1));
+        last = left;
+        for (i = left+1; i <= right; i++) {
+            if (order == ASCENDING_SORT) {
+                if (arr[i].compareTo(arr[left]) < 0) {
+                    swap(arr, ++last, i);
+                }
+            } else {
+                if (arr[i].compareTo(arr[left]) > 0) {
+                    swap(arr, ++last, i);
+                }
+            }
+        }
+        swap(arr, left, last);
+        quicksort(arr, left, last-1, order);
+        quicksort(arr, last+1, right, order);
+    }
+
+    private static void swap(Vector vec, int i, int j) {
+        Object tmp;
+
+        tmp = vec.elementAt(i);
+        vec.setElementAt(vec.elementAt(j), i);
+        vec.setElementAt(tmp, j);
+    }
+
+    /**
+     * quicksort the vector of objects.
+     *
+     * @param vec - a vector of objects
+     * @param left - the start index - from where to begin sorting
+     * @param right - the last index
+     * @param comp - object that implements the Compare interface
+     */
+    private static void quicksort(Vector vec, int left, int right,
+	Compare comp) {
+
+        int i, last;
+
+        if (left >= right) { /* do nothing if vector contains fewer than two */
+	    return;	/* two elements */
+        }
+        swap(vec, left, left+(Math.abs(rn.nextInt())%(right-left)+1));
+        last = left;
+        for (i = left+1; i <= right; i++) {
+            if (comp.doCompare(vec.elementAt(i), vec.elementAt(left)) < 0) {
+                swap(vec, ++last, i);
+            }
+        }
+        swap(vec, left, last);
+        quicksort(vec, left, last-1, comp);
+        quicksort(vec, last+1, right, comp);
+    }
+
+    /**
+     * quicksort the vector of strings.
+     *
+     * @param vec - a vector of strings
+     * @param left - the start index - from where to begin sorting
+     * @param right - the last index.
+     * @param order - ASCENDING_SORT or DESCENDING_SORT
+     */
+    private static void quicksort(Vector vec, int left, int right, int order) {
+        int i, last;
+
+        if (left >= right) { /* do nothing if vector contains fewer than two */
+	    return;		/* two elements */
+        }
+        swap(vec, left, left+(Math.abs(rn.nextInt())%(right-left)+1));
+        last = left;
+        for (i = left+1; i <= right; i++) {
+            if (order == ASCENDING_SORT) {
+               if (((String)(vec.elementAt(i))).compareTo(
+				(String)vec.elementAt(left)) < 0) {
+                   swap(vec, ++last, i);
+               }
+            } else {
+               if (((String)(vec.elementAt(i))).compareTo(
+				(String)vec.elementAt(left)) > 0) {
+                   swap(vec, ++last, i);
+               }
+            }
+        }
+        swap(vec, left, last);
+        quicksort(vec, left, last-1, order);
+        quicksort(vec, last+1, right, order);
+    }
+
+    /**
+     * quicksort the vector of objects.
+     *
+     * @param vec - a vector of objects
+     * @param left - the start index - from where to begin sorting
+     * @param right - the last index
+     * @param comp - object that implemnts the Compare interface
+     */
+    private static void quicksort(QuickVector vec, int left, int right,
+	Compare comp) {
+
+        int i, last;
+
+        if (left >= right) { /* do nothing if vector contains fewer than two */
+	    return;		/* two elements */
+        }
+        vec.quickSwapElementsAt(left,
+				left+(Math.abs(rn.nextInt())%(right-left)+1));
+        last = left;
+        for (i = left+1; i <= right; i++) {
+            if (comp.doCompare(vec.quickElementAt(i),
+				vec.quickElementAt(left)) < 0) {
+                vec.quickSwapElementsAt(++last, i);
+            }
+        }
+        vec.quickSwapElementsAt(left, last);
+        quicksort(vec, left, last-1, comp);
+        quicksort(vec, last+1, right, comp);
+    }
+
+    /**
+     * quicksort the vector of strings.
+     *
+     * @param vec - a vector of strings
+     * @param left - the start index - from where to begin sorting
+     * @param right - the last index.
+     * @param order - ASCENDING_SORT or DESCENDING_SORT
+     */
+    private static void quicksort(QuickVector vec, int left, int right,
+	int order) {
+
+        int i, last;
+
+        if (left >= right) { /* do nothing if vector contains fewer than two */
+	    return;		/* two elements */
+        }
+        vec.quickSwapElementsAt(left,
+				left+(Math.abs(rn.nextInt())%(right-left)+1));
+        last = left;
+        for (i = left+1; i <= right; i++) {
+            if (order == ASCENDING_SORT) {
+               if (((String)(vec.quickElementAt(i))).compareTo(
+				(String)vec.quickElementAt(left)) < 0) {
+                   vec.quickSwapElementsAt(++last, i);
+               }
+            } else {
+               if (((String)(vec.quickElementAt(i))).compareTo(
+				(String)vec.quickElementAt(left)) > 0) {
+                   vec.quickSwapElementsAt(++last, i);
+               }
+            }
+        }
+        vec.quickSwapElementsAt(left, last);
+        quicksort(vec, left, last-1, order);
+        quicksort(vec, last+1, right, order);
+    }
+
+    /**
+     * sort the array of objects.
+     *
+     * @param arr - a array of objects
+     * @param comp - object that implemnts the Compare interface
+     */
+    public static void sort(Object arr[], Compare comp) {
+        if (rn == null)
+            rn = new Random();
+        quicksort(arr, 0, arr.length-1, comp);
+    }
+
+    /**
+     * sort the array of strings.
+     *
+     * @param arr - an array of strings
+     * @param order - ASCENDING_SORT or DESCENDING_SORT
+     */
+    public static void sort(String arr[], int order) {
+        if (rn == null)
+            rn = new Random();
+        quicksort(arr, 0, arr.length-1, order);
+    }
+
+    /**
+     * sort the array of strings in ascending order
+     *
+     * @param arr - an array of strings
+     */
+    public static void sort(String arr[]) {
+        sort(arr, ASCENDING_SORT);
+    }
+
+    /**
+     * sort the vector of objects.
+     *
+     * @param vec - a vector of objects
+     * @param comp - object that implemnts the Compare interface
+     */
+    public static void sort(Vector vec, Compare comp) {
+        if (rn == null)
+            rn = new Random();
+        if (vec.size() > MAX_ELEMENTS_FOR_COPY) {
+            // Would use up too much memory, so have to do an in place sort
+            quicksort(vec, 0, vec.size()-1, comp);
+        } else {
+            // For small vector, optimize the sort by copying to an array
+            // first
+            Object[] arr = new Object[vec.size()];
+            vec.copyInto(arr);
+            quicksort(arr, 0, arr.length-1, comp);
+            for (int i = 0; i < arr.length; i++) {
+                vec.setElementAt(arr[i], i);
+            }
+        }
+    }
+
+    /**
+     * sort the vector of strings.
+     *
+     * @param vec - a vector of strings
+     * @param order - ASCENDING_SORT or DESCENDING_SORT
+     */
+    public static void sort(Vector vec, int order) {
+        if (rn == null)
+            rn = new Random();
+        if (vec.size() > MAX_ELEMENTS_FOR_COPY) {
+            // Would use up too much memory, so have to do an in place sort
+            quicksort(vec, 0, vec.size()-1, order);
+        } else {
+            // For small vector, we can optimize the sort by copying to an array
+            // first
+            String[] arr = new String[vec.size()];
+            vec.copyInto(arr);
+            vec.removeAllElements();
+            quicksort(arr, 0, arr.length-1, order);
+            vec.setSize(arr.length);
+            for (int i = 0; i < arr.length; i++) {
+                vec.setElementAt(arr[i], i);
+            }
+        }
+    }
+
+    /**
+     * sort the vector of strings in ascending order
+     *
+     * @param vec - a vector of strings
+     */
+    public static void sort(Vector vec) {
+        sort(vec, ASCENDING_SORT);
+    }
+
+    /**
+     * sort the vector of objects.
+     *
+     * @param vec - a vector of objects
+     * @param comp - object that implemnts the Compare interface
+     */
+    public static void sort(QuickVector vec, Compare comp) {
+        if (rn == null)
+            rn = new Random();
+        quicksort(vec, 0, vec.size()-1, comp);
+    }
+
+    /**
+     * sort the vector of strings.
+     *
+     * @param vec - a vector of strings
+     * @param order - ASCENDING_SORT or DESCENDING_SORT
+     */
+    public static void sort(QuickVector vec, int order) {
+        if (rn == null)
+            rn = new Random();
+        quicksort(vec, 0, vec.size()-1, order);
+    }
+
+    /**
+     * sort the vector of strings in ascending order
+     *
+     * @param vec - a vector of strings
+     */
+    public static void sort(QuickVector vec) {
+        sort(vec, ASCENDING_SORT);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/TableMap.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,101 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.table.*;
+import javax.swing.event.TableModelListener;
+import javax.swing.event.TableModelEvent;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * In a chain of data manipulators some behaviour is common. TableMap
+ * provides most of this behavour and can be subclassed by filters
+ * that only need to override a handful of specific methods. TableMap
+ * implements TableModel by routing all requests to its model, and
+ * TableModelListener by routing all events to its listeners. Inserting
+ * a TableMap which has not been subclassed into a chain of table filters
+ * should have no effect.
+ *
+ * (This code taken from the Swing table examples.)
+ *
+ */
+public class TableMap extends AbstractTableModel implements TableModelListener {
+
+	protected TableModel model;
+
+	public TableModel  getModel() {
+		return model;
+	}
+
+	public void  setModel(TableModel model) {
+		this.model = model;
+		model.addTableModelListener(this);
+	}
+
+	// By default, Implement TableModel by forwarding all messages
+	// to the model.
+
+	public Object getValueAt(int aRow, int aColumn) {
+		return model.getValueAt(aRow, aColumn);
+	}
+
+	public void setValueAt(Object aValue, int aRow, int aColumn) {
+		model.setValueAt(aValue, aRow, aColumn);
+	}
+
+	public int getRowCount() {
+		return (model == null) ? 0 : model.getRowCount();
+	}
+
+	public int getColumnCount() {
+		return (model == null) ? 0 : model.getColumnCount();
+	}
+
+	public String getColumnName(int aColumn) {
+		return model.getColumnName(aColumn);
+	}
+
+	public Class getColumnClass(int aColumn) {
+		return model.getColumnClass(aColumn);
+	}
+
+	public boolean isCellEditable(int row, int column) {
+		return model.isCellEditable(row, column);
+	}
+
+
+	//
+	// Implementation of the TableModelListener interface,
+	//
+
+	// By default forward all events to all the listeners.
+	public void tableChanged(TableModelEvent e) {
+		fireTableChanged(e);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/TableSorter.java	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,351 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import java.util.*;
+
+import javax.swing.table.TableModel;
+import javax.swing.event.TableModelEvent;
+
+// Imports for picking up mouse events from the JTable.
+
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.InputEvent;
+import javax.swing.JTable;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * A sorter for TableModels. The sorter has a model (conforming to TableModel)
+ * and itself implements TableModel. TableSorter does not store or copy
+ * the data in the TableModel, instead it maintains an array of
+ * integers which it keeps the same size as the number of rows in its
+ * model. When the model changes it notifies the sorter that something
+ * has changed eg. "rowsAdded" so that its internal array of integers
+ * can be reallocated. As requests are made of the sorter (like
+ * getValueAt(row, col) it redirects them to its model via the mapping
+ * array. That way the TableSorter appears to hold another copy of the table
+ * with the rows in a different order. The sorting algorthm used is stable
+ * which means that it does not move around rows when its comparison
+ * function returns 0 to denote that they are equivalent.
+ *
+ * (This code taken from the Swing table examples.)
+ *
+ */
+public class TableSorter extends TableMap {
+
+    int	indexes[];
+    Vector<Integer> sortingColumns = new Vector<Integer>();
+    boolean    ascending = true;
+    int	compares;
+
+    public TableSorter() {
+	indexes = new int[0]; // For consistency.
+    }
+
+    public TableSorter(TableModel model) {
+	setModel(model);
+    }
+
+    public void setModel(TableModel model) {
+	super.setModel(model);
+	reallocateIndexes();
+    }
+
+    public int compareRowsByColumn(int row1, int row2, int column) {
+	Class type = model.getColumnClass(column);
+	TableModel data = model;
+
+	// Check for nulls
+
+	Object o1 = data.getValueAt(row1, column);
+	Object o2 = data.getValueAt(row2, column);
+
+	// If both values are null return 0
+	if (o1 == null && o2 == null)
+	    return 0;
+	else if (o1 == null) // Define null less than everything.
+	    return -1;
+	else if (o2 == null)
+	    return 1;
+
+	// We copy all returned values from the getValue call in case
+	// an optimised model is reusing one object to return many values.
+	// The Number subclasses in the JDK are immutable and so will not
+	// be used in this way but other subclasses of Number might want
+	// to do this to save space and avoid unnecessary heap allocation.
+
+	if (type.getSuperclass() == java.lang.Number.class) {
+	    Number n1 = (Number)data.getValueAt(row1, column);
+	    double d1 = n1.doubleValue();
+	    Number n2 = (Number)data.getValueAt(row2, column);
+	    double d2 = n2.doubleValue();
+
+	    if (d1 < d2)
+		return -1;
+	    else if (d1 > d2)
+		return 1;
+	    else
+		return 0;
+	} else if (type == java.util.Date.class) {
+	    Date d1 = (Date)data.getValueAt(row1, column);
+	    long n1 = d1.getTime();
+	    Date d2 = (Date)data.getValueAt(row2, column);
+	    long n2 = d2.getTime();
+
+	    if (n1 < n2)
+		return -1;
+	    else if (n1 > n2)
+		return 1;
+	    else
+		return 0;
+	} else if (type == String.class) {
+	    String s1 = (String)data.getValueAt(row1, column);
+	    String s2    = (String)data.getValueAt(row2, column);
+	    int result = s1.compareTo(s2);
+
+	    if (result < 0)
+		return -1;
+	    else if (result > 0)
+		return 1;
+	    else
+		return 0;
+	} else if (type == Boolean.class) {
+	    Boolean bool1 = (Boolean)data.getValueAt(row1, column);
+	    boolean b1 = bool1.booleanValue();
+	    Boolean bool2 = (Boolean)data.getValueAt(row2, column);
+	    boolean b2 = bool2.booleanValue();
+
+	    if (b1 == b2)
+		return 0;
+	    else if (b1) // Define false < true
+		return 1;
+	    else
+		return -1;
+	} else {
+	    Object v1 = data.getValueAt(row1, column);
+	    String s1 = v1.toString();
+	    Object v2 = data.getValueAt(row2, column);
+	    String s2 = v2.toString();
+	    int result = s1.compareTo(s2);
+
+	    if (result < 0)
+		return -1;
+	    else if (result > 0)
+		return 1;
+	    else
+		return 0;
+	}
+    }
+
+    public int compare(int row1, int row2) {
+	compares++;
+	for (int level = 0; level < sortingColumns.size(); level++) {
+	    Integer column = sortingColumns.elementAt(level);
+	    int result = compareRowsByColumn(row1, row2, column.intValue());
+	    if (result != 0)
+		return ascending ? result : -result;
+	}
+	return 0;
+    }
+
+    public void  reallocateIndexes() {
+	int rowCount = model.getRowCount();
+
+	// Set up a new array of indexes with the right number of elements
+	// for the new data model.
+	indexes = new int[rowCount];
+
+	// Initialise with the identity mapping.
+	for (int row = 0; row < rowCount; row++)
+	    indexes[row] = row;
+    }
+
+
+    /**
+     * Return the index of the row in the model whose data is being displayed
+     * in the row viewRowIndex in the display.  Returns viewRowIndex unchanged
+     * viewRowIndex is less than zero.  Returns -1 if there are no rows or
+     * viewRowIndex exceeds the number of rows.
+     */
+    public int convertRowIndexToModel(int viewRowIndex) {
+	if (viewRowIndex < 0)
+	    return viewRowIndex;
+
+	if ((indexes.length == 0) || (viewRowIndex >= indexes.length))
+	    return -1;
+
+	return indexes[viewRowIndex];
+    }
+
+    public void tableChanged(TableModelEvent e) {
+	reallocateIndexes();
+
+	super.tableChanged(e);
+    }
+
+    public void checkModel() {
+	if (indexes.length != model.getRowCount())
+	    System.err.println("Sorter not informed of a change in model.");
+    }
+
+    public void  sort(Object sender) {
+	checkModel();
+
+	compares = 0;
+	// n2sort();
+	// qsort(0, indexes.length-1);
+	shuttlesort(indexes.clone(), indexes, 0, indexes.length);
+    }
+
+    public void n2sort() {
+	for (int i = 0; i < getRowCount(); i++) {
+	    for (int j = i+1; j < getRowCount(); j++) {
+		if (compare(indexes[i], indexes[j]) == -1) {
+		    swap(i, j);
+		}
+	    }
+	}
+    }
+
+    // This is a home-grown implementation which we have not had time
+    // to research - it may perform poorly in some circumstances. It
+    // requires twice the space of an in-place algorithm and makes
+    // NlogN assigments shuttling the values between the two
+    // arrays. The number of compares appears to vary between N-1 and
+    // NlogN depending on the initial order but the main reason for
+    // using it here is that, unlike qsort, it is stable.
+    public void shuttlesort(int from[], int to[], int low, int high) {
+
+	if (high - low < 2)
+	    return;
+
+	int middle = (low + high)/2;
+	shuttlesort(to, from, low, middle);
+	shuttlesort(to, from, middle, high);
+
+	int p = low;
+	int q = middle;
+
+	// This is an optional short-cut; at each recursive call,
+	// check to see if the elements in this subset are already
+	// ordered.  If so, no further comparisons are needed; the
+	// sub-array can just be copied.  The array must be copied rather
+	// than assigned otherwise sister calls in the recursion might
+	// get out of sinc.  When the number of elements is three they
+	// are partitioned so that the first set, [low, mid), has one
+	// element and and the second, [mid, high), has two. We skip the
+	// optimisation when the number of elements is three or less as
+	// the first compare in the normal merge will produce the same
+	// sequence of steps. This optimisation seems to be worthwhile
+	// for partially ordered lists but some analysis is needed to
+	// find out how the performance drops to Nlog(N) as the initial
+	// order diminishes - it may drop very quickly.
+
+	if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) {
+	    for (int i = low; i < high; i++)
+		to[i] = from[i];
+
+	    return;
+	}
+
+	// A normal merge.
+
+	for (int i = low; i < high; i++) {
+	    if (q >= high || (p < middle && compare(from[p], from[q]) <= 0))
+		to[i] = from[p++];
+	    else
+		to[i] = from[q++];
+	}
+    }
+
+    public void swap(int i, int j) {
+	int tmp = indexes[i];
+	indexes[i] = indexes[j];
+	indexes[j] = tmp;
+    }
+
+    // The mapping only affects the contents of the data rows.
+    // Pass all requests to these rows through the mapping array: "indexes".
+
+    public Object getValueAt(int aRow, int aColumn) {
+	checkModel();
+	if (indexes.length == 0)
+	    return null;
+	return model.getValueAt(indexes[aRow], aColumn);
+    }
+
+    public void setValueAt(Object aValue, int aRow, int aColumn) {
+	checkModel();
+	model.setValueAt(aValue, indexes[aRow], aColumn);
+    }
+
+    public void sortByColumn(int column) {
+	sortByColumn(column, true);
+    }
+
+    public void sortByColumn(int column, boolean ascending) {
+	this.ascending = ascending;
+	sortingColumns.removeAllElements();
+	sortingColumns.addElement(new Integer(column));
+	sort(this);
+	super.tableChanged(new TableModelEvent(this));
+    }
+
+    // There is no-where else to put this.
+    // Add a mouse listener to the Table to trigger a table sort
+    // when a column heading is clicked in the JTable.
+    public void addMouseListenerToHeaderInTable(JTable table) {
+
+	final TableSorter sorter = this;
+	final JTable tableView = table;
+
+	tableView.setColumnSelectionAllowed(false);
+
+	MouseAdapter listMouseListener = new MouseAdapter() {
+	    public void mouseClicked(MouseEvent e) {
+		TableColumnModel columnModel = tableView.getColumnModel();
+		int viewColumn = columnModel.getColumnIndexAtX(e.getX());
+		int column = tableView.convertColumnIndexToModel(viewColumn);
+		if (e.getClickCount() == 1 && column != -1) {
+		    int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK;
+		    boolean ascending = (shiftPressed == 0);
+		    sorter.sortByColumn(column, ascending);
+		}
+	    }
+	};
+
+	JTableHeader th = tableView.getTableHeader();
+	th.addMouseListener(listMouseListener);
+    }
+
+} // TableSorter
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserManagedObject.java	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserManagedObject.java	Fri Apr 27 00:52:26 2012 -0400
@@ -25,15 +25,18 @@
 
 package com.oracle.solaris.vp.panels.usermgr.client.swing;
 
-import java.util.List;
+import java.util.*;
 import javax.swing.*;
 import com.oracle.solaris.vp.panel.common.model.AbstractManagedObject;
-import com.oracle.solaris.vp.panels.usermgr.*;
+import com.oracle.solaris.rad.usermgr.*;
 import com.oracle.solaris.vp.util.misc.*;
 import com.oracle.solaris.vp.util.misc.finder.Finder;
 import com.oracle.solaris.vp.util.misc.property.*;
 import com.oracle.solaris.vp.util.swing.HasIcon;
 
+/**
+ * User Managed Object represents user object
+ */
 @SuppressWarnings({"serial"})
 public class UserManagedObject
     extends AbstractManagedObject<UserManagedObject> implements HasIcon {
@@ -41,19 +44,16 @@
     //
     // Static data
     //
+    public static final String PASSWORD = "PASSWORD";
+    public static final String NOTACTIVE = "NOTACTIVATED";
+
 
     // Icons - for user, roles
     protected static final List<ImageIcon> userIcons = Finder.getIcons(
-	"images/config-users-16.png",
-	"images/config-users-22.png",
-	"images/config-users-24.png",
-	"images/config-users-32.png");
+	"images/user-24.png");
 
     protected static final List<ImageIcon> roleIcons = Finder.getIcons(
-	"images/config-roles-16.png",
-	"images/config-roles-22.png",
-	"images/config-roles-24.png",
-	"images/config-roles-32.png");
+	"images/role-24.png");
 
     //
     // Instance data
@@ -62,6 +62,7 @@
     private UserMgrPanelDescriptor descriptor;
     private UserType type = UserType.NORMAL;
     private boolean isNewUser = false;
+    private UserChangeFieldsImpl modChanges = null;
 
     private MutableProperty<Long> groupIdProperty =
 	new LongProperty();
@@ -69,8 +70,17 @@
     private MutableProperty<String> homeDirProperty =
 	new StringProperty();
 
-    private MutableProperty<Boolean> isAdminProperty =
-	new BooleanProperty();
+    private MutableProperty<String> rightsProperty =
+	new StringProperty();
+
+    private MutableProperty<String> rolesProperty =
+	new StringProperty();
+
+    private MutableProperty<String> groupsProperty =
+	new StringProperty();
+
+    private MutableProperty<String> authsProperty =
+	new StringProperty();
 
     private MutableProperty<String> shellProperty =
 	new StringProperty();
@@ -84,12 +94,16 @@
     private MutableProperty<String> userNameProperty =
 	new StringProperty();
 
+    private MutableProperty<String> accountStatusProperty =
+	new StringProperty();
+
     private MutableProperty<char[]> passProperty =
 	new BasicMutableProperty<char[]>();
     {
         ChangeableAggregator aggregator = getChangeableAggregator();
 	aggregator.addChangeables(groupIdProperty, homeDirProperty,
-	    isAdminProperty, passProperty, shellProperty,
+	    passProperty, shellProperty,
+	    rolesProperty, rightsProperty, authsProperty, groupsProperty,
 	    userDescProperty, userIdProperty, userNameProperty);
     }
 
@@ -98,7 +112,7 @@
     //
 
     UserManagedObject(UserMgrPanelDescriptor descriptor,
-	User user, UserType type, boolean isAdministrator,
+	User user, UserType type,
 	char[] password, boolean bNewUser) {
 
 	this.descriptor = descriptor;
@@ -111,13 +125,22 @@
 	groupIdProperty.update(user.getGroupID(), true);
 	homeDirProperty.update(user.getHomeDirectory(), true);
 	shellProperty.update(user.getDefaultShell(), true);
-	passProperty.update(password, true);
-	isAdminProperty.update(isAdministrator, true);
+
+	rolesProperty.update(listToString(user.getRoles()), true);
+	rightsProperty.update(listToString(user.getProfiles()), true);
+	authsProperty.update(listToString(user.getAuths()), true);
+	groupsProperty.update(listToString(user.getGroups()), true);
+	accountStatusProperty.update(user.getAccountStatus() == null ? ""
+		: user.getAccountStatus(), true);
+
+	if (password != null) {
+	    passProperty.update(password, true);
+        }
     }
 
     UserManagedObject(UserMgrPanelDescriptor descriptor,
 	User user, char[] password) {
-	this(descriptor, user, UserType.NORMAL, false, password, true);
+	this(descriptor, user, UserType.NORMAL, password, true);
     }
 
     //
@@ -148,19 +171,34 @@
     @Override
     public String toString() {
 	StringBuilder sb = new StringBuilder();
-	sb.append("\n\tuser name: ").append(getUsername())
-	    .append("\n\tuserID: ").append(getUserId())
-	    .append("\n\tgroupID: ").append(getGroupId())
+	sb.append("\n\tname: ").append(getUsername())
+	    .append("\n\tuid: ").append(getUserId())
+	    .append("\n\tgid: ").append(getGroupId())
 	    .append("\n\tdescription: ").append(getUserDescription())
 	    .append("\n\thome dir: ").append(getHomedir())
-	    .append("\n\tdefault shell: ").append(getShell())
-	    .append("\n\tuser type: ")
-	    .append(type == UserType.NORMAL ? "normal" : "role")
-	    .append("\n\tadmin: ")
-	    .append(isAdministrator() ? "true" : "false");
+	    .append("\n\tshell: ").append(getShell())
+	    .append("\n\ttype: ")
+	    .append(type == UserType.NORMAL ? "user" : "role")
+	    .append("\n\trights: ").append(getRights())
+	    .append("\n\tauths: ").append(getAuths())
+	    .append("\n\tgroups: ").append(getGroups())
+	    .append("\n\troles: ").append(getRoles())
+	    .append("\n\tstatus: ").append(getAccountStatus());
 	return sb.toString();
     }
 
+    public void setUser(User user, char[] password) {
+
+	userNameProperty.update(user.getUsername(), true);
+	userDescProperty.update(user.getDescription(), true);
+	userIdProperty.update(user.getUserID(), true);
+	groupIdProperty.update(user.getGroupID(), true);
+	homeDirProperty.update(user.getHomeDirectory(), true);
+	shellProperty.update(user.getDefaultShell(), true);
+
+	passProperty.update(password, true);
+    }
+
     //
     // UserManagedObject methods
     //
@@ -173,8 +211,21 @@
 	return homeDirProperty;
     }
 
-    public MutableProperty<Boolean> getIsAdminProperty() {
-	return isAdminProperty;
+
+    public MutableProperty<String> getRightsProperty() {
+	return rightsProperty;
+    }
+
+    public MutableProperty<String> getRolesProperty() {
+	return rolesProperty;
+    }
+
+    public MutableProperty<String> getGroupsProperty() {
+	return groupsProperty;
+    }
+
+    public MutableProperty<String> getAuthsProperty() {
+	return authsProperty;
     }
 
     public MutableProperty<String> getUserDescProperty() {
@@ -209,10 +260,6 @@
 	return userDescProperty.getValue();
     }
 
-    public boolean isAdministrator() {
-	return isAdminProperty.getValue();
-    }
-
     public long getUserId() {
 	return userIdProperty.getValue();
     }
@@ -237,11 +284,31 @@
 	return type;
     }
 
+    public String getRights() {
+	return rightsProperty.getValue();
+    }
+
+    public String getRoles() {
+	return rolesProperty.getValue();
+    }
+
+    public String getGroups() {
+	return groupsProperty.getValue();
+    }
+
+    public String getAuths() {
+	return authsProperty.getValue();
+    }
+
+    public String getAccountStatus() {
+	return accountStatusProperty.getValue();
+    }
+
     public boolean isUserNormal() {
 	return type == UserType.NORMAL;
     }
 
-    public boolean isUserRole() {
+    public boolean isRole() {
 	return type == UserType.ROLE;
     }
 
@@ -249,6 +316,14 @@
 	return isNewUser;
     }
 
+    public boolean hasPassword() {
+        if (getAccountStatus().equals(PASSWORD)) {
+	    return (true);
+	}
+
+	return (false);
+    }
+
     // Update the "auto-generated" properties for the newly created user
     public void updateUser(User user) {
 	userIdProperty.update(user.getUserID(), true);
@@ -258,6 +333,7 @@
 
     // Construct a new User object from the defined properties
     public User getNewUser() {
+
 	UserImpl newUser = new UserImpl();
 	newUser.setUsername(getUsername());
 	newUser.setUserID(getUserId());
@@ -267,7 +343,27 @@
 	    newUser.setHomeDirectory(getHomedir());
 	else // must be null
 	    newUser.setHomeDirectory(null);
+
 	newUser.setDefaultShell(getShell());
+
+	if (getRights() != null) {
+	    // System.out.println("new user rights:" + getRights());
+	    newUser.setProfiles(stringToList(getRights()));
+	}
+
+	if (getRoles() != null) {
+	    // System.out.println("new user roles:" + getRoles());
+	    newUser.setRoles(stringToList(getRoles()));
+	}
+
+	if (getAuths() != null) {
+	    newUser.setAuths(stringToList(getAuths()));
+	}
+
+	if (getGroups() != null) {
+	    newUser.setGroups(stringToList(getGroups()));
+	}
+
 	return newUser;
     }
 
@@ -275,6 +371,8 @@
     public User getModifiedUser() {
 	boolean bChanged = false;
 	UserImpl modUser = new UserImpl();
+	modChanges = new UserChangeFieldsImpl();
+
 	// check each property for changes
 	if (userDescProperty.isChanged()) {
 	    modUser.setDescription(getUserDescription());
@@ -291,7 +389,35 @@
 	if (passProperty.isChanged()) {
 	    bChanged = true;
 	}
-	// If *only* the admin property is changed, the User object is not used.
+
+	if (rightsProperty.isChanged()) {
+	    // System.out.println("mod user rights " + getRights());
+	    modUser.setProfiles(stringToList(getRights()));
+	    modChanges.setProfilesChanged(true);
+	    bChanged = true;
+	}
+
+	if (rolesProperty.isChanged()) {
+	    // System.out.println("mod user roles " + getRoles());
+	    modUser.setRoles(stringToList(getRoles()));
+	    modChanges.setRolesChanged(true);
+	    bChanged = true;
+	}
+
+	if (authsProperty.isChanged()) {
+	    // System.out.println("mod user auths " + getAuths());
+	    modUser.setAuths(stringToList(getAuths()));
+	    modChanges.setAuthsChanged(true);
+	    bChanged = true;
+	}
+
+	if (groupsProperty.isChanged()) {
+	    // System.out.println("mod user groups " + getGroups());
+	    modUser.setGroups(stringToList(getGroups()));
+	    modChanges.setGroupsChanged(true);
+	    bChanged = true;
+	}
+
 	if (bChanged) {
 	    modUser.setUsername(getUsername());
 	} else {
@@ -300,4 +426,40 @@
 
 	return modUser;
     }
+
+    public String listToString(List<String> list) {
+	String str;
+
+	if (list == null) {
+	    return ("");
+	}
+
+	if (list.size() > 0) {
+		str = list.get(0);
+	} else {
+		str = "";
+	}
+
+	for (int i = 1; i < list.size(); i++) {
+	    str = str.concat(",");
+	    str = str.concat(list.get(i));
+        }
+
+	return (str);
+    }
+
+    public List<String> stringToList(String str) {
+	List<String> list = new ArrayList<String>();
+	String[] strings = str.split(",");
+
+	for (String s : strings) {
+	    list.add(s);
+        }
+
+	return (list);
+    }
+
+    public UserChangeFieldsImpl getModifiedChanges() {
+        return (modChanges);
+    }
 }
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrAdvancedControl.java	Thu Apr 26 00:14:30 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
- */
-
-package com.oracle.solaris.vp.panels.usermgr.client.swing;
-
-import java.util.List;
-import com.oracle.solaris.vp.panel.common.action.*;
-import com.oracle.solaris.vp.panel.common.control.Control;
-import com.oracle.solaris.vp.panel.swing.control.SettingsControl;
-import com.oracle.solaris.vp.panels.usermgr.Group;
-import com.oracle.solaris.vp.util.misc.finder.Finder;
-
-public class UserMgrAdvancedControl
-    extends SettingsControl<UserMgrPanelDescriptor, UserMgrAdvancedPanel> {
-
-    //
-    // Static data
-    //
-    public static final String ID = "advanced";
-    public static final String NAME = Finder.getString("usermgr.advanced.name");
-
-    //
-    // Instance data
-    //
-
-    private UserMgrControl parent;
-
-    //
-    // Constructor
-    //
-    public UserMgrAdvancedControl(UserMgrControl parent) {
-        super(ID, NAME, parent.getPanelDescriptor());
-	this.parent = parent;
-
-    }
-
-    //
-    // Control methods
-    //
-
-    @Override
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	// Always save changes on the client
-	return UnsavedChangesAction.SAVE;
-    }
-
-    @Override
-    protected boolean isChanged() {
- 	// Save unconditionally for now
-  	return true;
-    }
-
-    @Override
-    protected void save() throws ActionAbortedException,
-        ActionFailedException, ActionUnauthorizedException {
-
-	UserMgrAdvancedPanel panel = getComponent();
-	UserManagedObject umo = parent.getUserManagedObject();
-
-	setPropertyChangeIgnore(true);
-	// Set changed values from the panel
-	if (panel.getGroupNameProperty().isChanged()) {
-	    umo.getGroupIdProperty().setValue(toGid(
-		panel.getGroupNameProperty().getValue()));
-	}
-
-	if (panel.getShellProperty().isChanged()) {
-	    umo.getShellProperty().setValue(
-		panel.getShellProperty().getValue());
-	}
-
-	try {
-	    if (umo.isNewUser()) {
-		if (panel.getUserIdProperty().isChanged()) {
-		    Long luid = panel.getUserIdProperty().getValue();
-		    UserMgrUtils.validateUID(luid);
-		    umo.getUserIdProperty().setValue(luid);
-		}
-		if (panel.getHomeDirProperty().isChanged()) {
-		    String homeDir = panel.getHomeDirProperty().getValue();
-		    UserMgrUtils.validateHomeDir(homeDir);
-		    umo.getHomeDirProperty().setValue(homeDir);
-		}
-	    }
-	} catch (NumberFormatException nfe) {
-	    throw new ActionFailedException(
-		Finder.getString("usermgr.advanced.error.uid.bad"));
-	} finally {
-	    setPropertyChangeIgnore(false);
-	}
-    }
-
-    //
-    // SwingControl Methods
-    //
-
-    @Override
-    protected UserMgrAdvancedPanel createComponent() {
-	return new UserMgrAdvancedPanel();
-    }
-
-    @Override
-    protected void initComponent() {
-	UserMgrAdvancedPanel panel = getComponent();
-	// Initialize the fields
-	panel.init(parent.getPanelDescriptor(), parent.getUserManagedObject());
-    }
-
-    //
-    // Private Methods
-    //
-    private long toGid(String gName) {
-	List<Group> groups = parent.getPanelDescriptor().getGroups();
- 	for (Group g : groups) {
-	    if (gName.equals(g.getGroupName()))
- 		return (g.getGroupID());
- 	}
- 	return 1L;
-    }
-}
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrAdvancedPanel.java	Thu Apr 26 00:14:30 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,275 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
- */
-
-package com.oracle.solaris.vp.panels.usermgr.client.swing;
-
-import java.awt.EventQueue;
-import javax.swing.*;
-import com.oracle.solaris.vp.panel.swing.view.ChangeIndicator;
-import com.oracle.solaris.vp.panels.usermgr.Group;
-import com.oracle.solaris.vp.util.misc.ChangeableAggregator;
-import com.oracle.solaris.vp.util.misc.finder.Finder;
-import com.oracle.solaris.vp.util.misc.property.*;
-import com.oracle.solaris.vp.util.swing.*;
-import com.oracle.solaris.vp.util.swing.layout.*;
-import com.oracle.solaris.vp.util.swing.property.ComboBoxPropertySynchronizer;
-
-@SuppressWarnings({"serial"})
-public class UserMgrAdvancedPanel extends SettingsPanel {
-    //
-    // Instance data
-    //
-    private JLabel userIdLabel;
-    private HintTextField userIdField;
-    private ChangeIndicator userIdChange;
-    private JLabel userIdROLabel;
-    private JLabel userIdROField;
-    private JLabel userIdROSpacer;
-    private JLabel homeDirLabel;
-    private HintTextField homeDirField;
-    private ChangeIndicator homeDirChange;
-    private JLabel homeDirROLabel;
-    private JLabel homeDirROField;
-    private JLabel homeDirROSpacer;
-    private JComboBox groupNameCombo;
-    private JComboBox shellCombo;
-    private MutableProperty<String> groupNameProperty = new StringProperty();
-    private MutableProperty<Long> userIdProperty = new LongProperty();
-    private MutableProperty<String> homeDirProperty = new StringProperty();
-    private MutableProperty<String> shellProperty = new StringProperty();
-
-    {
-        ChangeableAggregator aggregator = getChangeableAggregator();
-	aggregator.addChangeables(userIdProperty, groupNameProperty,
-	    homeDirProperty, shellProperty);
-    }
-
-    //
-    // Constructors
-    //
-
-    public UserMgrAdvancedPanel() {
-	JPanel form = createForm();
-	setContent(form, false, false);
-    }
-
-    //
-    // Advanced panel methods
-    //
-    public MutableProperty<Long> getUserIdProperty() {
-	return userIdProperty;
-    }
-
-    public MutableProperty<String> getHomeDirProperty() {
-	return homeDirProperty;
-    }
-
-    public MutableProperty<String> getGroupNameProperty() {
-	return groupNameProperty;
-    }
-
-    public MutableProperty<String> getShellProperty() {
-	return shellProperty;
-    }
-
-    public void init(UserMgrPanelDescriptor descriptor, UserManagedObject umo) {
-	// Sanity check -- the UI should be updated only on the event thread
-	assert EventQueue.isDispatchThread();
-
-	// Show editable vs. non-editable fields, init labels
-	showFields(umo.isNewUser());
-	initLabels(umo.isUserNormal());
-
-	// user id
- 	if (!umo.isNewUser()) {
-	    userIdROField.setText(Long.toString(umo.getUserId()));
- 	}
-	userIdProperty.update(umo.getUserIdProperty().getSavedValue(), false);
-
-	// homedir
- 	if (!umo.isNewUser()) {
-	    homeDirROField.setText(umo.getHomedir());
- 	}
-	homeDirProperty.update(umo.getHomeDirProperty().getSavedValue(), false);
-
-	// group
-	long gid = umo.getGroupId();
-	String gname = null;
-	long savedGid = umo.getGroupIdProperty().getSavedValue();
-	String savedGname = null;
-	if (groupNameCombo.getItemCount() > 0)
-	    groupNameCombo.removeAllItems();
-	for (Group g : descriptor.getGroups()) {
-	    groupNameCombo.addItem(g.getGroupName());
-	    if (gid == g.getGroupID())
-		gname = g.getGroupName();
-	    if (savedGid == g.getGroupID())
-		savedGname = g.getGroupName();
-	}
-	groupNameProperty.update(savedGname, false);
-	groupNameCombo.setSelectedItem(gname);
-
-	// shell
-	if (shellCombo.getItemCount() > 0)
-	    shellCombo.removeAllItems();
-	for (String s : descriptor.getShells())
-	    shellCombo.addItem(s);
-	shellProperty.update(umo.getShellProperty().getSavedValue(), false);
-	shellCombo.setSelectedItem(umo.getShell());
-    }
-
-    //
-    // Private methods
-    //
-
-    private JPanel createForm() {
-	// Create the form elements
-        int hGap = GUIUtil.getHalfGap();
-	int width = GUIUtil.getTextFieldWidth();
-
-	// User Id
-        userIdLabel = new JLabel();
-	userIdField = new HintTextField(width);
-	userIdField.setHintText(
-	    Finder.getString("usermgr.advanced.value.auto"));
-	userIdField.setDocument(new NumericDocument());
-	new HintTextPropertySynchronizer<Long>(userIdProperty,
-	    userIdField, 0L);
-	userIdChange = new ChangeIndicator();
-	userIdProperty.addChangeListener(userIdChange);
-	userIdProperty.save();
-
-	// Readonly fields
-    	userIdROLabel = new JLabel();
-	userIdROField = new JLabel();
-	userIdROSpacer = new JLabel();
-
-	// Group Name
-	JLabel groupNameLabel = new JLabel(
-	    Finder.getString("usermgr.advanced.label.group"));
-	groupNameCombo = new JComboBox();
-	new ComboBoxPropertySynchronizer<String>
-	    (groupNameProperty, groupNameCombo);
-	ChangeIndicator groupNameChange = new ChangeIndicator();
-	groupNameProperty.addChangeListener(groupNameChange);
-
-	// Home Directory
-	homeDirLabel = new JLabel(
-	    Finder.getString("usermgr.advanced.label.homedir"));
-	homeDirField = new HintTextField(width);
-	homeDirField.setHintText(
-	    Finder.getString("usermgr.advanced.value.auto"));
-	new HintTextPropertySynchronizer<String>(homeDirProperty,
-	    homeDirField, "");
-	homeDirChange = new ChangeIndicator();
-	homeDirProperty.addChangeListener(homeDirChange);
-
-	// Readonly fields
-	homeDirROLabel = new JLabel(
-	    Finder.getString("usermgr.advanced.label.homedir"));
-	homeDirROField = new JLabel();
-	homeDirROSpacer = new JLabel();
-
-	// Login Shell
-	JLabel shellLabel = new JLabel(
-	    Finder.getString("usermgr.advanced.label.shell"));
-	shellCombo = new JComboBox();
-	new ComboBoxPropertySynchronizer<String>(shellProperty, shellCombo);
-	ChangeIndicator shellChange = new ChangeIndicator();
-	shellProperty.addChangeListener(shellChange);
-
-	showFields(false);
-
-	// Create the form and add the form elements
-	JPanel formPanel = new JPanel();
-	formPanel.setOpaque(false);
-	Form form = new Form(formPanel, VerticalAnchor.TOP);
-
-	ColumnLayoutConstraint col = new ColumnLayoutConstraint(
-	    HorizontalAnchor.FILL, hGap);
-	HasAnchors a = new SimpleHasAnchors(
-	    HorizontalAnchor.LEFT, VerticalAnchor.CENTER);
-
-	form.addTable(3, hGap, hGap, HorizontalAnchor.LEFT, col);
-	form.add(userIdLabel, a);
-	form.add(userIdField, a);
-	form.add(userIdChange, a);
-
-	form.add(userIdROLabel, a);
-	form.add(userIdROField, a);
-	form.add(userIdROSpacer, a);
-
-        form.add(groupNameLabel, a);
-        form.add(groupNameCombo, a);
-        form.add(groupNameChange, a);
-
-        form.add(homeDirLabel, a);
-        form.add(homeDirField, a);
-        form.add(homeDirChange, a);
-
-        form.add(homeDirROLabel, a);
-        form.add(homeDirROField, a);
-        form.add(homeDirROSpacer, a);
-
-        form.add(shellLabel, a);
-        form.add(shellCombo, a);
-	form.add(shellChange, a);
-
-	return formPanel;
-    }
-
-    private void showFields(boolean bNewUser) {
-	// Editable
-	userIdLabel.setVisible(bNewUser);
-	userIdField.setVisible(bNewUser);
-	userIdChange.setVisible(bNewUser);
-	homeDirLabel.setVisible(bNewUser);
-	homeDirField.setVisible(bNewUser);
-	homeDirChange.setVisible(bNewUser);
-	// Readonly
-	userIdROLabel.setVisible(!bNewUser);
-	userIdROField.setVisible(!bNewUser);
-	userIdROSpacer.setVisible(!bNewUser);
-	homeDirROLabel.setVisible(!bNewUser);
-	homeDirROField.setVisible(!bNewUser);
-	homeDirROSpacer.setVisible(!bNewUser);
-    }
-
-    private void initLabels(boolean bNormalUser) {
-	if (bNormalUser) {
-	    // Normal user
-	    userIdLabel.setText(
-		Finder.getString("usermgr.advanced.label.uid"));
-	    userIdROLabel.setText(
-		Finder.getString("usermgr.advanced.label.uid"));
-	} else {
-	    // Role
-	    userIdLabel.setText(
-		Finder.getString("usermgr.advanced.label.roleid"));
-	    userIdROLabel.setText(
-		Finder.getString("usermgr.advanced.label.roleid"));
-	}
-    }
-}
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicControl.java	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicControl.java	Fri Apr 27 00:52:26 2012 -0400
@@ -25,9 +25,13 @@
 
 package com.oracle.solaris.vp.panels.usermgr.client.swing;
 
+
+import java.util.List;
+import java.util.Map;
+import com.oracle.solaris.rad.usermgr.*;
 import com.oracle.solaris.vp.panel.common.action.*;
-import com.oracle.solaris.vp.panel.common.control.Control;
-import com.oracle.solaris.vp.panel.swing.control.SettingsControl;
+import com.oracle.solaris.vp.panel.common.control.*;
+import com.oracle.solaris.vp.panel.swing.control.*;
 import com.oracle.solaris.vp.util.misc.finder.Finder;
 
 public class UserMgrBasicControl
@@ -36,21 +40,19 @@
     //
     // Static data
     //
-    public static final String ID = "basic";
-    public static final String NAME = Finder.getString("usermgr.basic.name");
+    public static final String ID = "usermgr";
+    public static final String PARAM_USER = "user";
+    private UserMgrPanelDescriptor descriptor;
 
     //
     // Instance data
     //
 
-    private UserMgrControl parent;
+    private UserManagedObject userMO;
 
-    //
-    // Constructor
-    //
-    public UserMgrBasicControl(UserMgrControl parent) {
-        super(ID, NAME, parent.getPanelDescriptor());
-	this.parent = parent;
+    public UserMgrBasicControl(UserMgrPanelDescriptor descriptor) {
+        super(ID, PARAM_USER, descriptor);
+	this.descriptor = descriptor;
     }
 
     //
@@ -58,11 +60,17 @@
     //
 
     @Override
+    public boolean isBrowsable() {
+	// This control requires init parameters
+	return false;
+    }
+
+    @Override
     protected boolean isChanged() {
-	// Save unconditionally for now
 	return true;
     }
 
+
     @Override
     protected UnsavedChangesAction getUnsavedChangesAction() {
 	// Always save changes on the client
@@ -74,32 +82,41 @@
         ActionFailedException, ActionUnauthorizedException {
 
 	UserMgrBasicPanel panel = getComponent();
-	UserManagedObject umo = parent.getUserManagedObject();
+	UserManagedObject umo = getUserManagedObject();
 
 	setPropertyChangeIgnore(true);
-	try {
-	    // Set the values from the panel
-	    if (panel.getUserDescProperty().isChanged()) {
-		String userdesc = panel.getUserDescProperty().getValue();
-		UserMgrUtils.validateUserDesc(userdesc);
-		umo.getUserDescProperty().setValue(userdesc);
-	    }
+
+	// Set changed values from the panel
+	if (panel.getGroupProperty().isChanged()) {
+	    umo.getGroupIdProperty().setValue(toGid(
+		panel.getGroupProperty().getValue()));
+	}
+
+	if (panel.getShellProperty().isChanged()) {
+	    umo.getShellProperty().setValue(
+		panel.getShellProperty().getValue());
+	}
 
-	    if (panel.getIsAdminProperty().isChanged()) {
-		boolean admin = panel.getIsAdminProperty().getValue();
-		umo.getIsAdminProperty().setValue(admin);
-	    }
+	// Set the values from the panel
+	if (panel.getDescProperty().isChanged()) {
+	    String userdesc = panel.getDescProperty().getValue();
+	    UserMgrUtils.validateUserDesc(userdesc);
+	    umo.getUserDescProperty().setValue(userdesc);
+	 }
 
-	    if (panel.getPassProperty().isChanged() ||
-		panel.getPassConfirmProperty().isChanged()) {
-		char[] pass1 = panel.getPassProperty().getValue();
-		char[] pass2 = panel.getPassConfirmProperty().getValue();
-		UserMgrUtils.validatePassword(umo.isNewUser(), pass1, pass2);
-		umo.getPassProperty().setValue(pass1);
-	    }
-	} finally {
-	    setPropertyChangeIgnore(false);
-	}
+	 if (panel.getHomeProperty().isChanged()) {
+	    String homeDir = panel.getHomeProperty().getValue();
+	    UserMgrUtils.validateHomeDir(homeDir);
+	    umo.getHomeDirProperty().setValue(homeDir);
+	 }
+
+	 if (panel.getPassProperty().isChanged() ||
+	    panel.getPassConfirmProperty().isChanged()) {
+	    char[] pass1 = panel.getPassProperty().getValue();
+	    char[] pass2 = panel.getPassConfirmProperty().getValue();
+	    UserMgrUtils.validatePassword(umo.isNewUser(), pass1, pass2);
+	    umo.getPassProperty().setValue(pass1);
+	 }
     }
 
     //
@@ -108,16 +125,72 @@
 
     @Override
     protected UserMgrBasicPanel createComponent() {
-        UserMgrBasicPanel panel = new UserMgrBasicPanel();
+        UserMgrBasicPanel panel = new UserMgrBasicPanel(descriptor);
         return panel;
     }
 
     @Override
     protected void initComponent() {
 	UserMgrBasicPanel panel = getComponent();
-	UserManagedObject umo = parent.getUserManagedObject();
+	UserManagedObject umo = getUserManagedObject();
 
 	// Initialize the panel
-	panel.init(umo);
+	panel.init(getPanelDescriptor(), umo);
+    }
+
+    private long toGid(String gName) {
+	List<Group> groups = getPanelDescriptor().getGroups();
+ 	for (Group g : groups) {
+	    if (gName.equals(g.getGroupName()))
+ 		return (g.getGroupID());
+ 	}
+ 	return 1L;
+    }
+
+    @Override
+    public void start(Navigator navigator, Map<String, String> parameters)
+	throws NavigationAbortedException, InvalidParameterException,
+	NavigationFailedException {
+
+	String param = getParameter(parameters, PARAM_USER);
+  	UserManagedObject umo =
+	    getPanelDescriptor().getUserManagedObject(param);
+	if (umo == null) {
+	    throw new InvalidParameterException(getId(), PARAM_USER, param);
+  	}
+
+  	setUserManagedObject(umo);
+
+ 	super.start(navigator, parameters);
+    }
+
+    @Override
+    public void stop(boolean isCancel) throws NavigationAbortedException {
+ 	super.stop(isCancel);
+ 	setUserManagedObject(null);
+    }
+
+    //
+    // UserMgrControl methods
+    //
+
+    public UserManagedObject getUserManagedObject() {
+	return userMO;
+    }
+
+    //
+    // Private methods
+    //
+
+    private void setUserManagedObject(UserManagedObject umo) {
+	this.userMO = umo;
+	setName(umo == null ? null : umo.getName());
+    }
+
+    /**
+     * Clear the advanced settings change state.
+     */
+    public void clearChanges() {
+        getComponent().clearChanges();
     }
 }
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicPanel.java	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicPanel.java	Fri Apr 27 00:52:26 2012 -0400
@@ -25,23 +25,48 @@
 
 package com.oracle.solaris.vp.panels.usermgr.client.swing;
 
-import java.awt.EventQueue;
+import java.awt.*;
+import java.awt.event.*;
 import javax.swing.*;
+import javax.swing.border.Border;
 import com.oracle.solaris.vp.panel.swing.view.ChangeIndicator;
 import com.oracle.solaris.vp.util.misc.ChangeableAggregator;
 import com.oracle.solaris.vp.util.misc.finder.Finder;
 import com.oracle.solaris.vp.util.misc.property.*;
+import com.oracle.solaris.rad.usermgr.*;
 import com.oracle.solaris.vp.util.swing.*;
 import com.oracle.solaris.vp.util.swing.layout.*;
 import com.oracle.solaris.vp.util.swing.property.*;
 
+/**
+ * User Manager Basic panel
+ */
 @SuppressWarnings({"serial"})
-public class UserMgrBasicPanel extends SettingsPanel {
+public class UserMgrBasicPanel extends SettingsPanel
+    implements ActionListener {
+    private static final String ACTION_ADV_SETTINGS = "settings";
+
     //
     // Inner class
     //
+    private JLabel nameLabel;
+    private JLabel nameField;
+    private JLabel uidLabel;
+    private JLabel uidField;
+    private JLabel descLabel;
+    private JTextField findField;
+    private JTextField descField;
+    private JComboBox groupCombo;
+    private HintTextField homeField;
+    private JComboBox shellCombo;
+    private UserManagedObject umo;
+    private AdvancedSettingsDialog advDialog = null;
+    private ActionString actString = null;
+    ChangeIndicator settingsChange;
+    String changepassStr;
 
     public class PasswordPanel extends LinkCollapsiblePane {
+
 	//
 	// Instance data
 	//
@@ -63,23 +88,31 @@
 	public PasswordPanel() {
 	    super(GUIUtil.getHalfGap());
 
-	    int width = GUIUtil.getTextFieldWidth();
+	    changepassStr = Finder.getString("usermgr.basic.label.changepass");
 
-	    passLabel = new JLabel(
-		Finder.getString("usermgr.basic.label.pass"));
+	    int width = GUIUtil.getTextFieldWidth();
+	    actString = new ActionString("usermgr.basic.label.pass");
+            passLabel = new JLabel(actString.getString());
+            passLabel.setDisplayedMnemonic(actString.getMnemonic());
+
 	    passField = new JPasswordField(width);
 	    new PasswordFieldPropertySynchronizer(passProperty, passField);
 	    ChangeIndicator passChange = new ChangeIndicator();
 	    passProperty.addChangeListener(passChange);
+	    passLabel.setLabelFor(passField);
 
-	    passConfirmLabel = new JLabel(
-		Finder.getString("usermgr.basic.label.passconfirm"));
+	    actString = new ActionString("usermgr.basic.label.passconfirm");
+            passConfirmLabel = new JLabel(actString.getString());
+            passConfirmLabel.setDisplayedMnemonic(actString.getMnemonic());
+
 	    passConfirmField = new JPasswordField(width);
 	    new PasswordFieldPropertySynchronizer(
 		passConfirmProperty, passConfirmField);
 	    ChangeIndicator passConfirmChange = new ChangeIndicator();
 	    passConfirmProperty.addChangeListener(passConfirmChange);
 
+	    passConfirmLabel.setLabelFor(passConfirmField);
+
 	    // Create the form and the form elements
 	    JPanel formPanel = new JPanel();
 	    formPanel.setOpaque(false);
@@ -119,7 +152,7 @@
 
 	@Override
 	public String getLinkText(boolean collapsed) {
-	    return Finder.getString("usermgr.basic.label.changepass");
+	    return (changepassStr);
 	}
 
 	//
@@ -141,40 +174,55 @@
     private ChangeableAggregator aggregator;
     private PasswordPanel passPanel;
 
-    private JLabel userNameLabel;
-    private JLabel userNameValue;
-    private JLabel userDescLabel;
+    private MutableProperty<String> descProperty = new StringProperty();
+    private MutableProperty<String> groupProperty = new StringProperty();
+    private MutableProperty<String> homeProperty = new StringProperty();
+    private MutableProperty<String> shellProperty = new StringProperty();
+    private MutableProperty<Boolean> settingsProperty = new BooleanProperty();
 
-    private MutableProperty<String> userDescProperty =
-	new StringProperty();
-    private MutableProperty<Boolean> isAdminProperty =
-	new BooleanProperty();
+    private UserMgrPanelDescriptor descriptor;
 
     //
     // Constructors
     //
 
-    public UserMgrBasicPanel() {
+    public UserMgrBasicPanel(UserMgrPanelDescriptor descriptor) {
+        this.descriptor = descriptor;
 	JPanel form = createForm();
 	setContent(form, false, false);
 
         aggregator = getChangeableAggregator();
-	aggregator.addChangeables(userDescProperty);
-	aggregator.addChangeables(isAdminProperty);
+	aggregator.addChangeables(descProperty);
+	aggregator.addChangeables(groupProperty);
+	aggregator.addChangeables(homeProperty);
+	aggregator.addChangeables(shellProperty);
+	aggregator.addChangeables(settingsProperty);
 	aggregator.addChangeables(getPassProperty());
 	aggregator.addChangeables(getPassConfirmProperty());
     }
 
     //
-    // BasicUserMgrPanel methods
+    // UserMgrBasicPanel methods
     //
 
-    public MutableProperty<String> getUserDescProperty() {
-	return userDescProperty;
+    public MutableProperty<String> getDescProperty() {
+	return descProperty;
+    }
+
+    public MutableProperty<String> getGroupProperty() {
+	return groupProperty;
     }
 
-    public MutableProperty<Boolean> getIsAdminProperty() {
-	return isAdminProperty;
+    public MutableProperty<String> getHomeProperty() {
+	return homeProperty;
+    }
+
+    public MutableProperty<String> getShellProperty() {
+	return shellProperty;
+    }
+
+    public MutableProperty<Boolean> getSettingsProperty() {
+	return settingsProperty;
     }
 
     public MutableProperty<char[]> getPassProperty() {
@@ -185,24 +233,67 @@
 	return passPanel.passConfirmProperty;
     }
 
-    public void init(UserManagedObject umo) {
+    public void init(UserMgrPanelDescriptor paneldesc, UserManagedObject umo) {
 	// Sanity check -- the UI should be updated only on the event thread
 	assert EventQueue.isDispatchThread();
 
-	// Toggle the labels for roles
-	initLabels(umo.isUserNormal());
+
+	this.umo = umo;
+	descriptor = paneldesc;
 
 	// Set the current and saved values for each property
-	userNameValue.setText(umo.getName());
+	nameField.setText(umo.getName());
+	Long uidValue = new Long(umo.getUserId());
+	uidField.setText(uidValue.toString());
+
+	descProperty.update(umo.getUserDescProperty().getSavedValue(), false);
+	descField.setText(umo.getUserDescription());
 
-	userDescProperty.update(
-	    umo.getUserDescProperty().getSavedValue(), false);
-	isAdminProperty.update(umo.getIsAdminProperty().getSavedValue(), false);
+	// group
+	long gid = umo.getGroupId();
+	String gname = null;
+	long savedGid = umo.getGroupIdProperty().getSavedValue();
+	String savedGname = null;
+	if (groupCombo.getItemCount() > 0)
+	    groupCombo.removeAllItems();
+	for (Group g : descriptor.getGroups()) {
+	    groupCombo.addItem(g.getGroupName());
+	    if (gid == g.getGroupID())
+		gname = g.getGroupName();
+	    if (savedGid == g.getGroupID())
+		savedGname = g.getGroupName();
+	}
+	groupProperty.update(savedGname, false);
+	groupCombo.setSelectedItem(gname);
+
+	// homedir
+ 	if (!umo.isNewUser()) {
+	    homeField.setText(umo.getHomedir());
+ 	}
+	homeProperty.update(umo.getHomeDirProperty().getSavedValue(), false);
+
+	// shell
+	if (shellCombo.getItemCount() > 0)
+	    shellCombo.removeAllItems();
+	for (String s : descriptor.getShells())
+	    shellCombo.addItem(s);
+	shellProperty.update(umo.getShellProperty().getSavedValue(), false);
+	shellCombo.setSelectedItem(umo.getShell());
+
+	// Password
 	getPassProperty().update(umo.getPassProperty().getSavedValue(), false);
 	getPassConfirmProperty().update(
 	    umo.getPassProperty().getSavedValue(), false);
 
-	passPanel.setCollapsed(!getPassProperty().isChanged());
+	if (umo.hasPassword()) {
+	    changepassStr = Finder.getString("usermgr.basic.label.changepass");
+	} else {
+	    changepassStr = Finder.getString("usermgr.basic.label.initialpass");
+	}
+
+	passPanel.setCollapsed(true);
+
+	settingsProperty.update(false, true);
     }
 
     //
@@ -210,76 +301,191 @@
     //
 
     private JPanel createForm() {
-	// Create the form elements
-	// User name - Readonly
-        userNameLabel = new JLabel();
-        userNameValue = new JLabel();
+	JPanel form = new JPanel(new GridBagLayout());
+	GridBagConstraints gbc = new GridBagConstraints();
+	int width = GUIUtil.getTextFieldWidth();
+        int hGap = GUIUtil.getHalfGap();
+
+	gbc.weightx = 1.0;
+	gbc.anchor = GridBagConstraints.LINE_START;
+	gbc.fill = GridBagConstraints.NONE;
+	gbc.insets = new Insets(0, 0, hGap, hGap);
+
+	// User name
+	actString = new ActionString("usermgr.basic.name." +
+	    descriptor.getTypeString());
+        nameLabel = new JLabel(actString.getString());
+
+	nameField = new JLabel();
+
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy = 0;
+        form.add(nameLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(nameField, gbc);
+	form.add(new Spacer(), gbc);
 
-	// User Description
-	userDescLabel = new JLabel();
-	JTextField userDescField = GUIUtil.createTextField();
+	// Description
+	actString = new ActionString("usermgr.basic.desc." +
+	    descriptor.getTypeString());
+        descLabel = new JLabel(actString.getString());
+        descLabel.setDisplayedMnemonic(actString.getMnemonic());
+	descField = GUIUtil.createTextField();
 	new TextComponentPropertySynchronizer<String, JTextField>(
-	    userDescProperty, userDescField);
-	ChangeIndicator userDescChange = new ChangeIndicator();
-	userDescProperty.addChangeListener(userDescChange);
+	    descProperty, descField);
+	ChangeIndicator descChange = new ChangeIndicator();
+	descProperty.addChangeListener(descChange);
+
+	// Connect the label to the field
+	descLabel.setLabelFor(descField);
+
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(descLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(descField, gbc);
+        form.add(descChange, gbc);
+
+	// User ID
+	actString = new ActionString("usermgr.basic.uid." +
+	    descriptor.getTypeString());
+        uidLabel = new JLabel(actString.getString());
+	uidField = new JLabel();
+
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(uidLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(uidField, gbc);
+	form.add(new Spacer(), gbc);
 
-	// Is Administrator
-	JCheckBox isAdminCheckBox = new JCheckBox(
-	    Finder.getString("usermgr.basic.label.enableadmin"));
-	new CheckBoxPropertySynchronizer(
-	    isAdminProperty, isAdminCheckBox);
-	ChangeIndicator isAdminChange = new ChangeIndicator();
-	isAdminProperty.addChangeListener(isAdminChange);
-	isAdminCheckBox.setSelected(false);
+	// Group Name
+	actString = new ActionString("usermgr.basic.label.group");
+        JLabel groupLabel = new JLabel(actString.getString());
+        groupLabel.setDisplayedMnemonic(actString.getMnemonic());
+	groupCombo = new JComboBox();
+	new ComboBoxPropertySynchronizer<String>(groupProperty, groupCombo);
+
+	for (Group g : descriptor.getGroups()) {
+	    groupCombo.addItem(g.getGroupName());
+	}
+	ChangeIndicator groupChange = new ChangeIndicator();
+	groupProperty.addChangeListener(groupChange);
+
+	// Connect the label to the field
+	groupLabel.setLabelFor(groupCombo);
+
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(groupLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(groupCombo, gbc);
+        form.add(groupChange, gbc);
+
+	// Home Directory
+	actString = new ActionString("usermgr.basic.label.home");
+        JLabel homeLabel = new JLabel(actString.getString());
+        homeLabel.setDisplayedMnemonic(actString.getMnemonic());
+
+	homeField = new HintTextField(width);
+	homeField.setHintText(Finder.getString("usermgr.new.value.auto"));
+	new HintTextPropertySynchronizer<String>(homeProperty, homeField, "");
+
+	ChangeIndicator homeChange = new ChangeIndicator();
+	homeProperty.addChangeListener(homeChange);
 
-	// Create the form and add the form elements
-	JPanel formPanel = new JPanel();
-	formPanel.setOpaque(false);
-	Form form = new Form(formPanel, VerticalAnchor.TOP);
+	// Connect the label to the field
+	homeLabel.setLabelFor(homeField);
+
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(homeLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(homeField, gbc);
+        form.add(homeChange, gbc);
 
+	// Login Shell
+	actString = new ActionString("usermgr.basic.label.shell");
+        JLabel shellLabel = new JLabel(actString.getString());
+        shellLabel.setDisplayedMnemonic(actString.getMnemonic());
+	shellCombo = new JComboBox();
+	new ComboBoxPropertySynchronizer<String>(shellProperty, shellCombo);
+	for (String s : descriptor.getShells())
+	    shellCombo.addItem(s);
+	ChangeIndicator shellChange = new ChangeIndicator();
+	shellProperty.addChangeListener(shellChange);
+
+	// Connect the label to the field
+	shellLabel.setLabelFor(shellCombo);
+
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+        form.add(shellLabel, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+        form.add(shellCombo, gbc);
+        form.add(shellChange, gbc);
+
+	// Change Password
+	gbc.gridx = 0;
+	gbc.gridy++; // next row
+	gbc.weightx = 0.0;
+	gbc.gridwidth = GridBagConstraints.REMAINDER;
 	passPanel = new PasswordPanel();
+        form.add(passPanel, gbc);
 
-        int hGap = GUIUtil.getHalfGap();
-	ColumnLayoutConstraint col = new ColumnLayoutConstraint(
-	    HorizontalAnchor.FILL, hGap);
-	RowLayoutConstraint row = new RowLayoutConstraint(
-	    VerticalAnchor.CENTER, hGap);
-	HasAnchors a = new SimpleHasAnchors(
-	    HorizontalAnchor.LEFT, VerticalAnchor.CENTER);
-
-	form.addTable(3, hGap, hGap*2, HorizontalAnchor.LEFT, col);
+	// Advanced Settings
+	actString = new ActionString("usermgr.advanced.settings");
+	JButton advSettings = new JButton(actString.getString());
+	advSettings.setActionCommand(ACTION_ADV_SETTINGS);
+	advSettings.addActionListener(this);
+	advSettings.setMnemonic(actString.getMnemonic());
+	settingsChange = new ChangeIndicator();
+	settingsProperty.addChangeListener(settingsChange);
 
-        form.add(userNameLabel, a);
-        form.add(userNameValue, a);
-	form.add(new Spacer(), a);
-
-        form.add(userDescLabel, a);
-        form.add(userDescField, a);
-        form.add(userDescChange, a);
+	// Add to the layout
+	gbc.gridx = 0;
+	gbc.gridy++;
+	gbc.gridwidth = 1; // GridBagConstraints.RELATIVE;
+	gbc.weighty = 1.0;
+	gbc.anchor = GridBagConstraints.LAST_LINE_START;
+	form.add(advSettings, gbc);
+	gbc.gridx = GridBagConstraints.RELATIVE;
+	gbc.gridwidth = 0;
+        form.add(settingsChange, gbc);
 
-	form.addRow(HorizontalAnchor.LEFT, col);
-	form.add(isAdminCheckBox, row);
-	form.add(isAdminChange, row);
-
-	form.addRow(HorizontalAnchor.LEFT, col);
-	form.add(passPanel);
-
-	return formPanel;
+	return form;
     }
 
-    private void initLabels(boolean bNormalUser) {
-	if (bNormalUser) {
-	    // Normal user
-	    userNameLabel.setText(
-		Finder.getString("usermgr.basic.label.username"));
-	    userDescLabel.setText(
-		Finder.getString("usermgr.basic.label.userdesc"));
-	} else {
-	    // Role
-	    userNameLabel.setText(
-		Finder.getString("usermgr.basic.label.rolename"));
-	    userDescLabel.setText(
-		Finder.getString("usermgr.basic.label.roledesc"));
+    /**
+     * ActionListener for Advanced Settings
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        String actionCmd = e.getActionCommand();
+	if (actionCmd == ACTION_ADV_SETTINGS) {
+		if (advDialog == null ||
+			descriptor.isTypeRole() != advDialog.isTypeRole()) {
+		    advDialog = new AdvancedSettingsDialog(this,
+			descriptor, umo);
+		} else {
+			advDialog.setUser(umo);
+		}
+		advDialog.show();
+		if (advDialog.getValue() == JOptionPane.OK_OPTION) {
+		    advDialog.update();
+		    settingsProperty.setValue(advDialog.isChanged());
+		}
 	}
     }
+
+    /**
+     * Clear the advanced settings change state.
+     */
+    public void clearChanges() {
+        settingsProperty.update(false, true);
+    }
 }
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrControl.java	Thu Apr 26 00:14:30 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
- */
-
-package com.oracle.solaris.vp.panels.usermgr.client.swing;
-
-import java.util.Map;
-import com.oracle.solaris.vp.panel.common.control.*;
-import com.oracle.solaris.vp.panel.swing.control.TabbedControl;
-
-public class UserMgrControl extends TabbedControl<UserMgrPanelDescriptor> {
-
-    //
-    // Static data
-    //
-    public static final String ID = "usermgr";
-    public static final String PARAM_USER = "user";
-
-    //
-    // Instance data
-    //
-
-    private UserManagedObject userMO;
-
-    //
-    // Constructor
-    //
-
-    public UserMgrControl(UserMgrPanelDescriptor descriptor) {
-        super(ID, null, descriptor);
-    }
-
-    //
-    // Control methods
-    //
-
-    @Override
-    public boolean isBrowsable() {
-	// This control requires init parameters
-	return false;
-    }
-
-    //
-    // DefaultControl Methods
-    //
-
-    @Override
-    protected void ensureChildrenCreated() {
-	// Add the basic and advanced tab controls
-	if (children.size() == 0) {
-	    addChildren(new UserMgrBasicControl(this));
-	    addChildren(new UserMgrAdvancedControl(this));
-	}
-    }
-
-    //
-    // SwingControl Methods
-    //
-
-    @Override
-    public void start(Navigator navigator, Map<String, String> parameters)
-	throws NavigationAbortedException, InvalidParameterException,
-	NavigationFailedException {
-
-	String param = getParameter(parameters, PARAM_USER);
-  	UserManagedObject umo =
-	    getPanelDescriptor().getUserManagedObject(param);
-	if (umo == null) {
-	    throw new InvalidParameterException(getId(), PARAM_USER, param);
-  	}
-
-  	setUserManagedObject(umo);
-
- 	super.start(navigator, parameters);
-    }
-
-    @Override
-    public void stop(boolean isCancel) throws NavigationAbortedException {
- 	super.stop(isCancel);
- 	setUserManagedObject(null);
-    }
-
-    //
-    // UserMgrControl methods
-    //
-
-    public UserManagedObject getUserManagedObject() {
-	return userMO;
-    }
-
-    //
-    // Private methods
-    //
-
-    private void setUserManagedObject(UserManagedObject umo) {
-	this.userMO = umo;
-	setName(umo == null ? null : umo.getName());
-    }
-}
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrEmptyPanel.java	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrEmptyPanel.java	Fri Apr 27 00:52:26 2012 -0400
@@ -30,6 +30,10 @@
 import com.oracle.solaris.vp.util.misc.finder.Finder;
 import com.oracle.solaris.vp.util.swing.GUIUtil;
 
+/**
+ * This panel provides preliminary information on what button
+ * does what. Details are available from the Help button.
+ */
 @SuppressWarnings({"serial"})
 public class UserMgrEmptyPanel extends JPanel {
     //
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrPanelDescriptor.java	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrPanelDescriptor.java	Fri Apr 27 00:52:26 2012 -0400
@@ -38,7 +38,7 @@
 import com.oracle.solaris.vp.panel.common.model.*;
 import com.oracle.solaris.vp.panel.swing.control.PanelFrameControl;
 import com.oracle.solaris.vp.panel.swing.model.SwingPanelDescriptor;
-import com.oracle.solaris.vp.panels.usermgr.*;
+import com.oracle.solaris.rad.usermgr.*;
 import com.oracle.solaris.vp.util.misc.*;
 import com.oracle.solaris.vp.util.misc.finder.Finder;
 import com.oracle.solaris.vp.util.misc.property.*;
@@ -53,17 +53,27 @@
     //
 
     // Constants needed for registering the MBean
-    public static final String DOMAIN =
-        MBeanUtil.VP_PANEL_DOMAIN + ".usermgr";
+    public static final String INTERFACE_NAME =
+    	"com.oracle.solaris.rad.usermgr";
     public static final ObjectName OBJECT_NAME =
-        MBeanUtil.makeObjectName(DOMAIN, "UserMgr");
+        MBeanUtil.makeObjectName(INTERFACE_NAME, "UserMgr");
+
+    public static final String USER_TYPE_NORMAL = "normal";
+    public static final String SCOPE_FILES = "files";
+    public static final String MATCH_ALL = "*";
 
     //
     // Instance data
     //
 
+    private MainControl mc;
     private DefaultControl control;
     private MXBeanTracker<UserMgrMXBean> beanTracker;
+    private UserType uType;
+
+    private String scopeStr = SCOPE_FILES;
+    private String typeStr = USER_TYPE_NORMAL;
+    private String matchStr = MATCH_ALL;
 
     private List<UserManagedObject> deleteList =
 	new ArrayList<UserManagedObject> ();
@@ -104,14 +114,14 @@
 	setComparator(SimpleHasId.COMPARATOR);
 
 	// Initialize list of users
-	initUsers();
+	initUsers(SCOPE_FILES, USER_TYPE_NORMAL, MATCH_ALL);
 
 	// Keep track of users added/deleted
 	addedProperty.update(0, true);
 	deletedProperty.update(0, true);
 
         control = new PanelFrameControl<UserMgrPanelDescriptor>(this);
-        MainControl mc = new MainControl(this);
+        mc = new MainControl(this);
 	control.addChildren(mc);
     }
 
@@ -174,35 +184,23 @@
 	}
     }
 
-    @Override
-    public void removeChildren(UserManagedObject... toRemove) {
+    //
+    // UserMgrPanelDescriptor methods
+    //
+
+    public void removeChildren(UserManagedObject toRemove) {
 	super.removeChildren(toRemove);
 
 	ChangeableAggregator aggregator = getChangeableAggregator();
-	for (UserManagedObject umo : toRemove) {
-	    aggregator.removeChangeable(umo.getChangeableAggregator());
-	}
+	aggregator.removeChangeable(toRemove.getChangeableAggregator());
     }
 
-    @Override
-    protected String getCalculatedStatusText() {
-    	int nUsers = 0;
-	int nRoles = 0;
-	List<UserManagedObject>umoList = getChildren();
-	for (UserManagedObject umo : umoList) {
-	    if (umo.isUserNormal())
-		nUsers++;
-	    else if (umo.isUserRole())
-		nRoles++;
-	}
-
-	return Finder.getString("user.status", nUsers, nRoles);
+    public void removeAllChildren() {
+	super.clearChildren();
+	ChangeableAggregator aggregator = getChangeableAggregator();
+	aggregator.reset();
     }
 
-    //
-    // UserMgrPanelDescriptor methods
-    //
-
     public UserMgrMXBean getUserMgrBean() {
         return beanTracker.getBean();
     }
@@ -225,16 +223,22 @@
 
     public void deleteUserManagedObject(UserManagedObject toRemove) {
 	removeChildren(toRemove);
-	deletedProperty.setValue(deletedProperty.getValue() + 1);
-	deleteList.add(toRemove);
     }
 
     public void addUserManagedObject(UserManagedObject toAdd) {
 	addChildren(toAdd);
+    }
+
+    public void addToAddList(UserManagedObject toAdd) {
 	addedProperty.setValue(addedProperty.getValue() + 1);
 	addList.add(toAdd);
     }
 
+    public void addToDeleteList(UserManagedObject toRemove) {
+	deletedProperty.setValue(deletedProperty.getValue() + 1);
+	deleteList.add(toRemove);
+    }
+
     public void saveDeletedUsers() throws ActionAbortedException,
 	ActionFailedException, ActionUnauthorizedException {
 
@@ -243,26 +247,23 @@
 	    UserManagedObject umo = it.next();
 	    try {
 		getUserMgrBean().deleteUser(umo.getName());
+		deleteUserManagedObject(umo);
 		it.remove();
 		deletedProperty.setValue(deletedProperty.getValue() - 1);
 	    } catch (SecurityException se) {
 		throw new ActionUnauthorizedException(se);
 	    } catch (ObjectException e) {
 		UserMgrError ume = e.getPayload(UserMgrError.class);
-		String msg;
-		UserMgrErrorType error = (ume != null) ?
-		    ume.getErrorCode() : UserMgrErrorType.INVALIDDATA;
-		switch (error) {
-		    case LASTADMIN:
-			msg = Finder.getString(
-			    "usermgr.delete.lastAdmin.error");
-			break;
-		    default: // Invalid Data
-			msg = Finder.getString("usermgr.error.invalidData");
-			break;
-		}
+		String msg = Finder.getString("usermgr.error.invalidData");
 		String err = Finder.getString(
-		    "usermgr.delete.general.error", umo.getUsername());
+		    "usermgr.error.delete", umo.getUsername());
+		getLog().log(Level.SEVERE, err + msg, e);
+		throw new ActionFailedException(err + msg);
+	    // Any other remaining exceptions
+	    } catch (Exception e) {
+		String msg = Finder.getString("usermgr.error.system");
+		String err = Finder.getString(
+		    "usermgr.error.delete", umo.getUsername());
 		getLog().log(Level.SEVERE, err + msg, e);
 		throw new ActionFailedException(err + msg);
 	    }
@@ -279,18 +280,16 @@
 		char[] password = umo.getPassword();
 		User user = getUserMgrBean().addUser(
 		    umo.getNewUser(), password);
+		addUserManagedObject(umo);
 		Arrays.fill(password, (char)0);
 
-		if (umo.isAdministrator()) {
-		    getUserMgrBean().
-			setAdministrator(user.getUsername(), true);
-		}
 		it.remove();
 		addedProperty.setValue(addedProperty.getValue() - 1);
 		umo.updateUser(user);
 	    } catch (SecurityException se) {
 		throw new ActionUnauthorizedException(se);
 	    } catch (ObjectException e) {
+		e.printStackTrace();
 		UserMgrError ume = e.getPayload(UserMgrError.class);
 		String msg;
 		UserMgrErrorType error = (ume != null) ?
@@ -306,9 +305,17 @@
 			msg = Finder.getString("usermgr.error.invalidData");
 			break;
 		}
-		String err = Finder.getString("usermgr.add.general.error",
+		String err = Finder.getString("usermgr.error.add",
 		    umo.getUsername());
 		getLog().log(Level.SEVERE, err + msg, e);
+    		deleteUserManagedObject(umo);
+		throw new ActionFailedException(err + msg);
+	    // Any other remaining exceptions
+	    } catch (Exception e) {
+		String msg = Finder.getString("usermgr.error.system");
+		String err = Finder.getString(
+		    "usermgr.error.add", umo.getUsername());
+		getLog().log(Level.SEVERE, err + msg, e);
 		throw new ActionFailedException(err + msg);
 	    }
 	    umo.getChangeableAggregator().save();
@@ -322,19 +329,16 @@
 	for (UserManagedObject umo : kids) {
 	    if (umo.getChangeableAggregator().isChanged()) {
 		User user = umo.getModifiedUser();
+		UserChangeFields changes = umo.getModifiedChanges();
 		try {
 		    if (user != null) {
 			char[] password = null;
 			if (umo.getPassProperty().isChanged())
 			    password = umo.getPassword();
-			getUserMgrBean().modifyUser(user, password);
+			getUserMgrBean().modifyUser(user, password, changes);
 			if (password != null)
 			    Arrays.fill(password, (char)0);
 		    }
-		    if (umo.getIsAdminProperty().isChanged()) {
-			getUserMgrBean().setAdministrator(umo.getUsername(),
-			    umo.isAdministrator());
-		    }
 		} catch (SecurityException se) {
 		    throw new ActionUnauthorizedException(se);
 		} catch (ObjectException e) {
@@ -346,23 +350,21 @@
 			case PASSERROR:
 			    msg = Finder.getString("usermgr.error.passError");
 			    break;
-			case LASTADMIN:
-			    msg = Finder.getString(
-				"usermgr.modify.lastAdmin.error");
-			    break;
 			default:
 			    msg = Finder.getString("usermgr.error.invalidData");
 			    break;
 		    }
 		    String err = Finder.getString(
-			"usermgr.modify.general.error", umo.getUsername());
+			"usermgr.error.modify", umo.getUsername());
 		    getLog().log(Level.SEVERE, err + msg, e);
 		    throw new ActionFailedException(err + msg);
-		} catch (Exception e) { // debug only!!!
+		// Any other remaining exceptions
+		} catch (Exception e) {
+		    String msg = Finder.getString("usermgr.error.system");
 		    String err = Finder.getString(
-			"usermgr.modify.general.error", umo.getUsername());
-		    getLog().log(Level.SEVERE, err, e);
-		    throw new ActionFailedException("Error modifying user!!!!");
+			"usermgr.error.modify", umo.getUsername());
+		    getLog().log(Level.SEVERE, err + msg, e);
+		    throw new ActionFailedException(err + msg);
 		}
 		umo.getChangeableAggregator().save();
 	    }
@@ -378,6 +380,16 @@
 	return null;
     }
 
+    public List<String> getSupplGroups() {
+	try {
+	    return getUserMgrBean().getsupplGroups();
+        } catch (ObjectException e) {
+            getLog().log(Level.SEVERE,
+	    "Error getting supplementary group list.", e);
+	}
+	return null;
+    }
+
     public List<String> getShells() {
 	try {
 	    return getUserMgrBean().getshells();
@@ -387,18 +399,144 @@
 	return null;
     }
 
-    public UserImpl getDefaultUser() throws ActionFailedException,
-	ActionUnauthorizedException {
+    public List<String> getScopes() {
+	try {
+	    return getUserMgrBean().getscopes();
+        } catch (ObjectException e) {
+            getLog().log(Level.SEVERE, "Error getting  scopes list.", e);
+	}
+	return null;
+    }
+
+    public List<String> getProfiles() {
+	try {
+	    return getUserMgrBean().getprofiles();
+        } catch (ObjectException e) {
+            getLog().log(Level.SEVERE, "Error getting profiles list.", e);
+	}
+	return null;
+    }
+
+    public List<String> getAuths() {
+	try {
+	    return getUserMgrBean().getauths();
+        } catch (ObjectException e) {
+            getLog().log(Level.SEVERE, "Error getting authorizations list.", e);
+	}
+	return null;
+    }
+
+    public List<String> getRoles() {
+	try {
+	    return getUserMgrBean().getroles();
+        } catch (ObjectException e) {
+            getLog().log(Level.SEVERE, "Error getting roles list.", e);
+	}
+	return null;
+    }
+
+    public void setScope(String scope) {
+        ScopeType sType;
+	if (scope.equals(SCOPE_FILES)) {
+	    sType = ScopeType.FILES;
+	} else {
+	    sType = ScopeType.LDAP;
+	}
+
+	try {
+	    getUserMgrBean().setScope(sType);
+        } catch (Exception e) {
+            getLog().log(Level.SEVERE, "Error setting  scope.", e);
+	}
+    }
+
+    public UserImpl getDefaultUser() {
 	try {
 	    User defUser = getUserMgrBean().getdefaultUser();
-	    return new UserImpl("", 0L, defUser.getGroupID(), "", "",
-		defUser.getDefaultShell());
-	} catch (SecurityException se) {
-	    throw new ActionUnauthorizedException(se);
+	    return new UserImpl(
+		"", 0L, defUser.getGroupID(),
+		"", "", defUser.getDefaultShell(),
+		0, 0, 0, 0,
+		"", "", "", "", "", "",
+		"", "", "", "", "", "",
+		null, null, null, null, null, null);
 	} catch (ObjectException e) {
 	    getLog().log(Level.SEVERE, "Error getting default user.", e);
-	    throw new ActionFailedException(e);
+	}
+
+	return null;
+    }
+
+    public void initUsers(String scopeStr,
+    		String typeStr, String matchStr) {
+	int count = 0;
+	String statusStr;
+	String listTitle;
+
+	this.scopeStr = scopeStr;
+	this.typeStr = typeStr;
+	this.matchStr = matchStr;
+
+	setScope(scopeStr);
+
+	statusStr = Finder.getString("usermgr.status.scope") +
+	    " " + scopeStr;
+	if (typeStr.equals(USER_TYPE_NORMAL)) {
+	    uType = UserType.NORMAL;
+	    listTitle = Finder.getString("usermgr.list.title.user");
+	} else {
+	    uType = UserType.ROLE;
+	    listTitle = Finder.getString("usermgr.list.title.role");
 	}
+
+	setFilter(uType, matchStr);
+	List<User> users = getUsers();
+
+	removeAllChildren();
+	try {
+	    boolean uTypeSet = false;
+	    for (User user : users) {
+		String username = user.getUsername();
+		UserMgrMXBean bean = getUserMgrBean();
+		if (uTypeSet == false) {
+		    uType = bean.getUserType(username);
+		    uTypeSet = true;
+		}
+
+		UserManagedObject umo = new UserManagedObject(this,
+		    user, uType, null, false);
+		addChildren(umo);
+	    }
+
+	} catch (ObjectException e) {
+	    getLog().log(Level.SEVERE, "Error creating user list.", e);
+	} finally {
+	    setStatusText(statusStr);
+	    if (mc != null) {
+		mc.setListTitle(listTitle);
+	    }
+        }
+    }
+
+    public boolean isTypeRole() {
+        return (uType == UserType.ROLE ? true : false);
+    }
+
+    public String getTypeString() {
+        return (uType == UserType.ROLE ? "role" : "user");
+    }
+
+    public String getScope() {
+        return (scopeStr);
+    }
+
+    public String getType() {
+        return (typeStr);
+    }
+
+
+    public String getMatch() {
+        return (matchStr);
     }
 
     //
@@ -415,32 +553,11 @@
 	return users;
     }
 
-    private void initUsers() {
-	int nUsers = 0;
-	int nRoles = 0;
-
-	List<User> users = getUsers();
-
+    private void setFilter(UserType utype, String search) {
 	try {
-	    for (User user : users) {
-		String username = user.getUsername();
-		UserMgrMXBean bean = getUserMgrBean();
-		boolean isAdmin = bean.isAdministrator(username);
-		UserType uType = bean.getUserType(username);
-		UserManagedObject umo = new UserManagedObject(this,
-		    user, uType, isAdmin, null, false);
-
-		if (uType == UserType.NORMAL)
-		    nUsers++;
-		else
-		    nRoles++;
-
-		addChildren(umo);
-	    }
-	} catch (ObjectException e) {
-	    getLog().log(Level.SEVERE, "Error creating user list.", e);
-	} finally {
-	    setStatusText(Finder.getString("user.status", nUsers, nRoles));
+	    getUserMgrBean().setFilter(utype, search);
+        } catch (Exception e) {
+            getLog().log(Level.SEVERE, "Error setting filter.", e);
 	}
     }
 }
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrUtils.java	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrUtils.java	Fri Apr 27 00:52:26 2012 -0400
@@ -25,7 +25,9 @@
 
 package com.oracle.solaris.vp.panels.usermgr.client.swing;
 
+import java.awt.*;
 import java.util.Arrays;
+import javax.swing.*;
 import com.oracle.solaris.vp.panel.common.action.ActionFailedException;
 import com.oracle.solaris.vp.util.misc.finder.Finder;
 
@@ -53,19 +55,19 @@
 	// User name must be specified
 	if (username.length() == 0) {
 	    throw new ActionFailedException(
-		Finder.getString("usermgr.basic.error.username.none"));
+		Finder.getString("usermgr.error.username.none"));
 	}
 
 	// Ensure that the username is valid
 	if (!isValidLogin(username)) {
 	    throw new ActionFailedException(
-		Finder.getString("usermgr.basic.error.username.bad"));
+		Finder.getString("usermgr.error.username.bad"));
 	}
 
 	// Ensure that username does not already exist
 	if (descriptor.getUserManagedObject(username) != null) {
 	    throw new ActionFailedException(
-		Finder.getString("usermgr.basic.error.username.exists",
+		Finder.getString("usermgr.error.username.exists",
 		    username));
 	}
     }
@@ -75,21 +77,17 @@
 	// Ensure that the user description, if specified, is valid.
 	if (!isValidUserDesc(userdesc)) {
 	    throw new ActionFailedException(
-		Finder.getString("usermgr.basic.error.userdesc.bad"));
+		Finder.getString("usermgr.error.userdesc.bad"));
 	}
     }
 
     public static void validatePassword(boolean bNewUser,
 	char[] pass1, char[] pass2) throws ActionFailedException {
-	// Password must be specified for a new user
-	if (pass1.length == 0 && bNewUser)
-	    throw new ActionFailedException(
-		Finder.getString("usermgr.basic.error.pass.none"));
 
 	// Ensure that the passwords match
 	if (!Arrays.equals(pass1, pass2)) {
 	    throw new ActionFailedException(
-		Finder.getString("usermgr.basic.error.pass.nomatch"));
+		Finder.getString("usermgr.error.pass.nomatch"));
 	}
     }
 
@@ -98,7 +96,7 @@
 	// Ensure that the UID is valid
 	if (uid < VALID_UID) {
 	    throw new ActionFailedException(
-		Finder.getString("usermgr.advanced.error.uid.bad"));
+		Finder.getString("usermgr.error.uid.bad"));
 	}
     }
 
@@ -107,7 +105,7 @@
 	// Ensure that the homedir is valid
 	if (!isValidHomeDir(homedir)) {
 	    throw new ActionFailedException(
-		Finder.getString("usermgr.advanced.error.homedir.bad"));
+		Finder.getString("usermgr.error.homedir.bad"));
 	}
     }
 
@@ -162,4 +160,20 @@
 	return (homedir.length() >= VALID_HOMEDIRLEN &&
 	    homedir.matches("^\\/[\\-\\p{Alnum}\\._\\/]+$"));
     }
+
+    public static void removeIcons(JOptionPane pane) {
+        Component[] comps = pane.getComponents();
+
+	for (int i = 0; i < comps.length; i++) {
+	    Component comp = comps[i];
+	    if (comp instanceof JPanel) {
+        	Component[] buttons = ((JPanel)comp).getComponents();
+		for (int j = 0; j < buttons.length; j++) {
+		    if (buttons[j] instanceof JButton) {
+			((JButton)buttons[j]).setIcon(null);
+		    }
+		}
+	    }
+	}
+    }
 }
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/DOCS has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/DOCS.TAB	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,7 @@
+e�������������������������������������������_������������u�������u����������������_��������u�����@9J���*�������0�
+��£
+�
+����
+�*������*��
+�ꪪ����4����0��ң|�"������J0�J0���4����0�
+�j��Ҫ�����ꪪ�*0�º����̊�2������ꪪ������
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/OFFSETS	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,1 @@
+��>d*��g��`��`P¢1��U{lmKx��k�����2��y��
\ No newline at end of file
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/POSITIONS has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/SCHEMA	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,2 @@
+JavaSearch 1.0
+TMAP bs=2048 rt=1 fl=-1 id1=399 id2=1
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/TMAP has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/app.hs	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,29 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- ident   "%Z%%M% %I%   %E% SMI" -->
+<!DOCTYPE helpset PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 2.0//EN" "helpset_1_0.dtd">
+
+<helpset version="2.0" xml:lang="en">
+<title>User Manager Online Help</title>
+<maps>
+	<homeID></homeID>
+	<mapref location="map.jhm"/>
+</maps>
+<view>
+	<name>TOC</name>
+	<label>Contents</label>
+	<type>javax.help.TOCView</type>
+	<data>toc.xml</data>
+</view>
+<view>
+	<name>Index</name>
+	<label>Index</label>
+	<type>javax.help.IndexView</type>
+	<data>index.xml</data>
+</view>
+<view>
+	<name>Search</name>
+	<label>Search</label>
+	<type>javax.help.SearchView</type>
+	<data engine="com.sun.java.help.search.DefaultSearchEngine">JavaHelpSearch</data>
+</view>
+</helpset>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/docinfo.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,77 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="documentinfo"></a><p>Copyright 2012</p><p>This
+software and related documentation are provided under a license agreement containing restrictions on
+use and disclosure and are protected by intellectual property laws. Except as expressly
+permitted in your license agreement or allowed by law, you may not use,
+copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display
+any part, in any form, or by any means. Reverse engineering, disassembly, or
+decompilation of this software, unless required by law for interoperability, is prohibited.</p>
+
+<p>The information
+contained herein is subject to change without notice and is not warranted to
+be error-free. If you find any errors, please report them to us in
+writing.</p>
+
+<p>If this is software or related documentation that is delivered to the U.S.
+Government or anyone licensing it on behalf of the U.S. Government, the following
+notice is applicable:</p>
+
+<p>U.S. GOVERNMENT END USERS. Oracle programs, including any operating system, integrated software,
+any programs installed on the hardware, and/or documentation, delivered to U.S. Government end
+users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and
+agency-specific supplemental regulations. As such, use, duplication, disclosure, modification, and adaptation of the programs,
+including any operating system, integrated software, any programs installed on the hardware, and/or
+documentation, shall be subject to license terms and license restrictions applicable to the
+programs. No other rights are granted to the U.S. Government.</p>
+
+<p>This software or hardware is
+developed for general use in a variety of information management applications. It is
+not developed or intended for use in any inherently dangerous applications, including applications
+that may create a risk of personal injury. If you use this software
+or hardware in dangerous  applications, then you shall be responsible to take
+all appropriate fail-safe, backup, redundancy, and other measures to ensure its safe use.
+Oracle Corporation and its affiliates disclaim any liability for any damages caused by
+use of this software or hardware in dangerous applications.</p>
+
+<p>Oracle and Java are registered
+trademarks of Oracle and/or its affiliates. Other names may be trademarks of their
+respective owners.</p>
+
+<p>Intel and Intel Xeon are trademarks or registered trademarks of Intel Corporation.
+All SPARC trademarks are used under license and are trademarks or registered trademarks
+of SPARC International, Inc. AMD, Opteron, the AMD logo, and the AMD Opteron
+logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a
+registered trademark of The Open Group.</p>
+
+<p>This software or hardware and documentation may
+provide access to or information on content, products, and services from third parties.
+Oracle Corporation and its affiliates are not responsible for and expressly disclaim all
+warranties of any kind with respect to third-party content, products, and services. Oracle Corporation
+and its affiliates will not be responsible for any loss, costs, or damages
+incurred due to your access to or use of third-party content, products, or
+services.</p>
+
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/index.xml	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- ident   "%Z%%M% %I%   %E% SMI" -->
+<!DOCTYPE index PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Index Version 2.0//EN" "index_1_0.dtd">
+<index version="2.0">
+</index>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/map.jhm	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- ident   "%Z%%M% %I%   %E% SMI" -->
+<!DOCTYPE map PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Map Version 2.0//EN" "map_1_0.dtd">
+<map version="2.0">
+	<mapID target="umolh" url="umolh.html"/>
+	<mapID target="docinfo" url="docinfo.html"/>
+	<mapID target="usermgr-mainpanel" url="usermgr-mainpanel.html"/>
+	<mapID target="usermgr-namesvcscope" url="usermgr-namesvcscope.html"/>
+	<mapID target="usermgr-createuser" url="usermgr-createuser.html"/>
+	<mapID target="usermgr-moduser" url="usermgr-moduser.html"/>
+	<mapID target="usermgr-deluser" url="usermgr-deluser.html"/>
+	<mapID target="usermgr-advtab" url="usermgr-advtab.html"/>
+	<mapID target="usermgr-admgrp" url="usermgr-admgrp.html"/>
+	<mapID target="usrmgr-admrole" url="usrmgr-admrole.html"/>
+	<mapID target="usermgr-admrights" url="usermgr-admrights.html"/>
+	<mapID target="usermgr-admauths" url="usermgr-admauths.html"/>
+	<mapID target="usermgr-assumerole" url="usermgr-assumerole.html"/>
+	<mapID target="usermgr-chgcred" url="usermgr-chgcred.html"/>
+</map>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/target.xml	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<div element="book" href="index.html">
+  <ttl>User Manager Online Help</ttl>
+  <xreftext>&#x201C;User Manager Online Help&#x201D;</xreftext>
+  <div href="docinfo.html" targetptr="documentinfo">
+  </div>
+  <div href="usermgr-mainpanel.html" targetptr="usermgr-mainpanel">
+    <ttl>User Manager Panel</ttl>
+    <xreftext>&#x201C;User Manager Panel&#x201D;</xreftext>
+  </div>
+  <div href="usermgr-namesvcscope.html" targetptr="usermgr-namesvcscope">
+    <ttl>Selecting a Name-Service Scope and Type</ttl>
+    <xreftext>&#x201C;Selecting a Name-Service Scope and Type&#x201D;</xreftext>
+  </div>
+  <div href="usermgr-createuser.html" targetptr="usermgr-createuser">
+    <ttl>Creating a New User or Role</ttl>
+    <xreftext>&#x201C;Creating a New User or Role&#x201D;</xreftext>
+  </div>
+  <div href="usermgr-moduser.html" targetptr="usermgr-moduser">
+    <ttl>Modifying a User or Role</ttl>
+    <xreftext>&#x201C;Modifying a User or Role&#x201D;</xreftext>
+  </div>
+  <div href="usermgr-deluser.html" targetptr="usermgr-deluser">
+    <ttl>Deleting a User or Role</ttl>
+    <xreftext>&#x201C;Deleting a User or Role&#x201D;</xreftext>
+  </div>
+  <div href="usermgr-advtab.html" targetptr="usermgr-advtab">
+    <ttl>Advanced Settings</ttl>
+    <xreftext>&#x201C;Advanced Settings&#x201D;</xreftext>
+  </div>
+  <div href="usermgr-admgrp.html" targetptr="usermgr-admgrp">
+    <ttl>Administering Groups</ttl>
+    <xreftext>&#x201C;Administering Groups&#x201D;</xreftext>
+  </div>
+  <div href="usrmgr-admrole.html" targetptr="usrmgr-admrole">
+    <ttl>Administering Roles</ttl>
+    <xreftext>&#x201C;Administering Roles&#x201D;</xreftext>
+  </div>
+  <div href="usermgr-admrights.html" targetptr="usermgr-admrights">
+    <ttl>Administering Rights</ttl>
+    <xreftext>&#x201C;Administering Rights&#x201D;</xreftext>
+  </div>
+  <div href="usermgr-admauths.html" targetptr="usermgr-admauths">
+    <ttl>Administering Authorizations</ttl>
+    <xreftext>&#x201C;Administering Authorizations&#x201D;</xreftext>
+  </div>
+  <div href="usermgr-assumerole.html" targetptr="usermgr-assumerole">
+    <ttl>Changing User Credentials</ttl>
+    <xreftext>&#x201C;Changing User Credentials&#x201D;</xreftext>
+  </div>
+  <div href="usermgr-chgcred.html" targetptr="usermgr-chgcred">
+    <ttl>To Change a User's Credentials</ttl>
+    <xreftext>&#x201C;To Change a User's Credentials&#x201D;</xreftext>
+  </div>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/toc.xml	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- ident   "%Z%%M% %I%   %E% SMI" -->
+<!DOCTYPE toc PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 2.0//EN" "toc_1_0.dtd">
+<toc version="2.0">
+
+ <tocitem target="usermgr-mainpanel" text="User Manager Panel" expand="false">
+    <tocitem target="usermgr-namesvcscope" text="Selecting a Name-Service Scope and Type" expand="false"></tocitem>
+    <tocitem target="usermgr-createuser" text="Creating a New User or Role" expand="false"></tocitem>
+    <tocitem target="usermgr-moduser" text="Modifying a User or Role" expand="false"></tocitem>
+    <tocitem target="usermgr-deluser" text="Deleting a User or Role" expand="false"></tocitem></tocitem>
+ <tocitem target="usermgr-advtab" text="Advanced Settings" expand="false">
+    <tocitem target="usermgr-admgrp" text="Administering Groups" expand="false"></tocitem>
+    <tocitem target="usrmgr-admrole" text="Administering Roles" expand="false"></tocitem>
+    <tocitem target="usermgr-admrights" text="Administering Rights" expand="false"></tocitem>
+    <tocitem target="usermgr-admauths" text="Administering Authorizations" expand="false"></tocitem></tocitem>
+ <tocitem target="usermgr-assumerole" text="Changing User Credentials" expand="false">
+    <tocitem target="usermgr-chgcred" text="To Change a User's Credentials" expand="false"></tocitem>
+</tocitem>
+</toc>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/umolh.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<h1>User Manager Online Help</h1>
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admauths.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,43 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-admauths"></a><h4>Administering Authorizations</h4>
+<p>To administer authorizations, select a user in the main User Manager panel, then
+click the Advanced Settings... button, which opens the Advanced Settings panel. Click the Authorization
+attribute on the left side of the panel to display a list of
+the available roles and a list of the authorizations that are granted to
+the current user.</p>
+
+<p>To assign an authorization, or multiple authorizations, to a user, select the authorization
+(or authorizations) from the Available Authorizations list, then click Add to add the
+authorization. The authorization is displayed in the Granted Authorizations list. To remove an
+authorization from the Granted Authorizations list, click Remove. Clicking the Add All or the Remove All
+button adds or removes all of the authorizations that are granted to the
+current user.</p>
+
+<p>Click OK to save the settings. Note that the changes are not
+applied to the current user until you click Apply or OK in the
+main User Manager panel.</p>
+
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admgrp.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,43 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-admgrp"></a><h4>Administering Groups</h4>
+<p>To administer groups, select a user or role in the main User
+Manager panel, then click the Advanced Settings... button, which opens the Advanced Settings panel. Click
+the Groups attribute on the left side of the panel to display a
+list of the available groups and a list of the groups that are
+assigned to the current user or role.</p>
+
+<p>To assign a group, or multiple groups, to a user or role,
+select the group (or groups) from the Available Groups list, then click Add. The
+group is displayed in the Assigned Groups list. To remove a group
+from the Assigned Groups list, select the group and click Remove. Clicking the Add All
+or the Remove All button adds or removes all of the groups that are
+assigned to the current user.</p>
+
+<p>Click OK to save the settings. Note that the changes are not
+applied to the current user until you click Apply or OK in the
+main User Manager panel.</p>
+
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admrights.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,48 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-admrights"></a><h4>Administering Rights</h4>
+<p>To administer rights profiles, select a user in the main User Manager panel,
+then click the Advanced Settings... button, which opens the Advanced Settings panel. Click the
+Rights Profiles attribute on the left side of the panel to display a
+list of the available rights and a list of the rights that are
+granted to the current user.</p>
+
+<p>To assign a right, or multiple rights, to a user, select the
+right (or rights) from the Available Rights list, then click Addr. The granted right
+is displayed in the Granted Rights list.</p>
+
+<p>The assignment of rights have an order precedence. Use the Move Up and
+Move Down buttons to change the order of the rights that are granted to
+the current user, as desired.</p>
+
+<p>To remove a right from the Granted Rights list, click Remove. Clicking the
+Add All or the Remove All button adds or removes all of the rights that
+are granted to the current user.</p>
+
+<p>Click OK to save the settings. Note that the changes are not
+applied to the current user until you click Apply or OK in the
+main User Manager panel.</p>
+
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-advtab.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,59 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-advtab"></a><h3>Advanced Settings</h3>
+<p>You can use the Advanced Settings... dialog to assign additional security attributes to
+a user or role, for example, rights profiles, roles, and authorizations.</p>
+
+<p>To administer advanced settings for a <b>new</b> user or role, click the Advanced
+Settings... button in the New User... dialog, which opens the Advanced Settings panel
+for the new user or role.</p>
+
+<p>To administer advanced attributes for an <b>existing</b> user or role, select the user
+or role in the main User Manager panel, then click the Advanced Settings... button,
+which opens the Advanced Settings panel for the current user or role. The
+selected user's name is displayed in parentheses at the top of the panel.</p>
+
+<p>In the Advanced Settings panel, the following settings are listed:</p>
+
+
+<ul><li><p>Groups</p>
+
+</li>
+<li><p>Roles</p>
+
+</li>
+<li><p>Rights Profiles</p>
+
+</li>
+<li><p>Authorizations</p>
+
+</li></ul>
+
+<hr><p><b>Note - </b>If you are creating a new user or role, the user or
+role is not created until you click the OK button.</p>
+
+
+<hr>
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-assumerole.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,41 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-assumerole"></a><h3>Changing User Credentials</h3>
+<p>Any user with the <tt>User Management</tt> rights profile can create new users, provided that
+the advanced attributes of the user or role to be created is a
+subset of those of the user who is performing the administration. If the
+user who is performing the administration does not have sufficient authorizations, but has
+an administrative role with sufficient authorizations, the user can assume that role to
+perform the necessary administration by clicking the Lock button in the main User
+Manager panel.</p>
+
+
+<hr><p><b>Note - </b>The authorizations and rights that are required to manage users and roles with
+User Manager are assigned through the application. The application both uses and provides
+authorizations.</p>
+
+
+<hr>
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-chgcred.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,52 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-chgcred"></a><h4>To Change a User's Credentials</h4>
+<p>Click the Lock icon to open a submenu that includes the following
+options:</p>
+
+
+<ul><li><p>Change Role...</p>
+
+</li>
+<li><p>Change User...</p>
+
+</li>
+<li><p>Administer New Host...</p>
+
+</li>
+<li><p>Clear History...</p>
+
+</li></ul>
+<p>When you select the Change Role... option, an authentication dialog is displayed. The authentication
+dialog contains a drop-down menu that lists the available roles for the specified
+user. Select the appropriate role, then click Log In to change the role.
+After assuming the role, you can perform the required administrative tasks. Click the
+Cancel button to cancel the operation or the Back button to go to
+the previous panel.</p>
+
+<p>For information about using the Administer New Host... and Clear History... menu options, refer to
+the Visual Panels documentation.</p>
+
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-createuser.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-createuser"></a><h4>Creating a New User or Role</h4>
+<p>To create a new user or role within the scope of the
+filter that is currently being used by the tool, click the New button in
+the main User Manager panel. The New User... dialog is displayed.</p>
+
+<p>In the New User... dialog, complete the following fields:</p>
+
+
+<ul><li><p><b>User Name</b></p>
+
+</li>
+<li><p><b>Full Name</b></p>
+
+</li>
+<li><p><b>User ID</b></p>
+
+<p>This field is optional. If the administrator does not provide any information, the system automatically assigns a default value.</p>
+
+</li>
+<li><p><b>Group</b></p>
+
+<p>For example, <tt>staff</tt>.</p>
+
+<p>The choices that are available vary, depending on the system's configuration.</p>
+
+</li>
+<li><p><b>Home Directory</b></p>
+
+<p>This field is optional. If the administrator does not provide any information, the system automatically assigns a default value.</p>
+
+<p>If you want the user's home directory to be automounted, precede the path name with a host name or a local host. For example, <tt>localhost:/export/home/test1</tt>.</p>
+
+</li>
+<li><p><b>Login Shell</b></p>
+
+<p>For example, <tt>/usr/bin/sh</tt>.</p>
+
+<p>The choices that are available vary, depending on the system's configuration.</p>
+
+</li>
+<li><p><b>Password</b></p>
+
+<p>Assign a temporary password to the user.</p>
+
+</li>
+<li><p><b>Confirm</b></p>
+
+<p>Confirm the temporary password that you assigned to the user.</p>
+
+</li></ul>
+
+<hr><p><b>Note - </b>All fields, with the exception of optional fields, must be completed by the
+administrator.</p>
+
+
+<hr>
+<p>To create the new user or role, and add the user or
+role to the list of users that is displayed in the main User
+Manager panel, click OK. To cancel the operation, click Cancel.</p>
+
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-deluser.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,31 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-deluser"></a><h4>Deleting a User or Role</h4>
+<p>To delete a user or role within the scope of the filter
+that is currently being used by the tool, select the user or role
+in the main User Manager panel, then click the Delete button. Click OK
+when the confirmation dialog is displayed. To cancel the operation, click Cancel.</p>
+
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-mainpanel.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,55 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-mainpanel"></a><h3>User Manager Panel</h3>
+<p>When you launch the User Manager GUI, the User Manager panel is
+displayed. The User Manager panel is used to administer users and roles. On
+the top left side of the panel is a Status field that displays
+the status of the services that are currently running on the local host.
+On the top right side of the panel is a User field. The
+User field displays the credential that is currently being used by the tool.
+To change credentials, click the Lock button on the far right of the panel.
+See <a href="usermgr-assumerole.html">Changing User Credentials</a>.</p>
+
+<p>The User Manager panel includes the following main components:</p>
+
+
+<ul><li><p><b>Users and Roles list</b> &#8211; Contains a list of users from which you can select to administer.</p>
+
+</li>
+<li><p><b>Basic Settings</b> &#8211; Displays the basic settings for a user, such as user name, full name.</p>
+
+</li></ul>
+<p><b>To view or modify information for an existing user:</b> Select the user from the list of users. The user's information is
+displayed on the right side of the panel.</p>
+
+<p><b>To create a new user:</b> Click the New... button. See <a href="usermgr-createuser.html">Creating a New User or Role</a>.</p>
+
+<p><b>To delete a user:</b> Click the Delete button. See <a href="usermgr-deluser.html">Deleting a User or Role</a>.</p>
+
+<p><b>To filter users based on scope type</b> (<tt>files</tt> <b>or</b> <tt>ldap</tt>)<b>, or by user or role:</b> Click the Filter... button.</p>
+
+<p><b>To administer advanced settings for a user, for example, roles or rights profiles:</b> Click the Advanced button. See <a href="usermgr-advtab.html">Advanced Settings</a>.</p>
+
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-moduser.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,46 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-moduser"></a><h4>Modifying a User or Role</h4>
+<p>To modify an existing user or role, select the user or role
+that you want to modify from the list that is displayed in the
+main User Manager panel. After selecting a user or role, the focus of
+the panel switches to the Modify mode.</p>
+
+<p>After selecting the user, the right side of the panel is populated
+with the user's information. In this dialog you can modify any or all
+the information for a user or role. To save the changes, click Apply.
+As with the New User... dialog, click the Advanced Settings... button to modify additional security
+attributes for the user or role. See <a href="usermgr-advtab.html">Advanced Settings</a>.</p>
+
+<p>Clicking OK saves the changes and closes the User Manager panel. Click Cancel
+to discard any unsaved changes and close the panel.</p>
+
+
+<hr><p><b>Note - </b> If a field is modified, an indicator is displayed adjacent to the
+field that has been modified.</p>
+
+
+<hr>
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-namesvcscope.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,46 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usermgr-namesvcscope"></a><h4>Selecting a Name-Service Scope and Type</h4>
+<p>The default name-service scope and type for User Manager is <tt>files</tt> and
+<tt>User</tt>. To administer the tool within a different scope, for example <tt>ldap</tt>
+and <tt>roles</tt>, click the Filter... button. Clicking the Filter... button launches a dialog
+that enables you to change the default scope and, or, type. Choices for
+Scope include <tt>files</tt> and <tt>ldap</tt>. Choices for Type include <tt>User</tt> and <tt>Role</tt>.
+Click OK to save the changes or click Cancel to cancel the operation.</p>
+
+
+<hr><p><b>Note - </b>If the system is not configured as an <tt>ldap</tt> client, only the <tt>files</tt>
+scope is available.</p>
+
+
+<hr>
+
+<hr><p><b>Tip - </b>To filter certain criteria, for example, all of the users or roles that
+start with the letter &#8220;a&#8221;, enter a search string in the Matches 
+field.</p>
+
+
+<hr>
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usrmgr-admrole.html	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,49 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html lang="en-US">
+
+<!--
+
+-->
+
+<head>
+<!-- GenHTML revision 25226-->
+
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+</head>
+
+<body class="HlpBdy">
+
+<a name="usrmgr-admrole"></a><h4>Administering Roles</h4>
+
+<hr><p><b>Note - </b>The roles attribute is available <b>only</b> for a user, <b>not</b> for a role,
+because roles can only be assigned to users.</p>
+
+
+<hr>
+<p>To administer roles, select a user in the main User Manager panel,
+then click the Advanced Settings... button, which opens the Advanced Settings panel. Click the Roles
+attribute on the left side of the panel to display a list of
+the available roles and a list of the roles that are assigned to
+the current user.</p>
+
+<p>To assign a role, or multiple roles, to a user, select the
+role (or roles) from the Available Roles list, then click Add. The role is
+displayed in the Assigned Roles list. To remove a role from the Assigned
+Roles list, select the group, then click Remove. Clicking the Add All or the
+Remove All button adds or removes all of the roles that are assigned to
+the current user.</p>
+
+<p>Click OK to save the settings. Note that the changes are not
+applied to the current user until you click Apply or OK in the
+main User Manager panel.</p>
+
+
+<br>
+
+
+<small>Copyright &#169; 2012, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></small>
+
+</body>
+</html>
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/add.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/add_all.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-16.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-22.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-24.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-32.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-16.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-22.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-24.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-32.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/group-16.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/group-24.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/move_dn.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/move_up.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/remove.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/remove_all.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/rights-16.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/rights-24.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/role-24.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/roles-16.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/roles-24.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/user-24.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-16.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-24.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-32.png has changed
Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/warning.gif has changed
--- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/resources/Resources.properties	Thu Apr 26 00:14:30 2012 -0400
+++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/resources/Resources.properties	Fri Apr 27 00:52:26 2012 -0400
@@ -20,80 +20,123 @@
 #
 
 #
-# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
 #
 
 #
-# Main
+# User Manager Panel resource strings
 #
-user.status = {0} users, {1} roles found.
+# Following messages can be localized. Some strings
+# contain an ampersand (&). Ampersand preceding the character
+# can be used as the accelerator or the hot-key (Alt+key).
+#
 
-panel.usermgr.name = User Manager
 
 #
-# Users
+# Main Panel
 #
-usermgr.list.title = Users:
-usermgr.action.add.button = New...
-usermgr.action.delete.button = Delete
-usermgr.action.delete.confirm = Delete user "{0}"?
+panel.usermgr.name = User Manager
+usermgr.status.scope = Connected; Scope:
+usermgr.list.title.user = Users:
+usermgr.list.title.role = Roles:
+usermgr.action.add.button = &New...
+usermgr.action.delete.button = &Delete
+usermgr.action.filter.button = &Filter...
+
+#
+# Info Panel
+#
+usermgr.empty.message = <html><p>This panel administers Users and Roles.<br/><br/>To view or modify an existing user, select the user from the list.<br/>To create a user, click on the <b>New...</b> button.<br/>To delete a user, click on the <b>Delete</b> button.<br/>To filter users based on scope (files|ldap), type (user|role),<br/>click on the <b>Filter...</b> button.<</p></html>
 
 #
-# Empty Panel
+# Delete Dialog
 #
-usermgr.empty.message = <html><p>This panel administers <b>local</b> users only.<br/><br/>To view or modify an existing user, select the user from the list.<br/>To create a user, click on the <b>New...</b> button.<br/>To delete a user, click on the <b>Delete</b> button.</p></html>
+usermgr.action.delete.title.user = Delete user...
+usermgr.action.delete.title.role = Delete role...
+usermgr.action.delete.confirm.user = Delete user "{0}"?
+usermgr.action.delete.confirm.role = Delete role "{0}"?
 
 #
-# Advanced Tab
+# Filter Dialog
 #
-usermgr.advanced.name = Advanced
-usermgr.advanced.label.uid = User ID:
-usermgr.advanced.label.roleid = Role ID:
-usermgr.advanced.label.group = Group:
-usermgr.advanced.label.homedir = Home Directory:
-usermgr.advanced.label.shell = Login Shell:
-usermgr.advanced.value.auto = (automatic)
+usermgr.filter.title = User Manager - Filter Users...
+usermgr.filter.label = Filter Users
+usermgr.filter.scope = Scope:
+usermgr.filter.type = Type:
+usermgr.filter.type.user = &User
+usermgr.filter.type.role = &Role
+usermgr.filter.match = &Matches:
+
+#
+# New User/Role Dialog
+#
+usermgr.new.title.user = New User...
+usermgr.new.label.user = Create a new user
+usermgr.new.title.role = New Role...
+usermgr.new.label.role = Create a new role
+usermgr.new.value.auto = (automatic)
 
 #
-# Basic Tab
+# Basic Panel. Some of the items are shared
+# with New dialog
 #
-usermgr.basic.name = Basic
-usermgr.basic.label.username = User Name:
-usermgr.basic.label.rolename = Role Name:
-usermgr.basic.label.userdesc = Full Name:
-usermgr.basic.label.roledesc = Description:
+usermgr.basic.name.user = User &Name:
+usermgr.basic.uid.user = &User ID:
+usermgr.basic.desc.user = &Full Name:
+
+usermgr.basic.name.role = Role &Name:
+usermgr.basic.uid.role = &Role ID:
+usermgr.basic.desc.role = &Description:
+
+usermgr.basic.label.group = &Group:
+usermgr.basic.label.home = &Home Directory:
+usermgr.basic.label.shell = Login &Shell:
 usermgr.basic.label.changepass = Change Password
-usermgr.basic.label.pass = Password:
-usermgr.basic.label.passconfirm = Confirm:
-usermgr.basic.label.enableadmin = User is Administrator
+usermgr.basic.label.initialpass = Set Initial Password
+usermgr.basic.label.pass = &Password:
+usermgr.basic.label.passconfirm = C&onfirm:
 
 #
-# Basic/Advanced Tab Errors 
+# Advanced Settings Dialog
 #
-usermgr.advanced.error.uid.bad = User ID must be an integer greater than 99
-usermgr.advanced.error.homedir.bad = Home directory must be a valid pathname.
-usermgr.basic.error.username.none = User name must be specified.
-usermgr.basic.error.username.bad = User name must begin with a letter, must be 8 characters or less, and may contain letters, numbers, unserscores, periods, and hyphens.
-usermgr.basic.error.username.exists = User "{0}" already exists.
-usermgr.basic.error.userdesc.bad = User description must not include colons, newlines or ampersands.
-usermgr.basic.error.pass.none = Password must be specified.
-usermgr.basic.error.pass.nomatch = Passwords do not match.
+usermgr.advanced.title = User Manager - Advanced Settings
+usermgr.advanced.settings = &Advanced Settings...
+usermgr.advanced.add_all_btn=Add A&ll
+usermgr.advanced.remove_all_btn=Re&move All
+usermgr.advanced.move_down_btn=Move &Down
+usermgr.advanced.move_up_btn=&Move Up
+usermgr.advanced.add_btn=&Add
+usermgr.advanced.remove_btn=&Remove
+usermgr.advanced.rights = Rights Profiles
+usermgr.advanced.rights.available = Available Rights:
+usermgr.advanced.rights.granted = Granted Rights:
+usermgr.advanced.roles = Roles     
+usermgr.advanced.roles.available = Available Roles:
+usermgr.advanced.roles.assigned = Assigned Roles:
+usermgr.advanced.groups = Groups     
+usermgr.advanced.groups.available = Available Groups:
+usermgr.advanced.groups.assigned = Assigned Groups:
+usermgr.advanced.auths = Authorizations
+usermgr.advanced.auths.available = Available Authorizations:
+usermgr.advanced.auths.granted = Granted Authorizations:
 
 #
-# New User Dialog
-#
-usermgr.adduser.label.intro = Create a new user
-usermgr.adduser.title = New User...
-
+# Error messages
 #
-# Add/Modify/Delete Errors
-#
-usermgr.add.general.error = Error adding user "{0}": 
-usermgr.delete.general.error = Error deleting user "{0}": 
-usermgr.delete.lastAdmin.error = Last Administrator cannot be deleted
-usermgr.modify.general.error = Error modifying user "{0}": 
-usermgr.modify.lastAdmin.error = At least one local user must be Administrator
+usermgr.error.uid.bad = User ID must be an integer greater than 99
+usermgr.error.homedir.bad = Home directory must be a valid pathname.
+usermgr.error.username.none = User name must be specified.
+usermgr.error.username.bad = User name must begin with a letter, must be 8 characters or less, and may contain letters, numbers, underscores, periods, and hyphens.
+usermgr.error.username.exists = "{0}" already exists.
+usermgr.error.userdesc.bad = User description must not include colons, newlines or ampersands.
+usermgr.error.pass.none = Password must be specified.
+usermgr.error.pass.nomatch = Passwords do not match.
+usermgr.error.add = Error adding "{0}": 
+usermgr.error.delete = Error deleting "{0}": 
+usermgr.error.modify = Error modifying "{0}": 
 usermgr.error.invalidData = Invalid data
 usermgr.error.permDenied = Permission denied
 usermgr.error.passError = Password cannot be set
 usermgr.error.userExists = User exists
+usermgr.error.system = System Error
+
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-16.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-24.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-32.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-16.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-24.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-32.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-16.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-24.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-32.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-16.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-24.png has changed
Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-32.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkg/manifests/system-management-rad-module-rad-usermgr.p5m	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,40 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+#
+
+license cr_Oracle license=cr_Oracle
+set name=pkg.fmri value=pkg:/system/management/rad/module/rad-usermgr@$(PKGVERS)
+set name=pkg.summary value="rad UserMgr module"
+set name=pkg.description value="rad UserMgr module"
+set name=info.classification value="org.opensolaris.category.2008:Applications/Configuration and Preferences"
+set name=variant.arch value=$(ARCH)
+dir path=usr group=sys
+dir path=usr/lib
+dir path=usr/lib/rad
+dir path=usr/lib/rad/java
+dir path=usr/lib/rad/module
+file path=usr/lib/rad/module/mod_usermgr.so
+dir path=usr/share group=sys
+#file path=usr/lib/rad/apis/usermgr.xml
+depend fmri=pkg:/system/management/rad@$(PKGVERS) type=require
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkg/manifests/system-management-visual-panels-panel-usermgr.p5m	Fri Apr 27 00:52:26 2012 -0400
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+#
+
+license cr_Oracle license=cr_Oracle
+set name=pkg.fmri value=pkg:/system/management/visual-panels/panel-usermgr@$(PKGVERS)
+set name=pkg.summary value="User Manager GUI"
+set name=pkg.description value="User Manager GUI"
+set name=info.classification value="org.opensolaris.category.2008:Applications/Configuration and Preferences"
+set name=variant.arch value=$(ARCH)
+dir path=usr group=sys
+dir path=usr/share group=sys
+#dir path=usr/share/applications group=other
+#file path=usr/share/applications/vp-usermgr.desktop
+dir path=usr/share/vpanels
+dir path=usr/share/vpanels/app
+file path=usr/share/vpanels/app/vpanels-panels-usermgr.jar
+dir path=usr/share/vpanels/conf
+#file path=usr/share/vpanels/conf/usermgr.xml
+dir path=usr/share/vpanels/pixmaps
+file path=usr/share/vpanels/pixmaps/usermgr.png
+depend fmri=pkg:/system/management/visual-panels-core@$(PKGVERS) type=require
--- a/usr/src/pkg/manifests_dev/system-management-visual-panels-panel-usermgr.p5m	Thu Apr 26 00:14:30 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-license cr_Oracle license=cr_Oracle
-set name=pkg.fmri value=pkg:/system/management/visual-panels/panel-usermgr@$(PKGVERS)
-set name=pkg.summary value="User Administration GUI"
-set name=pkg.description value="User Administration GUI"
-set name=info.classification value="org.opensolaris.category.2008:Applications/Configuration and Preferences"
-set name=variant.arch value=$(ARCH)
-dir path=usr group=sys
-dir path=usr/lib
-dir path=usr/lib/rad
-dir path=usr/lib/rad/module
-file path=usr/lib/rad/module/mod_usermgr.so
-dir path=usr/share group=sys
-dir path=usr/share/applications group=other
-file path=usr/share/applications/vp-usermgr.desktop
-dir path=usr/share/vpanels
-dir path=usr/share/vpanels/app
-file path=usr/share/vpanels/app/vpanels-panels-usermgr.jar
-dir path=usr/share/vpanels/conf
-file path=usr/share/vpanels/conf/usermgr.xml
-dir path=usr/share/vpanels/pixmaps
-file path=usr/share/vpanels/pixmaps/usermgr.png
-depend fmri=pkg:/system/management/visual-panels-core@$(PKGVERS) type=require