Update project structure to org.onap.aaf

Update project structure of authz module in aaf from
com.att to org.onap.aaf and add distribution management
and repositories.

Issue-id: AAF-21
Change-Id: Ia2486954e99f2bd60f18122ed60d32d5590781e9
Signed-off-by: sg481n <sg481n@att.com>
diff --git a/authz-gui/src/main/config/authGUI.props b/authz-gui/src/main/config/authGUI.props
new file mode 100644
index 0000000..d90e440
--- /dev/null
+++ b/authz-gui/src/main/config/authGUI.props
@@ -0,0 +1,34 @@
+##
+## AUTHZ GUI (authz-gui) Properties
+##
+
+hostname=_HOSTNAME_
+
+## DISCOVERY (DME2) Parameters on the Command Line
+AFT_LATITUDE=_AFT_LATITUDE_
+AFT_LONGITUDE=_AFT_LONGITUDE_
+AFT_ENVIRONMENT=_AFT_ENVIRONMENT_
+DEPLOYED_VERSION=_ARTIFACT_VERSION_
+
+## Pull in common/security properties
+
+cadi_prop_files=_COMMON_DIR_/com.att.aaf.common.props;_COMMON_DIR_/com.att.aaf.props
+
+##DME2 related parameters
+DMEServiceName=service=com.att.authz.authz-gui/version=_MAJOR_VER_._MINOR_VER_._PATCH_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+AFT_DME2_PORT_RANGE=_AUTHZ_GUI_PORT_RANGE_
+
+# Turn on both AAF TAF & LUR 2.0                                                
+aaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=_MAJOR_VER_._MINOR_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+
+## URLs
+aaf_url.gui_onboard=https://wiki.web.att.com/display/aaf/OnBoarding
+aaf_url.aaf_help=http://wiki.web.att.com/display/aaf
+aaf_url.cadi_help=http://wiki.web.att.com/display/cadi
+aaf_tools=swm,scamper,dme2,soacloud
+aaf_url.tool.swm=http://wiki.web.att.com/display/swm
+aaf_url.tool.scamper=https://wiki.web.att.com/display/scamper/Home
+aaf_url.tool.soacloud=https://wiki.web.att.com/display/soacloud/SOA+Cloud+Management+Platform
+aaf_url.tool.dme2=https://wiki.web.att.com/display/soacloud/User+Guide+-+DME2
+
+
diff --git a/authz-gui/src/main/config/log4j.properties b/authz-gui/src/main/config/log4j.properties
new file mode 100644
index 0000000..e1c9db7
--- /dev/null
+++ b/authz-gui/src/main/config/log4j.properties
@@ -0,0 +1,57 @@
+###############################################################################
+# Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+###############################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+log4j.appender.INIT=org.apache.log4j.DailyRollingFileAppender 
+log4j.appender.INIT.File=_LOG_DIR_/${LOG4J_FILENAME_init}
+log4j.appender.INIT.DatePattern='.'yyyy-MM-dd
+#log4j.appender.INIT.MaxFileSize=_MAX_LOG_FILE_SIZE_
+#log4j.appender.INIT.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_
+log4j.appender.INIT.layout=org.apache.log4j.PatternLayout 
+log4j.appender.INIT.layout.ConversionPattern=%d %p [%c] %m %n
+
+log4j.appender.GUI=org.apache.log4j.DailyRollingFileAppender 
+log4j.appender.GUI.File=_LOG_DIR_/${LOG4J_FILENAME_gui}
+log4j.appender.GUI.DatePattern='.'yyyy-MM-dd
+#log4j.appender.GUI.MaxFileSize=_MAX_LOG_FILE_SIZE_
+#log4j.appender.GUI.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_
+log4j.appender.GUI.layout=org.apache.log4j.PatternLayout 
+log4j.appender.GUI.layout.ConversionPattern=%d %p [%c] %m %n
+
+log4j.appender.AUDIT=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.AUDIT.File=_LOG_DIR_/${LOG4J_FILENAME_audit}
+log4j.appender.AUDIT.DatePattern='.'yyyy-MM-dd
+#log4j.appender.GUI.MaxFileSize=_MAX_LOG_FILE_SIZE_
+#log4j.appender.GUI.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_
+log4j.appender.AUDIT.layout=org.apache.log4j.PatternLayout 
+log4j.appender.AUDIT.layout.ConversionPattern=%d %p [%c] %m %n
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] %m %n
+
+# General Apache libraries
+log4j.rootLogger=WARN
+log4j.logger.org.apache=WARN,INIT
+log4j.logger.dme2=WARN,INIT
+log4j.logger.init=INFO,INIT
+log4j.logger.gui=_LOG4J_LEVEL_,GUI
+log4j.logger.audit=INFO,AUDIT
+
diff --git a/authz-gui/src/main/config/lrm-authz-gui.xml b/authz-gui/src/main/config/lrm-authz-gui.xml
new file mode 100644
index 0000000..f9a45e9
--- /dev/null
+++ b/authz-gui/src/main/config/lrm-authz-gui.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+    Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ -->
+
+<ns2:ManagedResourceList xmlns:ns2="http://scld.att.com/lrm/util" xmlns="http://scld.att.com/lrm/commontypes" xmlns:ns3="http://scld.att.com/lrm/types">
+    <ns2:ManagedResource>
+        <ResourceDescriptor>
+            <ResourceName>com.att.authz._ARTIFACT_ID_</ResourceName>
+            <ResourceVersion>
+                <Major>_MAJOR_VER_</Major>
+                <Minor>_MINOR_VER_</Minor>
+                <Patch>_PATCH_VER_</Patch>                
+            </ResourceVersion>
+            <RouteOffer>_ROUTE_OFFER_</RouteOffer>
+        </ResourceDescriptor>
+        <ResourceType>Java</ResourceType>
+        <ResourcePath>com.att.authz.gui.AuthGUI</ResourcePath>
+        <ResourceProps>
+            <Tag>process.workdir</Tag>
+            <Value>_ROOT_DIR_</Value>
+        </ResourceProps>    	       
+        <ResourceProps>
+            <Tag>jvm.version</Tag>
+            <Value>1.8</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>jvm.args</Tag>
+            <Value>-DAFT_LATITUDE=_AFT_LATITUDE_ -DAFT_LONGITUDE=_AFT_LONGITUDE_ -DAFT_ENVIRONMENT=_AFT_ENVIRONMENT_ -Dplatform=_SCLD_PLATFORM_ -Dcom.sun.jndi.ldap.connect.pool.maxsize=20  -Dcom.sun.jndi.ldap.connect.pool.prefsize=10 -Dcom.sun.jndi.ldap.connect.pool.timeout=3000 </Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>jvm.classpath</Tag>
+            <Value>_ROOT_DIR_/etc:_ROOT_DIR_/lib/*:</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>jvm.heap.min</Tag>
+            <Value>512m</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>jvm.heap.max</Tag>
+            <Value>2048m</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>start.class</Tag>
+            <Value>com.att.authz.gui.AuthGUI</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>stdout.redirect</Tag>
+            <Value>_ROOT_DIR_/logs/SystemOut.log</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>stderr.redirect</Tag>
+            <Value>_ROOT_DIR_/logs/SystemErr.log</Value>
+        </ResourceProps>
+        <ResourceOSID>aft</ResourceOSID>
+        <ResourceStartType>AUTO</ResourceStartType>
+        <ResourceStartPriority>3</ResourceStartPriority>
+		<ResourceMinCount>_RESOURCE_MIN_COUNT_</ResourceMinCount>
+		<ResourceMaxCount>_RESOURCE_MAX_COUNT_</ResourceMaxCount>        
+		<ResourceRegistration>_RESOURCE_REGISTRATION_</ResourceRegistration>
+        <ResourceSWMComponent>com.att.authz:_ARTIFACT_ID_</ResourceSWMComponent>
+        <ResourceSWMComponentVersion>_ARTIFACT_VERSION_</ResourceSWMComponentVersion>
+    </ns2:ManagedResource>
+</ns2:ManagedResourceList>
diff --git a/authz-gui/src/main/java/com/att/authz/cui/CUI.java b/authz-gui/src/main/java/com/att/authz/cui/CUI.java
new file mode 100644
index 0000000..b5e2b9f
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/cui/CUI.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.cui;
+
+import java.io.PrintWriter;
+import java.security.Principal;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.cadi.http.HTransferSS;
+import com.att.cmd.AAFcli;
+import com.att.cssa.rserv.HttpCode;
+
+public class CUI extends HttpCode<AuthzTrans, Void> {
+	private final AuthGUI gui;
+	public CUI(AuthGUI gui) {
+		super(null,"Command Line");
+		this.gui = gui;
+	}
+
+	@Override
+	public void handle(AuthzTrans trans, HttpServletRequest req,HttpServletResponse resp) throws Exception {
+		ServletInputStream isr = req.getInputStream();
+		PrintWriter pw = resp.getWriter();
+		int c;
+		StringBuilder cmd = new StringBuilder();
+
+		while((c=isr.read())>=0) {
+			cmd.append((char)c);
+		}
+
+		Principal p = trans.getUserPrincipal();
+		trans.env().setProperty(Config.AAF_DEFAULT_REALM, trans.env().getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm()));
+		AAFcli aafcli = new AAFcli(trans.env(), pw, 
+				gui.aafCon.hman(), 
+				gui.aafCon.securityInfo(), new HTransferSS(p,AuthGUI.app, 
+						gui.aafCon.securityInfo()));
+	
+		aafcli.verbose(false);
+		aafcli.gui(true);
+		String cmdStr = cmd.toString();
+		if (!cmdStr.contains("--help")) {
+			cmdStr = cmdStr.replaceAll("help", "--help");
+		}
+		if (!cmdStr.contains("--version")) {
+			cmdStr = cmdStr.replaceAll("version", "--version");
+		}
+		try {
+			aafcli.eval(cmdStr);
+			pw.flush();
+		} catch (Exception e) {
+			pw.flush();
+			pw.println(e.getMessage());
+		} finally {
+			aafcli.close();
+		}
+		
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/AuthGUI.java b/authz-gui/src/main/java/com/att/authz/gui/AuthGUI.java
new file mode 100644
index 0000000..470834e
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/AuthGUI.java
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import static com.att.cssa.rserv.HttpMethods.GET;
+import static com.att.cssa.rserv.HttpMethods.POST;
+import static com.att.cssa.rserv.HttpMethods.PUT;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Properties;
+
+import com.att.aft.dme2.api.DME2Exception;
+import com.att.aft.dme2.api.DME2Manager;
+import com.att.aft.dme2.api.DME2Server;
+import com.att.aft.dme2.api.DME2ServerProperties;
+import com.att.aft.dme2.api.DME2ServiceHolder;
+import com.att.aft.dme2.api.util.DME2FilterHolder;
+import com.att.aft.dme2.api.util.DME2FilterHolder.RequestDispatcherType;
+import com.att.aft.dme2.api.util.DME2ServletHolder;
+import com.att.authz.common.Define;
+import com.att.authz.cui.CUI;
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.env.AuthzTransFilter;
+import com.att.authz.env.AuthzTransOnlyFilter;
+import com.att.authz.gui.pages.ApiDocs;
+import com.att.authz.gui.pages.ApiExample;
+import com.att.authz.gui.pages.ApprovalAction;
+import com.att.authz.gui.pages.ApprovalForm;
+import com.att.authz.gui.pages.Home;
+import com.att.authz.gui.pages.LoginLanding;
+import com.att.authz.gui.pages.LoginLandingAction;
+import com.att.authz.gui.pages.NsDetail;
+import com.att.authz.gui.pages.NsHistory;
+import com.att.authz.gui.pages.NsInfoAction;
+import com.att.authz.gui.pages.NsInfoForm;
+import com.att.authz.gui.pages.NssShow;
+import com.att.authz.gui.pages.PassChangeAction;
+import com.att.authz.gui.pages.PassChangeForm;
+import com.att.authz.gui.pages.PendingRequestsShow;
+import com.att.authz.gui.pages.PermDetail;
+import com.att.authz.gui.pages.PermGrantAction;
+import com.att.authz.gui.pages.PermGrantForm;
+import com.att.authz.gui.pages.PermHistory;
+import com.att.authz.gui.pages.PermsShow;
+import com.att.authz.gui.pages.RequestDetail;
+import com.att.authz.gui.pages.RoleDetail;
+import com.att.authz.gui.pages.RoleHistory;
+import com.att.authz.gui.pages.RolesShow;
+import com.att.authz.gui.pages.UserRoleExtend;
+import com.att.authz.gui.pages.UserRoleRemove;
+import com.att.authz.gui.pages.WebCommand;
+import com.att.authz.org.OrganizationFactory;
+import com.att.authz.server.AbsServer;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.aaf.v2_0.AAFTrustChecker;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.config.Config;
+import com.att.cssa.rserv.CachingFileAccess;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.rosetta.env.RosettaDF;
+import com.att.xgen.html.HTMLGen;
+import com.att.xgen.html.State;
+
+import aaf.v2_0.Api;
+import aaf.v2_0.Approvals;
+import aaf.v2_0.CredRequest;
+import aaf.v2_0.Error;
+import aaf.v2_0.History;
+import aaf.v2_0.Nss;
+import aaf.v2_0.Perms;
+import aaf.v2_0.RolePermRequest;
+import aaf.v2_0.Roles;
+import aaf.v2_0.UserRoles;
+import aaf.v2_0.Users;
+
+public class AuthGUI extends AbsServer implements State<Env>{
+	public static final int TIMEOUT = 60000;
+	public static final String app = "AAF GUI";
+	
+	public RosettaDF<Perms> permsDF;
+	public RosettaDF<Roles> rolesDF;
+	public RosettaDF<Users> usersDF;
+	public RosettaDF<UserRoles> userrolesDF;
+	public RosettaDF<CredRequest> credReqDF;
+	public RosettaDF<RolePermRequest> rolePermReqDF;
+	public RosettaDF<Approvals> approvalsDF;
+	public RosettaDF<Nss> nssDF;
+	public RosettaDF<Api> apiDF;
+	public RosettaDF<Error> errDF;
+	public RosettaDF<History> historyDF;
+
+	public final AuthzEnv env;
+	public final Slot slot_httpServletRequest;
+
+	public AuthGUI(final AuthzEnv env) throws CadiException, GeneralSecurityException, IOException, APIException {
+		super(env,app);
+		this.env = env;
+		
+		env.setLog4JNames("log4j.properties","authz","gui","audit","init","trace ");
+		OrganizationFactory.setDefaultOrg(env, "com.att.authz.org.att.ATT");
+
+
+		slot_httpServletRequest = env.slot("HTTP_SERVLET_REQUEST");
+		
+		permsDF = env.newDataFactory(Perms.class);
+		rolesDF = env.newDataFactory(Roles.class);
+//			credsDF = env.newDataFactory(Cred.class);
+		usersDF = env.newDataFactory(Users.class);
+		userrolesDF = env.newDataFactory(UserRoles.class);
+		credReqDF = env.newDataFactory(CredRequest.class);
+		rolePermReqDF = env.newDataFactory(RolePermRequest.class);
+		approvalsDF = env.newDataFactory(Approvals.class);
+		nssDF = env.newDataFactory(Nss.class);
+		apiDF = env.newDataFactory(Api.class);
+		errDF   = env.newDataFactory(Error.class);
+		historyDF = env.newDataFactory(History.class);
+
+		/////////////////////////
+		// Screens
+		/////////////////////////
+		// Start Screen
+		final Page start = new Display(this, GET, new Home(this)).page();
+
+		// MyPerms Screens
+		final Page myPerms = new Display(this, GET, new PermsShow(this, start)).page();
+		Page permDetail = new Display(this, GET, new PermDetail(this, start, myPerms)).page();
+							new Display(this, GET, new PermHistory(this,start,myPerms,permDetail));
+
+		// MyRoles Screens
+		final Page myRoles = new Display(this, GET, new RolesShow(this, start)).page();
+		Page roleDetail = new Display(this, GET, new RoleDetail(this, start, myRoles)).page();
+							new Display(this, GET, new RoleHistory(this,start,myRoles,roleDetail));
+							
+		// MyNameSpace
+		final Page myNamespaces = new Display(this, GET, new NssShow(this, start)).page();
+		Page nsDetail = new Display(this, GET, new NsDetail(this, start, myNamespaces)).page();
+			   		  	new Display(this, GET, new NsHistory(this, start,myNamespaces,nsDetail));
+							 
+		// Password Change Screens
+		final Page pwc = new Display(this, GET, new PassChangeForm(this, start)).page();
+						 new Display(this, POST, new PassChangeAction(this, start, pwc));
+
+		// Validation Change Screens
+		final Page validate = new Display(this, GET, new ApprovalForm(this, start)).page();
+							  new Display(this, POST, new ApprovalAction(this, start, validate));
+							
+		// Onboard, Detailed Edit  Screens
+		final Page onb = new Display(this, GET, new NsInfoForm(this, start)).page();
+						 new Display(this, POST, new NsInfoAction(this, start, onb));
+
+		// Web Command Screens
+		/* final Page webCommand =*/ new Display(this, GET, new WebCommand(this, start)).page();
+		
+		// API Docs
+		final Page apidocs = new Display(this, GET, new ApiDocs(this, start)).page();
+							 new Display(this, GET, new ApiExample(this,start, apidocs)).page();
+		
+		// Permission Grant Page
+		final Page permGrant = 	new Display(this, GET, new PermGrantForm(this, start)).page();
+							 	new Display(this, POST, new PermGrantAction(this, start, permGrant)).page();
+							 	
+		// Login Landing if no credentials detected
+		final Page loginLanding = new Display(this, GET, new LoginLanding(this, start)).page();
+								  new Display(this, POST, new LoginLandingAction(this, start, loginLanding));
+								  
+		// User Role Request Extend and Remove
+		new Display(this, GET, new UserRoleExtend(this, start,myRoles)).page();
+		new Display(this, GET, new UserRoleRemove(this, start,myRoles)).page();
+		
+		// See my Pending Requests
+		final Page requestsShow = new Display(this, GET, new PendingRequestsShow(this, start)).page();
+								  new Display(this, GET, new RequestDetail(this, start, requestsShow));
+								  
+		// Command line Mechanism
+		route(env, PUT, "/gui/cui", new CUI(this),"text/plain;charset=utf-8","*/*");
+		
+		///////////////////////  
+		// WebContent Handler
+		///////////////////////
+		route(env,GET,"/theme/:key", new CachingFileAccess<AuthzTrans>(env,
+				CachingFileAccess.CFA_WEB_DIR,"theme"));
+		///////////////////////
+	}
+	
+	public static void main(String[] args) {
+		setup(AuthGUI.class, "authGUI.props");
+	}
+
+	/**
+	 * Start up AuthzAPI as DME2 Service
+	 * @param env
+	 * @param props
+	 * @throws DME2Exception
+	 * @throws CadiException 
+	 */
+	public void startDME2(Properties props) throws DME2Exception, CadiException {
+		
+		DME2Manager dme2 = new DME2Manager("AAF GUI DME2Manager", props);
+        DME2ServiceHolder svcHolder;
+        List<DME2ServletHolder> slist = new ArrayList<DME2ServletHolder>();
+        svcHolder = new DME2ServiceHolder();
+        String serviceName = env.getProperty("DMEServiceName",null);
+    	if(serviceName!=null) {
+	    	svcHolder.setServiceURI(serviceName);
+	        svcHolder.setManager(dme2);
+	        svcHolder.setContext("/");
+	        
+	        
+	        DME2ServletHolder srvHolder = new DME2ServletHolder(this, new String[]{"/gui"});
+	        srvHolder.setContextPath("/*");
+	        slist.add(srvHolder);
+	        
+	        EnumSet<RequestDispatcherType> edlist = EnumSet.of(
+	        		RequestDispatcherType.REQUEST,
+	        		RequestDispatcherType.FORWARD,
+	        		RequestDispatcherType.ASYNC
+	        		);
+
+	        ///////////////////////
+	        // Apply Filters
+	        ///////////////////////
+	        List<DME2FilterHolder> flist = new ArrayList<DME2FilterHolder>();
+	        
+	        // Secure all GUI interactions with AuthzTransFilter
+	        flist.add(new DME2FilterHolder(new AuthzTransFilter(env, aafCon, new AAFTrustChecker(
+	        		env.getProperty(Config.CADI_TRUST_PROP, Config.CADI_USER_CHAIN),
+	        		Define.ROOT_NS + ".mechid|"+Define.ROOT_COMPANY+"|trust"
+	        	)),"/gui/*", edlist));
+	        
+	        // Don't need security for display Artifacts or login page
+	        AuthzTransOnlyFilter atof;
+	        flist.add(new DME2FilterHolder(atof =new AuthzTransOnlyFilter(env),"/theme/*", edlist));
+	        flist.add(new DME2FilterHolder(atof,"/js/*", edlist));
+	        flist.add(new DME2FilterHolder(atof,"/login/*", edlist));
+
+	        svcHolder.setFilters(flist);
+	        svcHolder.setServletHolders(slist);
+	        
+	        DME2Server dme2svr = dme2.getServer();
+//	        dme2svr.setGracefulShutdownTimeMs(1000);
+	
+	        env.init().log("Starting AAF GUI with Jetty/DME2 server...");
+	        dme2svr.start();
+	        DME2ServerProperties dsprops = dme2svr.getServerProperties();
+	        try {
+//	        	if(env.getProperty("NO_REGISTER",null)!=null)
+	        	dme2.bindService(svcHolder);
+	        	env.init().log("DME2 is available as HTTP"+(dsprops.isSslEnable()?"/S":""),"on port:",dsprops.getPort());
+
+	            while(true) { // Per DME2 Examples...
+	            	Thread.sleep(5000);
+	            }
+	        } catch(InterruptedException e) {
+	            env.init().log("AAF Jetty Server interrupted!");
+	        } catch(Exception e) { // Error binding service doesn't seem to stop DME2 or Process
+	            env.init().log(e,"DME2 Initialization Error");
+	        	dme2svr.stop();
+	        	System.exit(1);
+	        }
+    	} else {
+    		env.init().log("Properties must contain DMEServiceName");
+    	}
+	}
+
+
+	public AuthzEnv env() {
+		return env;
+	}
+
+	/**
+	 * Derive API Error Class from AAF Response (future)
+	 */
+	public Error getError(AuthzTrans trans, Future<?> fp) {
+//		try {
+			String text = fp.body();
+			Error err = new Error();
+			err.setMessageId(Integer.toString(fp.code()));
+			if(text==null || text.length()==0) {
+				err.setText("**No Message**");
+			} else {
+				err.setText(fp.body());
+			}
+			return err;
+//		} catch (APIException e) {
+//			Error err = new Error();
+//			err.setMessageId(Integer.toString(fp.code()));
+//			err.setText("Could not obtain response from AAF Message: " + e.getMessage());
+//			return err;
+//		}
+	}
+
+	public void writeError(AuthzTrans trans, Future<?> fp, HTMLGen hgen) {
+		Error err = getError(trans,fp);
+
+		String messageBody = err.getText();
+		List<String> vars = err.getVariables();
+		for (int varCounter=0;varCounter<vars.size();) {
+			String var = vars.get(varCounter++);
+			if (messageBody.indexOf("%" + varCounter) >= 0) {
+				messageBody = messageBody.replace("%" + varCounter, var);
+			}
+		}
+
+		String msg = "[" + err.getMessageId() + "] " + messageBody;
+		if(hgen!=null) {
+			hgen.text(msg);
+		}
+		trans.checkpoint("AAF Error: " + msg);
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/BreadCrumbs.java b/authz-gui/src/main/java/com/att/authz/gui/BreadCrumbs.java
new file mode 100644
index 0000000..ffcc3f2
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/BreadCrumbs.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import static com.att.xgen.html.HTMLGen.A;
+import static com.att.xgen.html.HTMLGen.LI;
+import static com.att.xgen.html.HTMLGen.UL;
+
+import java.io.IOException;
+
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class BreadCrumbs extends NamedCode {
+	private Page[] breadcrumbs;
+
+	public BreadCrumbs(Page ... pages) {
+		super(false,"breadcrumbs");
+		breadcrumbs = pages;
+	}
+	
+	@Override
+	public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+		// BreadCrumbs
+		Mark mark = new Mark();
+		hgen.incr(mark, UL);
+		for(Page p : breadcrumbs) {
+			hgen.incr(LI,true)
+				.leaf(A,"href="+p.url()).text(p.name())
+				.end(2);
+		}
+		hgen.end(mark);
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/Controls.java b/authz-gui/src/main/java/com/att/authz/gui/Controls.java
new file mode 100644
index 0000000..e87075e
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/Controls.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import java.io.IOException;
+
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.html.HTMLGen;
+
+public class Controls extends NamedCode {
+	public Controls() {
+		super(false,"controls");
+	}
+	
+	@Override
+	public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+		hgen.incr("form","method=post")
+			.incr("input", true, "type=checkbox", "name=vehicle", "value=Bike").text("I have a bike").end()
+			.text("Password: ")
+			.incr("input", true, "type=password", "id=password1").end()
+			.tagOnly("input", "type=submit", "value=Submit")
+			.end();
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/Display.java b/authz-gui/src/main/java/com/att/authz/gui/Display.java
new file mode 100644
index 0000000..a3e6a64
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/Display.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import java.util.Enumeration;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.cssa.rserv.HttpCode;
+import com.att.cssa.rserv.HttpMethods;
+import org.onap.aaf.inno.env.Slot;
+
+public class Display {
+	private final Page get;
+	public Display(final AuthGUI gui, final HttpMethods meth, final Page page) {
+		get = page;
+		final String[] fields = page.fields();
+		final Slot slots[] = new Slot[fields.length];
+		String prefix = page.name() + '.';
+		for(int i=0;i<slots.length;++i) {
+			slots[i] = gui.env.slot(prefix + fields[i]);
+		}
+
+		/*
+		 * We handle all the "Form POST" calls here with a naming convention that allows us to create arrays from strings.
+		 * 
+		 * On the HTTP side, elements concatenate their name with their Index number (if multiple).  In this code, 
+		 * we turn such names into arrays with same index number.  Then, we place them in the Transaction "Properties" so that 
+		 * it can be transferred to subclasses easily.
+		 */ 
+		if(meth.equals(HttpMethods.POST)) {
+			// Here, we'll expect FORM URL Encoded Data, which we need to get from the body
+			gui.route(gui.env, meth, page.url(), 
+				new HttpCode<AuthzTrans,AuthGUI>(gui,page.name()) {
+					@Override
+					public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
+						trans.put(gui.slot_httpServletRequest, req);
+						for(int i=0; i<fields.length;++i) {
+							int idx = fields[i].indexOf("[]");
+							if(idx<0) { // single value
+								trans.put(slots[i], req.getParameter(fields[i])); // assume first value
+							} else { // multi value
+								String field=fields[i].substring(0, idx);
+								String[] array = new String[30];
+								for(Enumeration<String> names = req.getParameterNames(); names.hasMoreElements();) {
+									String key = names.nextElement();
+									if(key.subSequence(0, idx).equals(field)) {
+										try {
+											int x = Integer.parseInt(key.substring(field.length()));
+											if(x>=array.length) {
+												String[] temp = new String[x+10];
+												System.arraycopy(temp, 0, temp, 0, array.length);
+												array = temp;
+											}
+											array[x]=req.getParameter(key);
+										} catch (NumberFormatException e) {
+											trans.debug().log(e);
+										}
+									}
+								}
+								trans.put(slots[i], array);
+							}
+						}
+						page.replay(context,trans,resp.getOutputStream(),"general");
+					}
+				}, "application/x-www-form-urlencoded","*/*");
+
+		} else {
+			// Transfer whether Page shouldn't be cached to local Final var.
+			final boolean no_cache = page.no_cache;
+			
+			gui.route(gui.env, meth, page.url(), 
+				new HttpCode<AuthzTrans,AuthGUI>(gui,page.name()) {
+					@Override
+					public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
+						trans.put(gui.slot_httpServletRequest, req);
+						for(int i=0; i<slots.length;++i) {
+							int idx = fields[i].indexOf("[]");
+							if(idx<0) { // single value
+								trans.put(slots[i], req.getParameter(fields[i]));
+							} else { // multi value
+								String[] array = new String[30];
+								String field=fields[i].substring(0, idx);
+								
+								for(Enumeration<String> mm = req.getParameterNames();mm.hasMoreElements();) {
+									String key = mm.nextElement();
+									if(key.startsWith(field)) {
+										try {
+											int x = Integer.parseInt(key.substring(field.length()));
+											if(x>=array.length) {
+												String[] temp = new String[x+10];
+												System.arraycopy(temp, 0, temp, 0, array.length);
+												array = temp;
+											}
+											array[x]=req.getParameter(key);
+										} catch (NumberFormatException e) {
+											trans.debug().log(e);
+										}
+									}
+								}
+								trans.put(slots[i], array);
+							}
+						}
+						page.replay(context,trans,resp.getOutputStream(),"general");
+					}
+					
+					@Override
+					public boolean no_cache() {
+						return no_cache;
+					}
+				}, "text/html","*/*");
+		}
+
+	}
+	
+	public Page page() { 
+		return get;
+	}
+}
\ No newline at end of file
diff --git a/authz-gui/src/main/java/com/att/authz/gui/Form.java b/authz-gui/src/main/java/com/att/authz/gui/Form.java
new file mode 100644
index 0000000..52f5699
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/Form.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import java.io.IOException;
+
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.html.HTMLGen;
+
+public class Form extends NamedCode {
+	private String preamble;
+	private NamedCode content;
+	
+	public Form(boolean no_cache, NamedCode content) {
+		super(no_cache,content.idattrs());
+		this.content = content;
+		preamble=null;
+		idattrs = content.idattrs();
+	}
+	
+	public Form preamble(String preamble) {
+		this.preamble = preamble;
+		return this;
+	}
+	
+
+	@Override
+	public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+		if(preamble!=null) {
+			hgen.incr("p","class=preamble").text(preamble).end();
+		}
+		hgen.incr("form","method=post");
+	
+		content.code(cache, hgen);
+		
+		hgen.tagOnly("input", "type=submit", "value=Submit")
+			.tagOnly("input", "type=reset", "value=Reset")
+		.end();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.att.authz.gui.NamedCode#idattrs()
+	 */
+	@Override
+	public String[] idattrs() {
+		return content.idattrs();
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/NamedCode.java b/authz-gui/src/main/java/com/att/authz/gui/NamedCode.java
new file mode 100644
index 0000000..90e1170
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/NamedCode.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import com.att.xgen.Code;
+import com.att.xgen.html.HTMLGen;
+
+
+
+public abstract class NamedCode implements Code<HTMLGen> {
+	public final boolean no_cache;
+	protected String[] idattrs;
+	
+	/*
+	 *  Mark whether this code should not be cached, and any attributes 
+	 */
+	public NamedCode(final boolean no_cache, String ... idattrs) {
+		this.idattrs = idattrs;
+		this.no_cache = no_cache;
+	}
+	
+	/**
+	 * Return ID and Any Attributes needed to create a "div" section of this code
+	 * @return
+	 */
+	public String[] idattrs() {
+		return idattrs;
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/Page.java b/authz-gui/src/main/java/com/att/authz/gui/Page.java
new file mode 100644
index 0000000..a8c48e6
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/Page.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import static com.att.xgen.html.HTMLGen.A;
+import static com.att.xgen.html.HTMLGen.H1;
+import static com.att.xgen.html.HTMLGen.LI;
+import static com.att.xgen.html.HTMLGen.TITLE;
+import static com.att.xgen.html.HTMLGen.UL;
+
+import java.io.IOException;
+import java.security.Principal;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.util.Split;
+import com.att.xgen.Cache;
+import com.att.xgen.CacheGen;
+import com.att.xgen.Code;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLCacheGen;
+import com.att.xgen.html.HTMLGen;
+import com.att.xgen.html.Imports;
+
+/**
+ * A Base "Mobile First" Page 
+ * 
+ *
+ */
+public class Page extends HTMLCacheGen {
+	public static enum BROWSER {iPhone,html5,ie,ieOld};
+	
+	public static final int MAX_LINE=20;
+
+	protected static final String[] NO_FIELDS = new String[0];
+
+	private static final String ENV_CONTEXT = "envContext";
+	private static final String DME_SERVICE_NAME = "DMEServiceName";
+	private static final String ROUTE_OFFER = "routeOffer";
+	private static final String BROWSER_TYPE = "BROWSER_TYPE";
+
+	private final String bcName, bcUrl;
+	private final String[] fields;
+
+	public final boolean no_cache;
+
+	public String name() {
+		return bcName;
+	}
+	
+	public String url() {
+		return bcUrl;
+	}
+	
+	public String[] fields() {
+		return fields;
+	}
+	
+	public Page(AuthzEnv env, String name, String url, String [] fields, final NamedCode ... content) throws APIException,IOException {
+		this(env,name,url,1,fields,content);
+	}
+	
+	public Page(AuthzEnv env, String name, String url, int backdots, String [] fields, final NamedCode ... content) throws APIException,IOException {
+		super(CacheGen.PRETTY, new PageCode(env, backdots, content));
+		bcName = name;
+		bcUrl = url;
+		this.fields = fields;
+		// Mark which fields must be "no_cache"
+		boolean no_cacheTemp=false;
+		for(NamedCode nc : content) {
+			if(nc.no_cache) { 
+				no_cacheTemp=true;
+				break;
+			}
+		}
+		no_cache=no_cacheTemp;
+	}
+	
+	private static class PageCode implements Code<HTMLGen> {
+			private final NamedCode[] content;
+			private final Slot browserSlot;
+			private final int backdots;
+			protected AuthzEnv env;
+
+			public PageCode(AuthzEnv env, int backdots, final NamedCode[] content) {
+				this.content = content;
+				this.backdots = backdots;
+				browserSlot = env.slot(BROWSER_TYPE);
+				this.env = env;
+			}
+			
+			@Override
+			public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+				// Note: I found that App Storage saves everything about the page, or not.  Thus, if you declare the page uncacheable, none of the 
+				// Artifacts, like JPGs are stored, which makes this feature useless for Server driven elements
+				//hgen.html("manifest=../theme/aaf.appcache");
+				cache.dynamic(hgen,  new DynamicCode<HTMLGen,AuthGUI,AuthzTrans>() {
+					@Override
+					public void code(AuthGUI state, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+						switch(browser(trans,browserSlot)) {
+							case ieOld:
+							case ie:
+								hgen.directive("!DOCTYPE html");
+								hgen.directive("meta", "http-equiv=X-UA-Compatible","content=IE=11");
+							default:
+						}
+					}
+				});
+				hgen.html();
+				Mark head = hgen.head();
+					hgen.leaf(TITLE).text("AT&amp;T Authentication/Authorization Tool").end();
+					hgen.imports(new Imports(backdots).css("theme/aaf5.css")
+								 			   	.js("theme/comm.js")
+												.js("theme/console.js")
+												.js("theme/common.js"));
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI,AuthzTrans>() {
+						@Override
+						public void code(AuthGUI state, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+							switch(browser(trans,browserSlot)) {
+								case iPhone:
+									hgen.imports(new Imports(backdots).css("theme/aaf5iPhone.css"));
+									break;
+								case ie:
+								case ieOld:
+									hgen.js().text("document.createElement('header');")
+											.text("document.createElement('nav');")
+											.done();
+								case html5:
+									hgen.imports(new Imports(backdots).css("theme/aaf5Desktop.css"));
+									break;
+							}
+						}
+					});
+					hgen.end(head);
+					
+				Mark body = hgen.body();
+					Mark header = hgen.header();
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI,AuthzTrans>() {
+						@Override
+						public void code(AuthGUI state, AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen xgen)
+								throws APIException, IOException {
+							// Obtain Server Info, and print
+							String DMEServiceName = trans.getProperty(DME_SERVICE_NAME);
+							String env = DMEServiceName.substring(
+									DMEServiceName.indexOf(ENV_CONTEXT),
+									DMEServiceName.indexOf(ROUTE_OFFER) -1).split("=")[1];
+							
+							xgen.leaf(H1).text("AT&amp;T Auth Tool on " + env).end();
+							xgen.leaf("p","id=version").text("AAF Version: " + trans.getProperty(Config.AAF_DEPLOYED_VERSION, "N/A")).end();
+							
+							// Obtain User Info, and print
+							Principal p = trans.getUserPrincipal();
+							String user;
+							if(p==null) {
+								user = "please choose a Login Authority";
+							} else {
+								user = p.getName();
+							}
+							xgen.leaf("p","id=welcome").text("Welcome, " + user).end();
+							
+							switch(browser(trans,browserSlot)) {
+								case ieOld:
+								case ie:
+									xgen.incr("h5").text("This app is Mobile First HTML5.  Internet Explorer " 
+											+ " does not support all HTML5 standards. Old, non TSS-Standard versions may not function correctly.").br()
+											.text("  For best results, use a highly compliant HTML5 browser like Firefox.")
+										.end();
+									break;
+								default:
+							}
+						}
+					});
+					
+					hgen.hr();
+					
+					int cIdx;
+					NamedCode nc;
+					// If BreadCrumbs, put here
+					if(content.length>0 && content[0] instanceof BreadCrumbs) {
+						nc = content[0];
+						Mark ctnt = hgen.divID(nc.idattrs());
+						nc.code(cache, hgen);
+						hgen.end(ctnt);
+						cIdx = 1;
+					} else {
+						cIdx = 0;
+					}
+					
+					hgen.end(header);
+					
+					Mark inner = hgen.divID("inner");
+						// Content
+						for(int i=cIdx;i<content.length;++i) {
+							nc = content[i];
+							Mark ctnt = hgen.divID(nc.idattrs());
+							nc.code(cache, hgen);
+							hgen.end(ctnt);
+						}
+
+					hgen.end(inner);	
+					
+					// Navigation - Using older Nav to work with decrepit  IE versions
+					
+					Mark nav = hgen.divID("nav");
+					hgen.incr("h2").text("Related Links").end();
+					hgen.incr(UL)
+						 .leaf(LI).leaf(A,"href="+env.getProperty("aaf_url.aaf_help")).text("AAF WIKI").end(2)
+						 .leaf(LI).leaf(A,"href="+env.getProperty("aaf_url.cadi_help")).text("CADI WIKI").end(2);
+						String tools = env.getProperty("aaf_tools");
+						if(tools!=null) {
+							hgen.hr()
+								.incr(HTMLGen.UL,"style=margin-left:5%")
+							 	.leaf(HTMLGen.H3).text("Related Tools").end();
+
+							for(String tool : Split.splitTrim(',',tools)) {
+								hgen.leaf(LI).leaf(A,"href="+env.getProperty("aaf_url.tool."+tool)).text(tool.toUpperCase() + " Help").end(2);
+							}
+							hgen.end();
+						}
+						 hgen.end();
+					
+					hgen.hr();
+					
+					hgen.end(nav);
+					// Footer - Using older Footer to work with decrepit IE versions
+					Mark footer = hgen.divID("footer");
+						hgen.textCR(1, "(c) 2014-6 AT&amp;T Inc. All Rights Reserved")
+						.end(footer);
+						
+					hgen.end(body);
+				hgen.endAll();
+		}
+	}
+
+	public static String getBrowserType() {
+		return BROWSER_TYPE;
+	}
+	
+	/**
+	 * It's IE if int >=0
+	 * 
+	 * Use int found in "ieVersion"
+	 * 
+	 * Official IE 7
+	 * 		Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; 
+	 * 		.NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
+	 * Official IE 8
+	 * 		Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; 
+	 * 		.NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; ATT)
+	 * 
+	 * IE 11 Compatibility
+	 * 		Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; SLCC2; .NET CLR 2.0.50727; 
+	 * 		.NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E; InfoPath.3; HVD; ATT)
+	 * 
+	 * IE 11 (not Compatiblity)
+	 * 		Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; 
+	 * 		.NET CLR 3.5.30729; .NET CLR 3.0.30729;	Media Center PC 6.0; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E; InfoPath.3; HVD; ATT)
+	 * 
+	 * @param trans
+	 * @return
+	 */
+	public static BROWSER browser(AuthzTrans trans, Slot slot) {
+		BROWSER br = trans.get(slot, null);
+		if(br==null) {
+			String agent = trans.agent();
+			int msie; 
+			if(agent.contains("iPhone") /* other phones? */) {
+				br=BROWSER.iPhone;
+			} else if ((msie = agent.indexOf("MSIE"))>=0) {
+				msie+=5;
+				int end = agent.indexOf(";",msie);
+				float ver;
+				try {
+					ver = Float.valueOf(agent.substring(msie,end));
+					br = ver<8f?BROWSER.ieOld:BROWSER.ie;
+				} catch (Exception e) {
+					br = BROWSER.ie;
+				}
+			} else {
+				br = BROWSER.html5;
+			}
+			trans.put(slot,br);
+		}
+		return br;
+	}
+}
+
diff --git a/authz-gui/src/main/java/com/att/authz/gui/Table.java b/authz-gui/src/main/java/com/att/authz/gui/Table.java
new file mode 100644
index 0000000..f15d4be
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/Table.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import static com.att.xgen.html.HTMLGen.TABLE;
+import static com.att.xgen.html.HTMLGen.TD;
+import static com.att.xgen.html.HTMLGen.TR;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import com.att.authz.gui.table.AbsCell;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.Trans;
+import org.onap.aaf.inno.env.TransStore;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+import com.att.xgen.html.State;
+
+public class Table<S extends State<Env>, TRANS extends TransStore> extends NamedCode {
+	private final Slot ROW_MSG_SLOT, EMPTY_TABLE_SLOT;
+	private final String title;
+	private final String[] columns;
+	private final Rows rows;
+	
+	public Table(String title, TRANS trans, Data<S,TRANS> data, String ... attrs)  {
+		super(true,attrs);
+		ROW_MSG_SLOT=trans.slot("TABLE_ROW_MSG");
+		EMPTY_TABLE_SLOT=trans.slot("TABLE_EMPTY");
+		this.columns = data.headers();
+		boolean alt = false;
+		for(String s : attrs) {
+			if("class=std".equals(s) || "class=stdform".equals(s)) {
+				alt=true;
+			}
+		}
+		rows = new Rows(data,alt?1:0);
+		this.title = title;
+		
+		// Derive an ID from title (from no spaces, etc), and prepend to IDAttributes (Protected from NamedCode)
+		idattrs = new String[attrs.length+1];
+		idattrs[0] = title.replaceAll("\\s","");
+		System.arraycopy(attrs, 0, idattrs, 1, attrs.length);
+	}
+
+	@Override
+	public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+		Mark table = new Mark();
+		Mark tr = new Mark();
+		hgen.incr(table,TABLE)
+				.leaf("caption", "class=title").text(title).end()
+				.incr(tr,TR);
+					for(String column : columns) {
+						hgen.leaf("th").text(column).end();
+					}
+				hgen.end(tr);
+				
+		// Load Rows Dynamically
+		cache.dynamic(hgen, rows);
+		// End Table
+		hgen.end(table); 
+			
+		// Print Message from Row Gathering, if available
+		cache.dynamic(hgen, new DynamicCode<HTMLGen,S,TRANS>() {
+			@Override
+			public void code(S state, TRANS trans, Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+				String msg;
+				if((msg = trans.get(EMPTY_TABLE_SLOT, null))!=null) {
+					hgen.incr("style").text("#inner tr,caption,input,p.preamble {display: none;}#inner p.notfound {margin: 0px 0px 0px 20px}").end();
+					hgen.incr(HTMLGen.P,"class=notfound").text(msg).end().br();
+				} else if((msg=trans.get(ROW_MSG_SLOT,null))!=null) { 
+					hgen.p(msg).br();
+				}
+			}
+		});
+	}
+
+	public static class Cells {
+		public static final Cells EMPTY = new Cells();
+		private Cells() {
+			cells = new AbsCell[0][0];
+			msg = "No Data Found";
+		}
+		
+		public Cells(ArrayList<AbsCell[]> arrayCells, String msg) {
+			cells = new AbsCell[arrayCells.size()][];
+			arrayCells.toArray(cells);
+			this.msg = msg;
+		}
+		public AbsCell[][] cells;
+		public String msg;
+	}
+	
+	public interface Data<S extends State<Env>, TRANS extends Trans> {
+		public Cells get(S state,TRANS trans);
+		public String[] headers();
+	}
+
+	private class Rows extends DynamicCode<HTMLGen,S,TRANS> {
+		private Data<S,TRANS> data;
+		private int alt;
+		
+		public Rows(Data<S,TRANS> data, int alt) {
+			this.data = data;
+			this.alt = alt;
+		}
+		
+		@Override
+		public void code(S state, TRANS trans, Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+			Mark tr = new Mark();
+			Mark td = new Mark();
+			
+			int alt = this.alt;
+			Cells cells = data.get(state, trans);
+			if(cells.cells.length>0) {
+				for(AbsCell[] row : cells.cells) {
+					switch(alt) {
+						case 1:
+							alt=2;
+						case 0:
+							hgen.incr(tr,TR);
+							break;
+						default:
+							alt=1;
+							hgen.incr(tr,TR,"class=alt");
+					}
+					for(AbsCell cell :row) {
+						hgen.leaf(td, TD,cell.attrs());
+						cell.write(hgen);
+						hgen.end(td);
+					}
+					hgen.end(tr);
+				}
+				// Pass Msg back to Table code, in order to place after Table Complete
+				if(cells.msg!=null) {
+					trans.put(ROW_MSG_SLOT,cells.msg);
+				}
+
+			} else {
+				trans.put(EMPTY_TABLE_SLOT,cells.msg);
+			}
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/ApiDocs.java b/authz-gui/src/main/java/com/att/authz/gui/pages/ApiDocs.java
new file mode 100644
index 0000000..75ab331
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/ApiDocs.java
@@ -0,0 +1,304 @@
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.Symm;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import com.att.cssa.rserv.HttpMethods;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Api;
+import aaf.v2_0.Api.Route;
+
+public class ApiDocs extends Page {
+	// Package on purpose
+	private static final String HREF = "/gui/api";
+	private static final String NAME = "AAF RESTful API";
+	private static final String fields[] = {};
+	private static final String ERROR_LINK = "<a href=\"./example/"
+			+ "YXBwbGljYXRpb24vRXJyb3IranNvbg=="
+//			+ Symm.base64noSplit().encode("application/Error+json") 
+			+ "\">JSON</a> "
+			+ "<a href=\"./example/"
+			+ "YXBwbGljYXRpb24vRXJyb3IreG1s"
+//			+ Symm.base64noSplit().encode("application/Error+xml") 
+			+ "\">XML</a> ";
+
+	
+	public ApiDocs(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, fields,
+			new BreadCrumbs(breadcrumbs),
+			new Preamble(),
+			new Table<AuthGUI,AuthzTrans>("AAF API Reference",gui.env.newTransNoAvg(),new Model(), "class=std")
+			);
+	}
+	
+	private static class Preamble extends NamedCode {
+
+		private static final String I = "i";
+
+		public Preamble() {
+			super(false, "preamble");
+		}
+
+		@Override
+		public void code(Cache<HTMLGen> cache, HTMLGen xgen) throws APIException, IOException {
+			xgen.leaf(HTMLGen.H1).text("AAF 2.0 RESTful interface").end()
+				.hr();
+			xgen.leaf(HTMLGen.H2).text("Accessing RESTful").end();
+			xgen.incr(HTMLGen.UL)
+					.leaf(HTMLGen.LI).text("AAF RESTful service is secured by the following:").end()
+					.incr(HTMLGen.UL)
+						.leaf(HTMLGen.LI).text("The Client must utilize HTTP/S. Non Secure HTTP is not acceptable").end()
+						.leaf(HTMLGen.LI).text("The Client MUST supply an Identity validated by one of the following mechanisms").end()
+						.incr(HTMLGen.UL)
+							.leaf(HTMLGen.LI).text("(Near Future) Application level Certificate").end()
+						.end()
+					.end()
+					.leaf(HTMLGen.LI).text("Responses").end()
+					.incr(HTMLGen.UL)
+						.leaf(HTMLGen.LI).text("Each API Entity listed shows what structure will be accepted by service (ContentType) "
+								+ "or responded with by service (Accept). Therefore, use these in making your call. Critical for PUT/POST.").end()
+						.leaf(HTMLGen.LI).text("Each API call may respond with JSON or XML.  Choose the ContentType/Accept that has "
+								+ "+json after the type for JSON or +xml after the Type for XML").end()
+						.leaf(HTMLGen.LI).text("XSDs for Versions").end()
+						.incr(HTMLGen.UL)
+							.leaf(HTMLGen.LI).leaf(HTMLGen.A,"href=../theme/aaf_2_0.xsd").text("API 2.0").end().end()
+						.end()
+						.leaf(HTMLGen.LI).text("AAF can support multiple Versions of the API.  Choose the ContentType/Accept that has "
+								+ "the appropriate version=?.?").end()
+						.leaf(HTMLGen.LI).text("All Errors coming from AAF return AT&T Standard Error Message as a String: " + ERROR_LINK 
+								+ " (does not apply to errors from Container)").end()
+					.end()
+					.leaf(HTMLGen.LI).text("Character Restrictions").end()
+					.incr(HTMLGen.UL)
+						.leaf(HTMLGen.LI).text("Character Restrictions must depend on the Enforcement Point used").end()
+						.leaf(HTMLGen.LI).text("Most AAF usage will be AAF Enforcement Point Characters for Instance and Action are:")
+							.br().br().leaf(I).text("a-zA-Z0-9,.()_-=%").end()
+							.br().br().text("For Instance, you may declare a multi-dimensional key with : (colon) separator, example:").end()
+							.br().leaf(I).text(":myCluster:myKeyspace").end()
+							.br().br().text("The * (asterix) may be used as a wild-card by itself or within the multi-dimensional key, example:")
+							.br().leaf(I).text(":myCluster:*").end()
+							.br().br().text("The % (percent) character can be used as an Escape Character. Applications can use % followed by 2 hexadecimal "
+									+ "digits to cover odd keys.  It is their code, however, which must translate.")
+							.br().br().text("The = (equals) is allowed so that Applications can pass Base64 encodations of binary keys").end()
+						.leaf(HTMLGen.LI).text("Ask for a Consultation on how these are typically used, or, if your tool is the only Enforcement Point, if set may be expanded").end()
+					.end()
+				.end();
+			/*
+			
+			The Content is defined in the AAF XSD - TODO Add aaf.xsdâ€ï¿½;
+			Character Restrictions
+
+			URLs impose restrictions on characters which have specific meanings. This means you cannot have these characters in the Field Content you send
+			“#â€ï¿½ is a “Fragment URLâ€ï¿½, or anchor. Content after this Character is not sent. AAF cannot do anything about this… don’t use it.
+			“?=&â€ï¿½. These are used to delineate Parameters.
+			“/“ is used to separate fields
+			*/
+		}
+		
+	};
+	/**
+	 * Implement the Table Content for Permissions by User
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		public static final String[] HEADERS = new String[] {"Entity","Method","Path Info","Description"};
+		private static final TextCell BLANK = new TextCell("");
+	
+		@Override
+		public String[] headers() {
+			return HEADERS;
+		}
+		
+		@SuppressWarnings("unchecked")
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			ArrayList<AbsCell[]> ns = new ArrayList<AbsCell[]>();
+			ArrayList<AbsCell[]> perms = new ArrayList<AbsCell[]>();
+			ArrayList<AbsCell[]> roles = new ArrayList<AbsCell[]>();
+			ArrayList<AbsCell[]> user = new ArrayList<AbsCell[]>();
+			ArrayList<AbsCell[]> aafOnly = new ArrayList<AbsCell[]>();
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			
+	
+			TimeTaken tt = trans.start("AAF APIs",Env.REMOTE);
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						Future<Api> fa = client.read("/api",gui.apiDF);
+						if(fa.get(5000)) {
+							tt.done();
+							TimeTaken tt2 = trans.start("Load Data", Env.SUB);
+							try {
+								if(fa.value!=null)for(Route r : fa.value.getRoute()) {
+									String path = r.getPath();
+									// Build info
+									StringBuilder desc = new StringBuilder();
+			
+									desc.append("<p class=double>");
+									desc.append(r.getDesc());
+									
+									if(r.getComments().size()>0) {
+										for(String ct : r.getComments()) {
+											desc.append("</p><p class=api_comment>");
+											desc.append(ct);
+										}
+									}
+			
+									if(r.getParam().size()>0) {
+										desc.append("<hr><p class=api_label>Parameters</p>");
+										
+										for(String params : r.getParam()) {
+											String param[] = params.split("\\s*\\|\\s*");
+											desc.append("</p><p class=api_contentType>");
+											desc.append(param[0]);
+											desc.append(" : ");
+											desc.append(param[1]);
+											if("true".equalsIgnoreCase(param[2])) {
+												desc.append(" (Required)");
+											}
+										}
+									}
+			
+			
+									if(r.getExpected()!=0) {
+										desc.append("</p><p class=api_label>Expected HTTP Code</p><p class=api_comment>");
+										desc.append(r.getExpected());
+									} 
+			
+									if(r.getExplicitErr().size()!=0) {
+										desc.append("</p><p class=api_label>Explicit HTTP Error Codes</p><p class=api_comment>");
+										boolean first = true;
+										for(int ee : r.getExplicitErr()) {
+											if(first) {
+												first = false;
+											} else {
+												desc.append(", ");
+											}
+											desc.append(ee);
+										}
+									}
+			
+									desc.append("</p><p class=api_label>");
+									desc.append("GET".equals(r.getMeth())?"Accept:":"ContentType:");
+									Collections.sort(r.getContentType());
+									if(r.getPath().startsWith("/authn/basicAuth")) {
+										desc.append("</p><p class=api_contentType>text/plain");
+									}
+									for(String ct : r.getContentType()) {
+										if(ct.contains("version=2")) {
+											desc.append("</p><p class=api_contentType><a href=\"./example/");
+											try {
+												desc.append(Symm.base64noSplit.encode(ct));
+											} catch (IOException e) {
+												throw new CadiException(e);
+											}
+											desc.append("\"/>");
+											desc.append(ct);
+											desc.append("</a>");
+										}
+									}
+									desc.append("</p>");
+									
+									
+									AbsCell[] sa = new AbsCell[] {
+										null,
+										new TextCell(r.getMeth(),"class=right"),
+										new TextCell(r.getPath()),
+										new TextCell(desc.toString()),
+									};
+			
+									if(path.startsWith("/authz/perm")) {
+										sa[0] = perms.size()==0?new TextCell("PERMISSION"):BLANK;
+										perms.add(sa);
+									} else if(path.startsWith("/authz/role") || path.startsWith("/authz/userRole")) {
+										sa[0] = roles.size()==0?new TextCell("ROLE"):BLANK;
+										roles.add(sa);
+									} else if(path.startsWith("/authz/ns")) {
+										sa[0] = ns.size()==0?new TextCell("NAMESPACE"):BLANK;
+										ns.add(sa);
+									} else if(path.startsWith("/authn/basicAuth") 
+										|| path.startsWith("/authn/validate")
+										|| path.startsWith("/authz/user")) {
+										sa[0] = user.size()==0?new TextCell("USER"):BLANK;
+										user.add(sa);
+									} else {
+										sa[0] = aafOnly.size()==0?new TextCell("AAF ONLY"):BLANK;
+										aafOnly.add(sa);
+									}
+								}
+								//TODO if(trans.fish(p))
+								prepare(rv, perms,roles,ns,user);
+							} finally {
+								tt2.done();
+							}
+						} else {
+							gui.writeError(trans, fa, null);
+						}
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				trans.error().log(e.getMessage());
+			} finally {
+				tt.done();
+			}
+			
+			return new Cells(rv,null);
+		}
+
+		@SuppressWarnings("unchecked")
+		private void prepare(ArrayList<AbsCell[]> rv, ArrayList<AbsCell[]> ... all) {
+			AbsCell lead;
+			AbsCell[] row;
+			for(ArrayList<AbsCell[]> al : all) {
+				if(al.size()>1) {
+					row = al.get(0);
+					lead = row[0];
+					row[0]=BLANK;
+					al.get(0).clone()[0]=BLANK;
+					Collections.sort(al, new Comparator<AbsCell[]>() {
+						@Override
+						public int compare(AbsCell[] ca1, AbsCell[] ca2) {
+							int meth = ((TextCell)ca1[2]).name.compareTo(
+									   ((TextCell)ca2[2]).name);
+							if(meth == 0) {
+								return (HttpMethods.valueOf(((TextCell)ca1[1]).name).compareTo(
+										HttpMethods.valueOf(((TextCell)ca2[1]).name)));
+							} else { 
+								return meth;
+							}
+						}
+					});
+					// set new first row
+					al.get(0)[0]=lead;
+
+					rv.addAll(al);
+				}
+			}
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/ApiExample.java b/authz-gui/src/main/java/com/att/authz/gui/pages/ApiExample.java
new file mode 100644
index 0000000..5e8f81c
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/ApiExample.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.Symm;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Data.TYPE;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Error;
+
+/**
+ * Detail Page for Permissions
+ * 
+ *
+ */
+public class ApiExample extends Page {
+	public static final String HREF = "/gui/example/:tc";
+	public static final String NAME = "APIExample";
+
+	public ApiExample(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME, HREF, 2/*backdots*/, new String[] {"API Code Example"},
+				new BreadCrumbs(breadcrumbs),
+				new Model()
+				);
+	}
+	
+	private static class Model extends NamedCode {
+		private static final String WITH_OPTIONAL_PARAMETERS = "\n\n////////////\n  Data with Optional Parameters \n////////////\n\n";
+
+		public Model() {
+			super(false);
+		}
+
+		@Override
+		public void code(Cache<HTMLGen> cache, HTMLGen xgen) throws APIException, IOException {
+			Mark inner = xgen.divID("inner");
+			xgen.divID("example","class=std");
+			cache.dynamic(xgen, new DynamicCode<HTMLGen,AuthGUI,AuthzTrans>() {
+				@Override
+				public void code(final AuthGUI gui, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen xgen) throws APIException, IOException {
+					TimeTaken tt = trans.start("Code Example",Env.REMOTE);
+					try {
+						final String typecode;
+						int prefix = trans.path().lastIndexOf('/')+1;
+						String encoded = trans.path().substring(prefix);
+						typecode = Symm.base64noSplit.decode(encoded);
+						Future<String> fp = gui.client().read("/api/example/" + encoded,
+								"application/Void+json"
+								);
+						Future<String> fs2;
+						if(typecode.contains("Request+")) {
+							fs2 = gui.client().read("/api/example/" + typecode+"?optional=true",
+									"application/Void+json"
+									);
+						} else {
+							fs2=null;
+						}
+						
+						
+						if(fp.get(5000)) {
+								xgen.incr(HTMLGen.H1).text("Sample Code").end()
+								.incr(HTMLGen.H5).text(typecode).end();
+								xgen.incr("pre");
+								if(typecode.contains("+xml")) {
+									xgen.xml(fp.body());
+									if(fs2!=null && fs2.get(5000)) {
+										xgen.text(WITH_OPTIONAL_PARAMETERS);
+										xgen.xml(fs2.body());
+									}
+								} else {
+									xgen.text(fp.body());
+									if(fs2!=null && fs2.get(5000)) {
+										xgen.text(WITH_OPTIONAL_PARAMETERS);
+										xgen.text(fs2.body());
+									}
+								}
+								xgen.end();
+						} else {
+							Error err = gui.errDF.newData().in(TYPE.JSON).load(fp.body()).asObject();
+							xgen.incr(HTMLGen.H3)
+								.textCR(2,"Error from AAF Service")
+								.end();
+							
+							xgen.p("Error Code: ",err.getMessageId())
+								.p(err.getText())
+								.end();
+								
+						}
+
+					} catch (APIException e) {
+						throw e;
+					} catch (IOException e) {
+						throw e;
+					} catch (Exception e) {
+						throw new APIException(e);
+					}finally {
+						tt.done();
+					}
+				}
+					
+			});
+			xgen.end(inner);
+		}
+	}
+
+}		
+		
\ No newline at end of file
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalAction.java
new file mode 100644
index 0000000..22230cc
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalAction.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Approval;
+import aaf.v2_0.Approvals;
+
+public class ApprovalAction extends Page {
+	public ApprovalAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,"Approvals",ApprovalForm.HREF, ApprovalForm.FIELDS,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+				final Slot sAppr = gui.env.slot(ApprovalForm.NAME+'.'+ApprovalForm.FIELDS[0]);
+				final Slot sUser = gui.env.slot(ApprovalForm.NAME+'.'+ApprovalForm.FIELDS[1]);
+				
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {				
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(final AuthGUI gui, final AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+							boolean fail = true;
+							String[] appr = trans.get(sAppr,null);
+							String user = trans.get(sUser,null);
+							String lastPage = ApprovalForm.HREF;
+							if (user != null) {
+								lastPage += "?user="+user;
+							}
+							
+							if(appr==null) {
+								hgen.p("No Approvals have been selected.");
+							} else {
+								Approval app;
+								final Approvals apps = new Approvals();
+								int count = 0;
+								for(String a : appr) {
+									if(a!=null) {
+										int idx = a.indexOf('|');
+										if(idx>=0) {
+											app = new Approval();
+											app.setStatus(a.substring(0,idx));
+											app.setTicket(a.substring(++idx));
+											app.setApprover(trans.getUserPrincipal().getName());
+											apps.getApprovals().add(app);
+											++count;
+										}
+									}
+								}
+								if(apps.getApprovals().isEmpty()) {
+									hgen.p("No Approvals have been sent.");
+								} else {
+									TimeTaken tt = trans.start("AAF Update Approvals",Env.REMOTE);
+									try {
+										final int total = count;
+										fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Boolean>() {
+											@Override
+											public Boolean code(Rcli<?> client) throws APIException, CadiException  {
+												boolean fail2 = true;
+												Future<Approvals> fa = client.update("/authz/approval",gui.approvalsDF,apps);
+												if(fa.get(AuthGUI.TIMEOUT)) {
+													// Do Remote Call
+													fail2 = false;
+													hgen.p(total + (total==1?" Approval has":" Approvals have") + " been Saved");
+												} else {
+													gui.writeError(trans, fa, hgen);
+												}
+												return fail2;
+											}
+										});
+									} catch (Exception e) {
+										e.printStackTrace();
+									} finally {
+										tt.done();
+									}
+								}
+
+							hgen.br();
+							if(fail) {
+								hgen.incr("a",true,"href="+lastPage).text("Try again").end();
+							} else {
+								hgen.incr("a",true,"href="+Home.HREF).text("Home").end(); 
+							}
+							}
+						}
+					});
+				}
+			});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalForm.java
new file mode 100644
index 0000000..e6cf041
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalForm.java
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Form;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.ButtonCell;
+import com.att.authz.gui.table.RadioCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextAndRefCell;
+import com.att.authz.gui.table.TextCell;
+import com.att.authz.org.Organization;
+import com.att.authz.org.Organization.Identity;
+import com.att.authz.org.OrganizationFactory;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Approval;
+
+public class ApprovalForm extends Page {
+	// Package on purpose
+	static final String NAME="Approvals";
+	static final String HREF = "/gui/approve";
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	static final String[] FIELDS = new String[] {"line[]","user"};
+	
+	
+	public ApprovalForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, FIELDS,
+
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(false, "filterByUser") {
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+							String user = trans.get(trans.env().slot(NAME+".user"),"");
+							hgen.incr("p", "class=userFilter")
+								.text("Filter by User:")
+								.tagOnly("input", "type=text", "value="+user, "id=userTextBox")
+								.tagOnly("input", "type=button", "onclick=userFilter('"+HREF+"');", "value=Go!")
+								.end();
+								}
+					});
+				}
+			},
+			new Form(true,new Table<AuthGUI,AuthzTrans>("Approval Requests", gui.env.newTransNoAvg(),new Model(gui.env()),"class=stdform"))
+				.preamble("The following requires your Approval to proceed in the AAF System.</p><p class=subtext>Hover on Identity for Name; click for WebPhone"),
+			new NamedCode(false, "selectAlljs") {
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					Mark jsStart = new Mark();
+					hgen.js(jsStart);
+					hgen.text("function selectAll(radioClass) {");
+					hgen.text("var radios = document.querySelectorAll(\".\"+radioClass);");
+					hgen.text("for (i = 0; i < radios.length; i++) {");
+					hgen.text("radios[i].checked = true;");
+					hgen.text("}");
+					hgen.text("}");
+					hgen.end(jsStart);
+				}
+			});
+		
+	}
+	
+	/**
+	 * Implement the Table Content for Approvals
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[] {"Identity","Request","Approve","Deny"};
+		private static final Object THE_DOMAIN = null;
+		private Slot sUser;
+		
+		public Model(AuthzEnv env) {
+			sUser = env.slot(NAME+".user");
+		}
+		
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String userParam = trans.get(sUser, null);
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			String msg = null;
+			TimeTaken tt = trans.start("AAF Get Approvals for Approver",Env.REMOTE);
+			try {
+				final List<Approval> pendingApprovals = new ArrayList<Approval>();
+				final List<Integer> beginIndicesPerApprover = new ArrayList<Integer>();
+				int numLeft = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Integer>() {
+					@Override
+					public Integer code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						Future<aaf.v2_0.Approvals> fa = client.read("/authz/approval/approver/"+trans.user(),gui.approvalsDF);
+						int numLeft = 0;
+						if(fa.get(AuthGUI.TIMEOUT)) {
+							
+							if(fa.value!=null) {
+								for (Approval appr : fa.value.getApprovals()) {
+									if (appr.getStatus().equals("pending")) {
+										if (userParam!=null) {
+											if (!appr.getUser().equalsIgnoreCase(userParam)) {
+												numLeft++;
+												continue;
+											}
+										}
+										pendingApprovals.add(appr);
+									}
+								}
+							}
+							
+							String prevApprover = null;
+							int overallIndex = 0;
+								
+							for (Approval appr : pendingApprovals) {
+								String currApprover = appr.getApprover();
+								if (!currApprover.equals(prevApprover)) {
+									prevApprover = currApprover;
+									beginIndicesPerApprover.add(overallIndex);
+								}
+								overallIndex++;
+							}
+						}
+						return numLeft;
+					}
+				});
+				
+				if (pendingApprovals.size() > 0) {
+					// Only add select all links if we have approvals
+					AbsCell[] selectAllRow = new AbsCell[] {
+							AbsCell.Null,
+							AbsCell.Null,
+							new ButtonCell("all", "onclick=selectAll('approve')", "class=selectAllButton"),
+							new ButtonCell("all", "onclick=selectAll('deny')", "class=selectAllButton")
+						};
+					rv.add(selectAllRow);
+				}
+						
+				int line=-1;
+				
+				while (beginIndicesPerApprover.size() > 0) {
+					int beginIndex = beginIndicesPerApprover.remove(0);
+					int endIndex = (beginIndicesPerApprover.isEmpty()?pendingApprovals.size():beginIndicesPerApprover.get(0));
+					List<Approval> currApproverList = pendingApprovals.subList(beginIndex, endIndex);
+					
+					String currApproverFull = currApproverList.get(0).getApprover();
+					String currApproverShort = currApproverFull.substring(0,currApproverFull.indexOf('@'));
+					String currApprover = (trans.user().indexOf('@')<0?currApproverShort:currApproverFull);
+					if (!currApprover.equals(trans.user())) {
+						AbsCell[] approverHeader;
+						if (currApproverFull.substring(currApproverFull.indexOf('@')).equals(THE_DOMAIN)) {
+							approverHeader = new AbsCell[] { 
+									new TextAndRefCell("Approvals Delegated to Me by ", currApprover,
+											WEBPHONE + currApproverShort, 
+											new String[] {"colspan=4", "class=head"})
+							};
+						} else {
+							approverHeader = new AbsCell[] { 
+									new TextCell("Approvals Delegated to Me by " + currApprover,
+											new String[] {"colspan=4", "class=head"})
+							};
+						}
+						rv.add(approverHeader);
+					}
+					
+					// Sort by User Requesting
+					Collections.sort(currApproverList, new Comparator<Approval>() {
+						@Override
+						public int compare(Approval a1, Approval a2) {
+							return a1.getUser().compareTo(a2.getUser());
+						}
+					});
+					
+					String prevUser = null;
+					for (Approval appr : currApproverList) {
+						if(++line<MAX_LINE) { // limit number displayed at one time.
+							AbsCell userCell;
+							String user = appr.getUser();
+							if(user.equals(prevUser)) {
+								userCell = AbsCell.Null; 
+							} else {
+								String title;
+								Organization org = OrganizationFactory.obtain(trans.env(), user);
+								if(org==null) {
+									title="";
+								} else {
+									Identity au = org.getIdentity(trans, user);
+									if(au!=null) {
+										if(au.type().equals("MECHID")) {
+											title="title=Sponsor is " + au.responsibleTo();
+										} else {
+											title="title=" + au.fullName();
+										}
+									} else {
+										title="";
+									}
+								}
+								userCell = new RefCell(prevUser=user, 
+									"" //TODO add Organization Link ability
+									,title);
+							}
+							AbsCell[] sa = new AbsCell[] {
+								userCell,
+								new TextCell(appr.getMemo()),
+								new RadioCell("line"+ line,"approve", "approved|"+appr.getTicket()),
+								new RadioCell("line"+ line,"deny", "denied|"+appr.getTicket())
+							};
+							rv.add(sa);
+						} else {
+							++numLeft;
+						}
+					}
+				}
+				if(numLeft>0) {
+					msg = "After these, there will be " + numLeft + " approvals left to process";
+				}
+				if(rv.size()==0) {
+					if (numLeft>0) {
+						msg = "No Approvals to process at this time for user " + userParam +". You have " 
+							+ numLeft + " other approvals to process.";
+					} else {
+						msg = "No Approvals to process at this time";
+					}
+				}
+			} catch (Exception e) {
+				trans.error().log(e);
+			} finally {
+				tt.done();
+			}
+		return new Cells(rv,msg);
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/Home.java b/authz-gui/src/main/java/com/att/authz/gui/pages/Home.java
new file mode 100644
index 0000000..3c6abd0
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/Home.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.A;
+import static com.att.xgen.html.HTMLGen.H3;
+
+import java.io.IOException;
+
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+
+public class Home extends Page {
+	public static final String HREF = "/gui/home";
+	public Home(final AuthGUI gui) throws APIException, IOException {
+		super(gui.env,"Home",HREF, NO_FIELDS, new NamedCode(false,"content") {
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen xgen) throws APIException, IOException {
+//				// TEMP
+//				JSGen jsg = xgen.js();
+//				jsg.function("httpPost","sURL","sParam")
+//					.text("var oURL = new java.net.URL(sURL)")
+//					.text("var oConn = oURL.openConnection();")
+//					.text("oConn.setDoInput(true);")
+//					.text("oConn.setDoOutpu(true);")
+//					.text("oConn.setUseCaches(false);")
+//					.text("oConn.setRequestProperty(\"Content-Type\",\"application/x-www-form-urlencoded\");")
+//					.text(text)
+//				jsg.done();
+				// TEMP
+				final Mark pages = xgen.divID("Pages");
+				xgen.leaf(H3).text("Choose from the following:").end()
+					.leaf(A,"href=myperms").text("My Permissions").end()
+					.leaf(A,"href=myroles").text("My Roles").end()
+				//	TODO: uncomment when on cassandra 2.1.2 for MyNamespace GUI page
+					.leaf(A,"href=mynamespaces").text("My Namespaces").end()
+					.leaf(A,"href=approve").text("My Approvals").end()
+					.leaf(A, "href=myrequests").text("My Pending Requests").end()
+					// Enable later
+//					.leaf(A, "href=onboard").text("Onboarding").end()
+				// Password Change.  If logged in as CSP/GSO, go to their page
+					.leaf(A,"href=passwd").text("Password Management").end()
+					.leaf(A,"href=cui").text("Command Prompt").end()
+					.leaf(A,"href=api").text("AAF API").end()
+					;
+				
+				xgen.end(pages);
+			}
+		});
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLanding.java b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLanding.java
new file mode 100644
index 0000000..6ca1608
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLanding.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.URLDecoder;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class LoginLanding extends Page {
+	public static final String HREF = "/login";
+	static final String NAME = "Login";
+	static final String fields[] = {"id","password","environment"};
+	static final String envs[] = {"DEV","TEST","PROD"};
+	
+	public LoginLanding(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME,HREF, fields, new NamedCode(true, "content") {
+			@Override
+			public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+				hgen.leaf("p").text("No login credentials are found in your current session. " +
+					     "Choose your preferred login option to continue.").end();
+				
+				Mark loginPaths = hgen.divID("Pages");
+				
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI authGUI, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen xgen) throws APIException, IOException {
+						HttpServletRequest req = trans.get(gui.slot_httpServletRequest, null);
+						if(req!=null) {
+							String query = req.getQueryString();
+							if(query!=null) {
+								for(String qs : query.split("&")) {
+									int equals = qs.indexOf('=');
+									xgen.leaf(HTMLGen.A, "href="+URLDecoder.decode(qs.substring(equals+1),Config.UTF_8)).text(qs.substring(0,equals).replace('_', ' ')).end();
+								}
+							}
+						}
+						xgen.leaf(HTMLGen.A, "href=gui/home?Authentication=BasicAuth").text("AAF Basic Auth").end();
+					}
+				});
+//				hgen.leaf("a", "href=#","onclick=divVisibility('cso');").text("Global Login").end()
+//					.incr("p", "id=cso","style=display:none").text("this will redirect to global login").end()
+//					.leaf("a", "href=#","onclick=divVisibility('tguard');").text("tGuard").end()
+//					.incr("p", "id=tguard","style=display:none").text("this will redirect to tGuard login").end()
+//				hgen.leaf("a", "href=#","onclick=divVisibility('basicauth');").text("AAF Basic Auth").end();
+				hgen.end(loginPaths);
+				
+//					hgen.incr("form","method=post","style=display:none","id=basicauth","gui/home?Authentication=BasicAuth");
+//					Mark table = new Mark(TABLE);
+//					hgen.incr(table);
+//					cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+//						@Override
+//						public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	
+//								throws APIException, IOException {
+//							hgen
+//							.input(fields[0],"Username",true)
+//							.input(fields[1],"Password",true, "type=password");
+//						Mark selectRow = new Mark();
+//						hgen
+//						.incr(selectRow, "tr")
+//						.incr("td")
+//						.incr("label", "for=envs", "required").text("Environment").end()
+//						.end()
+//						.incr("td")
+//						.incr("select", "name=envs", "id=envs", "required")
+//						.incr("option", "value=").text("Select Environment").end();
+//						for (String env : envs) {
+//							hgen.incr("option", "value="+env).text(env).end();
+//						}
+//						hgen			
+//						.end(selectRow) 
+							
+//						hgen.end();
+//						}
+//					});
+//					hgen.end();
+//					hgen.tagOnly("input", "type=submit", "value=Submit")
+//						.tagOnly("input", "type=reset", "value=Reset")
+//					.end();
+			
+
+			}
+		});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLandingAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLandingAction.java
new file mode 100644
index 0000000..d70aca4
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLandingAction.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Slot;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+public class LoginLandingAction extends Page {
+	public LoginLandingAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,"Login",LoginLanding.HREF, LoginLanding.fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+				final Slot sID = gui.env.slot(LoginLanding.NAME+'.'+LoginLanding.fields[0]);
+//				final Slot sPassword = gui.env.slot(LoginLanding.NAME+'.'+LoginLanding.fields[1]);
+				
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(final AuthGUI gui, final AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+							String username = trans.get(sID,null);
+//							String password = trans.get(sPassword,null);
+
+							hgen.p("User: "+username);
+							hgen.p("Pass: ********");
+							
+							// TODO: clarification from JG
+							// put in request header?
+							// then pass through authn/basicAuth call?
+							
+						}
+					});
+				}
+		});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsDetail.java
new file mode 100644
index 0000000..75ff137
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsDetail.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import com.att.cmd.AAFcli;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+
+import aaf.v2_0.Nss;
+import aaf.v2_0.Nss.Ns;
+import aaf.v2_0.Perm;
+import aaf.v2_0.Perms;
+import aaf.v2_0.Role;
+import aaf.v2_0.Roles;
+import aaf.v2_0.Users;
+import aaf.v2_0.Users.User;
+
+public class NsDetail extends Page {
+	
+	public static final String HREF = "/gui/nsdetail";
+	public static final String NAME = "NsDetail";
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	public static enum NS_FIELD { OWNERS, ADMINS, ROLES, PERMISSIONS, CREDS};
+	private static final String BLANK = "";
+
+	public NsDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME, HREF, new String[] {"name"}, 
+				new BreadCrumbs(breadcrumbs),
+				new Table<AuthGUI,AuthzTrans>("Namespace Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+				);
+	}
+
+	/**
+	 * Implement the table content for Namespace Detail
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[0];		
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		private Slot name;
+		public Model(AuthzEnv env) {
+			name = env.slot(NAME+".name");
+		}
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String nsName = trans.get(name, null);
+			if(nsName==null) {
+				return Cells.EMPTY;
+			}
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			rv.add(new AbsCell[]{new TextCell("Name:"),new TextCell(nsName)});
+
+			final TimeTaken tt = trans.start("AAF Namespace Details",Env.REMOTE);
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(),new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						Future<Nss> fn = client.read("/authz/nss/"+nsName,gui.nssDF);
+
+						if(fn.get(AuthGUI.TIMEOUT)) {
+							tt.done();
+							try {
+//								TimeTaken tt = trans.start("Load Data", Env.SUB);
+								
+								for(Ns n : fn.value.getNs()) {
+									String desc = (n.getDescription()!=null?n.getDescription():BLANK);
+									rv.add(new AbsCell[]{new TextCell("Description:"),new TextCell(desc)});
+									
+									addField(trans, rv, n.getAdmin(), NS_FIELD.ADMINS);
+									addField(trans, rv, n.getResponsible(), NS_FIELD.OWNERS);
+			
+									Future<Users> fu = client.read(
+													"/authn/creds/ns/"+nsName, 
+													gui.usersDF
+													);
+									List<String> creds = new ArrayList<String>();
+									if(fu.get(AAFcli.timeout())) {
+										for (User u : fu.value.getUser()) {
+											StringBuilder sb = new StringBuilder(u.getId());
+											switch(u.getType()) {
+												case 1: sb.append(" (U/Pass) "); break;
+												case 10: sb.append(" (Cert) "); break;
+												case 200: sb.append(" (x509) "); break;
+												default:
+													sb.append(" ");
+											}
+											sb.append(Chrono.niceDateStamp(u.getExpires()));
+											creds.add(sb.toString());
+										}
+									}
+									addField(trans, rv, creds, NS_FIELD.CREDS);
+			
+									Future<Roles> fr = client.read(
+													"/authz/roles/ns/"+nsName, 
+													gui.rolesDF
+													);
+									List<String> roles = new ArrayList<String>();
+									if(fr.get(AAFcli.timeout())) {
+										for (Role r : fr.value.getRole()) {
+											roles.add(r.getName());
+										}
+									}
+									addField(trans, rv, roles, NS_FIELD.ROLES);
+									
+									
+									Future<Perms> fp = client.read(
+													"/authz/perms/ns/"+nsName, 
+													gui.permsDF
+													);
+									List<String> perms = new ArrayList<String>();
+			
+									if(fp.get(AAFcli.timeout())) {
+										for (Perm p : fp.value.getPerm()) {
+											perms.add(p.getType() + "|" + p.getInstance() + "|" + p.getAction());
+										}
+									}
+									addField(trans, rv, perms, NS_FIELD.PERMISSIONS);
+								}
+								String historyLink = NsHistory.HREF 
+										+ "?name=" + nsName;
+								rv.add(new AbsCell[] {new RefCell("See History",historyLink)});
+							} finally {
+								tt.done();
+							}
+						} else {
+							rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
+						}
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				e.printStackTrace();
+			} finally {
+				tt.done();
+			}
+			return new Cells(rv,null);
+		}
+
+		private void addField(AuthzTrans trans, ArrayList<AbsCell[]> rv, List<String> values, NS_FIELD field) {
+			if (!values.isEmpty()) {
+				switch(field) {
+				case OWNERS:
+				case ADMINS:
+				case CREDS:
+					for (int i=0; i< values.size(); i++) {
+						AbsCell label = (i==0?new TextCell(sentenceCase(field)+":"):AbsCell.Null);
+						String user = values.get(i);
+						AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+								new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+						rv.add(new AbsCell[] {
+								label, 
+								userCell
+						});
+					}
+					break;
+				case ROLES:
+					for (int i=0; i< values.size(); i++) {
+						AbsCell label = (i==0?new TextCell(sentenceCase(field)+":"):AbsCell.Null);
+						rv.add(new AbsCell[] {
+								label, 
+								new TextCell(values.get(i))
+						});
+					}
+					break;
+				case PERMISSIONS:
+					for (int i=0; i< values.size(); i++) {
+						AbsCell label = (i==0?new TextCell(sentenceCase(field)+":"):AbsCell.Null);
+						String perm = values.get(i);
+						String[] fields = perm.split("\\|");
+						String grantLink = PermGrantForm.HREF 
+								+ "?type=" + fields[0].trim()
+								+ "&amp;instance=" + fields[1].trim()
+								+ "&amp;action=" + fields[2].trim();
+						
+						rv.add(new AbsCell[] {
+								label, 
+								new TextCell(perm),
+								new RefCell("Grant This Perm", grantLink)
+						});
+					}
+					break;
+				}
+
+			}
+		}
+
+		private String sentenceCase(NS_FIELD field) {
+			String sField = field.toString();
+			return sField.substring(0, 1).toUpperCase() + sField.substring(1).toLowerCase();
+		}
+	
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsHistory.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsHistory.java
new file mode 100644
index 0000000..653b9e7
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsHistory.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.History;
+import aaf.v2_0.History.Item;
+
+public class NsHistory extends Page {
+	static final String NAME="NsHistory";
+	static final String HREF = "/gui/nsHistory";
+	static final String FIELDS[] = {"name","dates"};
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, 
+							AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
+	
+	public NsHistory(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, FIELDS,
+			new BreadCrumbs(breadcrumbs),
+			new Table<AuthGUI,AuthzTrans>("History", gui.env.newTransNoAvg(),new Model(gui.env()),"class=std"),
+			new NamedCode(true, "content") {
+				@Override
+				public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+					final Slot name = gui.env.slot(NAME+".name");
+					cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+							String obName = trans.get(name, null);
+							
+							// Use Javascript to make the table title more descriptive
+							hgen.js()
+							.text("var caption = document.querySelector(\".title\");")
+							.text("caption.innerHTML='History for Namespace [ " + obName + " ]';")						
+							.done();
+							
+							// Use Javascript to change Link Target to our last visited Detail page
+							String lastPage = NsDetail.HREF + "?name=" + obName;
+							hgen.js()
+								.text("alterLink('nsdetail', '"+lastPage + "');")							
+								.done();
+							
+							hgen.br();
+							hgen.leaf("a","href=#advanced_search","onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+								.divID("advanced_search", "style=display:none");
+							hgen.incr("table");
+								
+							addDateRow(hgen,"Start Date");
+							addDateRow(hgen,"End Date");
+							hgen.incr("tr").incr("td");
+							hgen.tagOnly("input", "type=button","value=Get History",
+									"onclick=datesURL('"+HREF+"?name=" + obName+"');");
+							hgen.end().end();
+							hgen.end();
+							hgen.end();
+								
+						}
+					});
+				}
+			}
+
+			);
+	}
+
+	private static void addDateRow(HTMLGen hgen, String s) {
+		hgen
+			.incr("tr")
+			.incr("td")
+			.incr("label", "for=month", "required").text(s+"*").end()
+			.end()
+			.incr("td")
+			.incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
+			.incr("option", "value=").text("Month").end();
+		for (Month m : Month.values()) {
+			if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
+				hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
+			} else {
+				hgen.incr("option", "value="+(m.ordinal()+1)).text(m.name()).end();
+			}
+		}
+		hgen.end()
+			.end()
+			.incr("td")
+			.tagOnly("input","type=number","id=year"+s.substring(0, s.indexOf(' ')),"required",
+					"value="+Calendar.getInstance().get(Calendar.YEAR), "min=1900", 
+					"max="+Calendar.getInstance().get(Calendar.YEAR),
+					"placeholder=Year").end()
+			.end();
+	}
+		
+
+	
+	
+	/**
+	 * Implement the Table Content for History
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		private static final String[] headers = new String[] {"Date","User","Memo"};
+		private Slot name;
+		private Slot dates;
+		
+		public Model(AuthzEnv env) {
+			name = env.slot(NAME+".name");
+			dates = env.slot(NAME+".dates");
+		}
+		
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String oName = trans.get(name,null);
+			final String oDates = trans.get(dates,null);
+			
+			if(oName==null) {
+				return Cells.EMPTY;
+			}
+			
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			String msg = null;
+			final TimeTaken tt = trans.start("AAF Get History for Namespace ["+oName+"]",Env.REMOTE);
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						if (oDates != null) {
+							client.setQueryParams("yyyymm="+oDates);
+						}
+						Future<History> fh = client.read("/authz/hist/ns/"+oName,gui.historyDF);
+						if (fh.get(AuthGUI.TIMEOUT)) {
+							tt.done();
+							TimeTaken tt2 = trans.start("Load History Data", Env.SUB);
+							try {
+								List<Item> histItems = fh.value.getItem();
+								
+								java.util.Collections.sort(histItems, new Comparator<Item>() {
+									@Override
+									public int compare(Item o1, Item o2) {
+										return o2.getTimestamp().compare(o1.getTimestamp());
+									}
+								});
+								
+								for (Item i : histItems) {
+									String user = i.getUser();
+									AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+											new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+									
+									rv.add(new AbsCell[] {
+											new TextCell(i.getTimestamp().toGregorianCalendar().getTime().toString()),
+											userCell,
+											new TextCell(i.getMemo())
+									});
+								}
+							} finally {
+								tt2.done();
+							}
+						} else {
+							if (fh.code()==403) {
+								rv.add(new AbsCell[] {new TextCell("You may not view History of Namespace [" + oName + "]", "colspan = 3", "class=center")});
+							} else {
+								rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***", "colspan = 3", "class=center")});
+							}
+						}
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				trans.error().log(e);
+			} finally {
+				tt.done();
+			}
+		return new Cells(rv,msg);
+		}
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoAction.java
new file mode 100644
index 0000000..19a90c3
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoAction.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.ParseException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.CredRequest;
+
+public class NsInfoAction extends Page {
+	public NsInfoAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,"Onboard",PassChangeForm.HREF, PassChangeForm.fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+				final Slot sID = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[0]);
+				final Slot sCurrPass = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[1]);
+				final Slot sPassword = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[2]);
+				final Slot sPassword2 = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[3]);
+				final Slot startDate = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[4]);
+				
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(final AuthGUI gui, final AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+							String id = trans.get(sID,null);
+							String currPass = trans.get(sCurrPass,null);
+							String password = trans.get(sPassword,null);
+							String password2 = trans.get(sPassword2,null);
+							
+							// Run Validations
+							boolean fail = true;
+							
+							if (id==null || id.indexOf('@')<=0) {
+								hgen.p("Data Entry Failure: Please enter a valid ID, including domain.");
+							} else if(password == null || password2 == null || currPass == null) {
+								hgen.p("Data Entry Failure: Both Password Fields need entries.");
+							} else if(!password.equals(password2)) {
+								hgen.p("Data Entry Failure: Passwords do not match.");
+							} else { // everything else is checked by Server
+								final CredRequest cred = new CredRequest();
+								cred.setId(id);
+								cred.setPassword(currPass);
+								try {
+									fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Boolean>() {
+										@Override
+										public Boolean code(Rcli<?> client)throws CadiException, ConnectException, APIException {
+											TimeTaken tt = trans.start("Check Current Password",Env.REMOTE);
+											try {
+												Future<CredRequest> fcr = client.create( // Note: Need "Post", because of hiding password in SSL Data
+															"/authn/validate",
+															gui.credReqDF,
+															cred
+														);
+												boolean go;
+												boolean fail = true;
+												fcr.get(5000);
+												if(fcr.code() == 200) {
+													hgen.p("Current Password validated");
+													go = true;
+												} else {
+													hgen.p(String.format("Invalid Current Password: %d %s",fcr.code(),fcr.body()));
+													go = false;
+												}
+												if(go) {
+													tt.done();
+													tt = trans.start("AAF Change Password",Env.REMOTE);
+													try {
+														// Change over Cred to reset mode
+														cred.setPassword(password);
+														String start = trans.get(startDate, null);
+														if(start!=null) {
+															try {
+																cred.setStart(Chrono.timeStamp(Chrono.dateOnlyFmt.parse(start)));
+															} catch (ParseException e) {
+																throw new CadiException(e);
+															}
+														}
+														
+														fcr = client.create(
+																"/authn/cred",
+																gui.credReqDF,
+																cred
+																);
+					
+														if(fcr.get(5000)) {
+															// Do Remote Call
+															hgen.p("New Password has been added.");
+															fail = false;
+														} else {
+															gui.writeError(trans, fcr, hgen);
+														}
+													} finally {
+														tt.done();
+													}
+												}
+ 												return fail;
+											} finally {
+												tt.done();
+											}
+										}
+									});
+
+								} catch (Exception e) {
+									hgen.p("Unknown Error");
+									e.printStackTrace();
+								}
+							}
+						hgen.br();
+						if(fail) {
+							hgen.incr("a",true,"href="+PassChangeForm.HREF+"?id="+id).text("Try again").end();
+						} else {
+							hgen.incr("a",true,"href="+Home.HREF).text("Home").end(); 
+						}
+					}
+				});
+			}
+		});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoForm.java
new file mode 100644
index 0000000..5cb8ff2
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoForm.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.A;
+import static com.att.xgen.html.HTMLGen.TABLE;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Nss;
+import aaf.v2_0.Nss.Ns;
+import aaf.v2_0.Nss.Ns.Attrib;
+
+public class NsInfoForm extends Page {
+	// Package on purpose
+	static final String HREF = "/gui/onboard";
+	static final String NAME = "Onboarding";
+	static final String fields[] = {"ns","description","mots","owners","admins"};
+	
+	public NsInfoForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+
+			private final Slot sID = gui.env.slot(NsInfoForm.NAME+'.'+NsInfoForm.fields[0]);
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				// p tags not closing right using .p() - causes issues in IE8 password form - so using leaf for the moment
+				hgen.leaf(HTMLGen.H2).text("Namespace Info").end()
+				     .leaf("p").text("Hover over Fields for Tool Tips, or click ")
+				     	.leaf(A,"href="+gui.env.getProperty("aaf_url.gui_onboard","")).text("Here").end()
+				     	.text(" for more information")
+				     .end()
+					.incr("form","method=post");
+				Mark table = new Mark(TABLE);
+				hgen.incr(table);
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@SuppressWarnings("unchecked")
+					@Override
+					public void code(final AuthGUI gui, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+						final String incomingID= trans.get(sID, "");
+						final String[] info = new String[fields.length];
+						final Object own_adm[] = new Object[2]; 
+						for(int i=0;i<info.length;++i) {
+							info[i]="";
+						}
+						if(incomingID.length()>0) {
+							TimeTaken tt = trans.start("AAF Namespace Info",Env.REMOTE);
+							try {
+								gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+									@Override
+									public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+										Future<Nss> fn = client.read("/authz/nss/"+incomingID,gui.nssDF);
+										if(fn.get(AuthGUI.TIMEOUT)) {
+											for(Ns ns : fn.value.getNs()) {
+												info[0]=ns.getName();
+												info[1]=ns.getDescription();
+												for(Attrib attr: ns.getAttrib()) {
+													switch(attr.getKey()) {
+														case "mots":
+															info[2]=attr.getValue();
+														default:
+													}
+												}
+												own_adm[0]=ns.getResponsible();
+												own_adm[1]=ns.getAdmin();
+											}
+										} else {
+											trans.error().log(fn.body());
+										}
+										return null;
+									}
+								});
+							} catch (Exception e) {
+								trans.error().log("Unable to access AAF for NS Info",incomingID);
+								e.printStackTrace();
+							} finally {
+								tt.done();
+							}
+						}
+						hgen.input(fields[0],"Namespace",false,"value="+info[0],"title=AAF Namespace")
+							.input(fields[1],"Description*",true,"value="+info[1],"title=Full Application Name, Tool Name or Group")
+							.input(fields[2],"MOTS ID",false,"value="+info[2],"title=MOTS ID if this is an Application, and has MOTS");
+						Mark endTD = new Mark(),endTR=new Mark();
+						// Owners
+						hgen.incr(endTR,HTMLGen.TR)
+								.incr(endTD,HTMLGen.TD)
+									.leaf("label","for="+fields[3]).text("Responsible Party")
+								.end(endTD)
+								.incr(endTD,HTMLGen.TD)
+									.tagOnly("input","id="+fields[3],"title=Owner of App, must be an Non-Bargained Employee");
+									if(own_adm[0]!=null) {
+										for(String s : (List<String>)own_adm[0]) {
+											hgen.incr("label",true).text(s).end();
+										}
+									}
+							hgen.end(endTR);
+
+							// Admins
+							hgen.incr(endTR,HTMLGen.TR)
+								.incr(endTD,HTMLGen.TD)
+									.leaf("label","for="+fields[4]).text("Administrators")
+								.end(endTD)
+								.incr(endTD,HTMLGen.TD)
+									.tagOnly("input","id="+fields[4],"title=Admins may be employees, contractors or mechIDs");
+									if(own_adm[1]!=null) {
+										for(String s : (List<String>)own_adm[1]) {
+											hgen.incr(HTMLGen.P,true).text(s).end();
+										}
+									}
+								hgen.end(endTR)
+						.end();
+					}
+				});
+				hgen.end();
+				hgen.tagOnly("input", "type=submit", "value=Submit")
+					.end();
+
+			}
+		});
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NssShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NssShow.java
new file mode 100644
index 0000000..3ca12d9
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NssShow.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Nss;
+import aaf.v2_0.Nss.Ns;
+
+public class NssShow extends Page {
+	public static final String HREF = "/gui/mynamespaces";
+
+	public NssShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, "MyNamespaces",HREF, NO_FIELDS,
+				new BreadCrumbs(breadcrumbs), 
+				new Table<AuthGUI,AuthzTrans>("Namespaces I administer",gui.env.newTransNoAvg(),new Model("admin",gui.env), 
+						"class=std", "style=display: inline-block; width: 45%; margin: 10px;"),
+				new Table<AuthGUI,AuthzTrans>("Namespaces I own",gui.env.newTransNoAvg(),new Model("responsible",gui.env),
+						"class=std", "style=display: inline-block; width: 45%; margin: 10px;"));
+	}
+	
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private String[] headers;
+		private String privilege = null;
+		public final Slot sNssByUser;
+		private boolean isAdmin;
+
+		public Model(String privilege,AuthzEnv env) {
+			super();
+			headers = new String[] {privilege};
+			this.privilege = privilege;
+			isAdmin = "admin".equals(privilege);
+			sNssByUser = env.slot("NSS_SHOW_MODEL_DATA");
+		}
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			List<Ns> nss = trans.get(sNssByUser, null);
+			if(nss==null) {
+				TimeTaken tt = trans.start("AAF Nss by User for " + privilege,Env.REMOTE);
+				try {
+					nss = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<List<Ns>>() {
+						@Override
+						public List<Ns> code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+							List<Ns> nss = null;
+							Future<Nss> fp = client.read("/authz/nss/either/" + trans.user(),gui.nssDF);
+							if(fp.get(AuthGUI.TIMEOUT)) {
+								TimeTaken tt = trans.start("Load Data for " + privilege, Env.SUB);
+								try {
+									if(fp.value!=null) {
+										nss = fp.value.getNs();
+										Collections.sort(nss, new Comparator<Ns>() {
+											public int compare(Ns ns1, Ns ns2) {
+												return ns1.getName().compareToIgnoreCase(ns2.getName());
+											}
+										});
+										trans.put(sNssByUser,nss);
+									} 
+								} finally {
+									tt.done();
+								}
+							}else {
+								gui.writeError(trans, fp, null);
+							}
+							return nss;
+						}
+					});
+				} catch (Exception e) {
+					trans.error().log(e);
+				} finally {
+					tt.done();
+				}
+			}
+			
+			if(nss!=null) {
+				for(Ns n : nss) {
+					if((isAdmin && !n.getAdmin().isEmpty())
+					  || (!isAdmin && !n.getResponsible().isEmpty())) {
+						AbsCell[] sa = new AbsCell[] {
+							new RefCell(n.getName(),NsDetail.HREF
+									+"?name="+n.getName()),
+						};
+						rv.add(sa);
+					}
+				}
+			}
+
+			return new Cells(rv,null);
+		}
+	}
+	
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeAction.java
new file mode 100644
index 0000000..1c57515
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeAction.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.ParseException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.CredRequest;
+
+public class PassChangeAction extends Page {
+	public PassChangeAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,"PassChange",PassChangeForm.HREF, PassChangeForm.fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+				final Slot sID = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[0]);
+				final Slot sCurrPass = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[1]);
+				final Slot sPassword = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[2]);
+				final Slot sPassword2 = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[3]);
+				final Slot startDate = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[4]);
+				
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(final AuthGUI gui, final AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+							String id = trans.get(sID,null);
+							String currPass = trans.get(sCurrPass,null);
+							String password = trans.get(sPassword,null);
+							String password2 = trans.get(sPassword2,null);
+							
+							// Run Validations
+							boolean fail = true;
+							
+							if (id==null || id.indexOf('@')<=0) {
+								hgen.p("Data Entry Failure: Please enter a valid ID, including domain.");
+							} else if(password == null || password2 == null || currPass == null) {
+								hgen.p("Data Entry Failure: Both Password Fields need entries.");
+							} else if(!password.equals(password2)) {
+								hgen.p("Data Entry Failure: Passwords do not match.");
+							} else { // everything else is checked by Server
+								final CredRequest cred = new CredRequest();
+								cred.setId(id);
+								cred.setPassword(currPass);
+								try {
+									fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Boolean>() {
+										@Override
+										public Boolean code(Rcli<?> client)throws CadiException, ConnectException, APIException {
+											boolean fail = true;
+											boolean go = false;
+											TimeTaken tt = trans.start("Check Current Password",Env.REMOTE);
+											try {
+												Future<CredRequest> fcr = client.create( // Note: Need "Post", because of hiding password in SSL Data
+															"/authn/validate",gui.credReqDF,cred);
+												
+												fcr.get(5000);
+												if(fcr.code() == 200) {
+													hgen.p("Current Password validated");
+													go = true;
+												} else {
+													hgen.p(String.format("Invalid Current Password: %d %s",fcr.code(),fcr.body()));
+													go = false;
+												}
+											} finally {
+												tt.done();
+											}
+											if(go) {
+												tt = trans.start("AAF Change Password",Env.REMOTE);
+												try {
+													// Change over Cred to reset mode
+													cred.setPassword(password);
+													String start = trans.get(startDate, null);
+													if(start!=null) {
+														try {
+															cred.setStart(Chrono.timeStamp(Chrono.dateOnlyFmt.parse(start)));
+														} catch (ParseException e) {
+															throw new CadiException(e);
+														}
+													}
+													
+													Future<CredRequest> fcr = client.create(
+															"/authn/cred",
+															gui.credReqDF,
+															cred
+															);
+		
+													if(fcr.get(5000)) {
+														// Do Remote Call
+														hgen.p("New Password has been added.");
+														fail = false;
+													} else {
+														gui.writeError(trans, fcr, hgen);
+													}
+												} finally {
+													tt.done();
+												}
+											} 
+											return fail;
+										}
+										
+									});
+							} catch (Exception e) {
+								hgen.p("Unknown Error");
+								e.printStackTrace();
+							}
+								
+						}
+						hgen.br();
+						if(fail) {
+							hgen.incr("a",true,"href="+PassChangeForm.HREF+"?id="+id).text("Try again").end();
+						} else {
+							hgen.incr("a",true,"href="+Home.HREF).text("Home").end(); 
+						}
+					}
+				});
+			}
+		});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeForm.java
new file mode 100644
index 0000000..440c0db
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeForm.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.TABLE;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Slot;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class PassChangeForm extends Page {
+	// Package on purpose
+	static final String HREF = "/gui/passwd";
+	static final String NAME = "PassChange";
+	static final String fields[] = {"id","current","password","password2","startDate"};
+	
+	public PassChangeForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+			private final Slot sID = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[0]);
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				// p tags not closing right using .p() - causes issues in IE8 password form - so using leaf for the moment
+				hgen.leaf("p").text("You are requesting a new Mechanical Password in the AAF System.  " +
+				     "So that you can perform clean migrations, you will be able to use both this " +
+				     "new password and the old one until their respective expiration dates.").end()
+				     .leaf("p").text("Note: You must be a Namespace Admin where the MechID resides.").end()
+					.incr("form","method=post");
+				Mark table = new Mark(TABLE);
+				hgen.incr(table);
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+//						GregorianCalendar gc = new GregorianCalendar();
+//						System.out.println(gc.toString());
+						String incomingID= trans.get(sID, "");
+						hgen
+						.input(fields[0],"ID*",true,"value="+incomingID)
+						.input(fields[1],"Current Password*",true,"type=password")
+						.input(fields[2],"New Password*",true, "type=password")
+						.input(fields[3], "Reenter New Password*",true, "type=password")
+//						.input(fields[3],"Start Date",false,"type=date", "value="+
+//								Chrono.dateOnlyFmt.format(new Date(System.currentTimeMillis()))
+//								)
+						.end();
+					}
+				});
+				hgen.end();
+				hgen.tagOnly("input", "type=submit", "value=Submit")
+				.end();
+
+			}
+		});
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PendingRequestsShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PendingRequestsShow.java
new file mode 100644
index 0000000..8bdb329
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PendingRequestsShow.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.UUID;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Approval;
+import aaf.v2_0.Approvals;
+
+public class PendingRequestsShow extends Page {
+	public static final String HREF = "/gui/myrequests";
+	public static final String NAME = "MyRequests";
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	private static final String DATE_TIME_FORMAT = "yyyy-MM-dd";
+	
+	public PendingRequestsShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME,HREF, NO_FIELDS,
+			new BreadCrumbs(breadcrumbs), 
+			new NamedCode(true,"expedite") {
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+						hgen
+							.leaf("p", "class=expedite_request").text("These are your submitted Requests that are awaiting Approval. ")
+							.br()
+							.text("To Expedite a Request: ")
+							.leaf("a","href=#expedite_directions","onclick=divVisibility('expedite_directions');")
+								.text("Click Here").end()
+							.divID("expedite_directions", "style=display:none");
+						hgen
+							.incr(HTMLGen.OL)
+							.incr(HTMLGen.LI)
+							.leaf("a","href="+ApprovalForm.HREF+"?user="+trans.user(), "id=userApprove")
+							.text("Copy This Link")
+							.end()
+							.end()
+							.incr(HTMLGen.LI)
+							.text("Send it to the Approver Listed")
+							.end()
+							.end()
+							.text("NOTE: Using this link, the Approver will only see your requests. You only need to send this link once!")
+							.end()
+							.end();
+					}
+				});
+			}
+		},
+			new Table<AuthGUI,AuthzTrans>("Pending Requests",gui.env.newTransNoAvg(),new Model(), "class=std")
+		);
+					
+
+	}
+
+	/**
+	 * Implement the Table Content for Requests by User
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;
+		private static final String[] headers = new String[] {"Request Date","Status","Memo","Approver"};
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			DateFormat createdDF = new SimpleDateFormat(DATE_TIME_FORMAT);
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client)throws CadiException, ConnectException, APIException {
+						TimeTaken tt = trans.start("AAF Get Approvals by User",Env.REMOTE);
+						try {
+							Future<Approvals> fa = client.read("/authz/approval/user/"+trans.user(),gui.approvalsDF);
+							if(fa.get(5000)) {
+								tt.done();
+								tt = trans.start("Load Data", Env.SUB);
+								if(fa.value!=null) {
+									List<Approval> approvals = fa.value.getApprovals();
+									Collections.sort(approvals, new Comparator<Approval>() {
+										@Override
+										public int compare(Approval a1, Approval a2) {
+											UUID id1 = UUID.fromString(a1.getId());
+											UUID id2 = UUID.fromString(a2.getId());
+											return id1.timestamp()<=id2.timestamp()?1:-1;
+										}
+									});
+									
+									String prevTicket = null;
+									for(Approval a : approvals) {
+										String approver = a.getApprover();
+										String approverShort = approver.substring(0,approver.indexOf('@'));
+										
+										AbsCell tsCell = null;
+										String ticket = a.getTicket();
+										if (ticket.equals(prevTicket)) {
+											tsCell = AbsCell.Null;
+										} else {
+											UUID id = UUID.fromString(a.getId());
+											tsCell = new RefCell(createdDF.format((id.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH)/10000),
+													RequestDetail.HREF + "?ticket=" + a.getTicket());
+											prevTicket = ticket;
+										}
+										
+										AbsCell approverCell = null;
+										if (approver.endsWith(CSP_ATT_COM)) {
+											approverCell = new RefCell(approver, WEBPHONE + approverShort);
+										} else {
+											approverCell = new TextCell(approver);
+										}
+										AbsCell[] sa = new AbsCell[] {
+											tsCell,
+											new TextCell(a.getStatus()),
+											new TextCell(a.getMemo()),
+											approverCell
+										};
+										rv.add(sa);
+									}
+								}
+							} else {
+								gui.writeError(trans, fa, null);
+							}
+						} finally {
+							tt.done();
+						}
+
+
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				trans.error().log(e);
+			}
+			return new Cells(rv,null);
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermDetail.java
new file mode 100644
index 0000000..ad26674
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermDetail.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.aft.dme2.internal.jetty.http.HttpStatus;
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Perm;
+import aaf.v2_0.Perms;
+
+/**
+ * Detail Page for Permissions
+ *
+ */
+public class PermDetail extends Page {
+	public static final String HREF = "/gui/permdetail";
+	public static final String NAME = "PermDetail";
+	private static final String BLANK = "";
+
+	public PermDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME, HREF, new String[] {"type","instance","action"},
+				new BreadCrumbs(breadcrumbs),
+				new Table<AuthGUI,AuthzTrans>("Permission Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+				);
+	}
+
+	/**
+	 * Implement the table content for Permissions Detail
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[0];
+		private Slot type, instance, action;
+		public Model(AuthzEnv env) {
+			type = env.slot(NAME+".type");
+			instance = env.slot(NAME+".instance");
+			action = env.slot(NAME+".action");
+		}
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String pType = trans.get(type, null);
+			final String pInstance = trans.get(instance, null);
+			final String pAction = trans.get(action, null);
+			if(pType==null || pInstance==null || pAction==null) {
+				return Cells.EMPTY;
+			}
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			rv.add(new AbsCell[]{new TextCell("Type:"),new TextCell(pType)});
+			rv.add(new AbsCell[]{new TextCell("Instance:"),new TextCell(pInstance)});
+			rv.add(new AbsCell[]{new TextCell("Action:"),new TextCell(pAction)});
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client)throws CadiException, ConnectException, APIException {
+						TimeTaken tt = trans.start("AAF Perm Details",Env.REMOTE);
+						try {
+							Future<Perms> fp= client.read("/authz/perms/"+pType + '/' + pInstance + '/' + pAction,gui.permsDF);
+					
+							if(fp.get(AuthGUI.TIMEOUT)) {
+								tt.done();
+								tt = trans.start("Load Data", Env.SUB);
+								List<Perm> ps = fp.value.getPerm();
+								if(!ps.isEmpty()) {
+									Perm perm = fp.value.getPerm().get(0);
+									String desc = (perm.getDescription()!=null?perm.getDescription():BLANK);
+									rv.add(new AbsCell[]{new TextCell("Description:"),new TextCell(desc)});
+									boolean first=true;
+									for(String r : perm.getRoles()) {
+										if(first){
+											first=false;
+											rv.add(new AbsCell[] {
+													new TextCell("Associated Roles:"),
+													new TextCell(r)
+												});
+										} else {
+											rv.add(new AbsCell[] {
+												AbsCell.Null,
+												new TextCell(r)
+											});
+										}
+									}
+								}
+								String historyLink = PermHistory.HREF 
+										+ "?type=" + pType + "&instance=" + pInstance + "&action=" + pAction;
+								
+								rv.add(new AbsCell[] {new RefCell("See History",historyLink)});
+							} else {
+								rv.add(new AbsCell[] {new TextCell(
+									fp.code()==HttpStatus.NOT_FOUND_404?
+										"*** Implicit Permission ***":
+										"*** Data Unavailable ***"
+										)});
+							}
+						} finally {
+							tt.done();
+						}
+
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			return new Cells(rv,null);
+		}
+	}
+}		
+		
\ No newline at end of file
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantAction.java
new file mode 100644
index 0000000..3fa6508
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantAction.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Pkey;
+import aaf.v2_0.RolePermRequest;
+
+public class PermGrantAction extends Page {
+	
+	
+	public PermGrantAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,PermGrantForm.NAME, PermGrantForm.HREF, PermGrantForm.fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+				final Slot sType = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[0]);
+				final Slot sInstance = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[1]);
+				final Slot sAction = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[2]);
+				final Slot sRole = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[3]);
+				
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(final AuthGUI gui, final AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+
+							String type = trans.get(sType,null);
+							String instance = trans.get(sInstance,null);
+							String action = trans.get(sAction,null);
+							String role = trans.get(sRole,null);
+							
+							String lastPage = PermGrantForm.HREF 
+									+ "?type=" + type + "&instance=" + instance + "&action=" + action;
+							
+							// Run Validations
+							boolean fail = true;
+						
+							TimeTaken tt = trans.start("AAF Grant Permission to Role",Env.REMOTE);
+							try {
+								
+								final RolePermRequest grantReq = new RolePermRequest();
+								Pkey pkey = new Pkey();
+								pkey.setType(type);
+								pkey.setInstance(instance);
+								pkey.setAction(action);
+								grantReq.setPerm(pkey);
+								grantReq.setRole(role);
+								
+								fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Boolean>() {
+									@Override
+									public Boolean code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+										boolean fail = true;
+										Future<RolePermRequest> fgrant = client.create(
+												"/authz/role/perm",
+												gui.rolePermReqDF,
+												grantReq
+												);
+
+										if(fgrant.get(5000)) {
+											hgen.p("Permission has been granted to role.");
+											fail = false;
+										} else {
+											if (202==fgrant.code()) {
+												hgen.p("Permission Grant Request sent, but must be Approved before actualizing");
+												fail = false;
+											} else {
+												gui.writeError(trans, fgrant, hgen);
+											}
+										}
+										return fail;
+									}
+								});
+							} catch (Exception e) {
+								hgen.p("Unknown Error");
+								e.printStackTrace();
+							} finally {
+								tt.done();
+							}
+								
+							hgen.br();
+							hgen.incr("a",true,"href="+lastPage);
+							if (fail) {
+								hgen.text("Try again");
+							} else {
+								hgen.text("Grant this Permission to Another Role");
+							}
+							hgen.end();
+							hgen.js()
+								.text("alterLink('permgrant', '"+lastPage + "');")							
+								.done();
+
+						}
+					});
+				}
+			});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantForm.java
new file mode 100644
index 0000000..b3b51f6
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantForm.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.TABLE;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Role;
+import aaf.v2_0.Roles;
+
+public class PermGrantForm extends Page {
+	static final String HREF = "/gui/permgrant";
+	static final String NAME = "Permission Grant";
+	static final String fields[] = {"type","instance","action","role"};
+	
+	public PermGrantForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				final Slot type = gui.env.slot(NAME+".type");
+				final Slot instance = gui.env.slot(NAME+".instance");
+				final Slot action = gui.env.slot(NAME+".action");
+				final Slot role = gui.env.slot(NAME+".role");
+				// p tags not closing right using .p() - causes issues in IE8 password form - so using leaf for the moment
+				hgen.leaf("p").text("Choose a role to grant to this permission").end()
+					.incr("form","method=post");
+				Mark table = new Mark(TABLE);
+				hgen.incr(table);
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+						
+						Mark copyRoleJS = new Mark();
+						hgen.js(copyRoleJS);
+						hgen.text("function copyRole(role) {");
+						hgen.text("var txtRole = document.querySelector(\"#role\");");
+//						hgen.text("if (role==;");
+						hgen.text("txtRole.value=role;");
+						hgen.text("}");
+						hgen.end(copyRoleJS);
+						
+						String typeValue = trans.get(type, "");
+						String instanceValue = trans.get(instance, "");
+						String actionValue = trans.get(action, "");
+						String roleValue = trans.get(role,null);
+						List<String> myRoles = getMyRoles(gui, trans);
+						hgen
+						.input(fields[0],"Perm Type",true,"value="+typeValue,"disabled")
+						.input(fields[1],"Perm Instance",true,"value="+instanceValue,"disabled")
+						.input(fields[2],"Perm Action",true,"value="+actionValue,"disabled");
+						
+						// select & options are not an input type, so we must create table row & cell tags
+						Mark selectRow = new Mark();
+						hgen
+						.incr(selectRow, "tr")
+						.incr("td")
+						.incr("label", "for=myroles", "required").text("My Roles").end()
+						.end()
+						.incr("td")
+						.incr("select", "name=myroles", "id=myroles", "onchange=copyRole(this.value)")
+						.incr("option", "value=").text("Select one of my roles").end();
+						for (String role : myRoles) {
+							hgen.incr("option", "value="+role).text(role).end();
+						}
+						hgen
+						.incr("option", "value=").text("Other").end()					
+						.end(selectRow);
+						if(roleValue==null) {
+							hgen.input(fields[3],"Role", true, "placeholder=or type a role here");
+						} else {
+							hgen.input(fields[3],"Role",true, "value="+roleValue);
+						}
+						hgen.end();
+					}
+				});
+				hgen.end();
+				hgen.tagOnly("input", "type=submit", "value=Submit")
+				.end();
+
+			}
+		});
+	}
+		
+	private static List<String> getMyRoles(final AuthGUI gui, final AuthzTrans trans) {
+		List<String> myRoles = new ArrayList<String>();
+		try {
+			gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+				@Override
+				public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+					TimeTaken tt = trans.start("AAF get my roles",Env.REMOTE);
+					try {
+						Future<Roles> fr = client.read("/authz/roles/user/"+trans.user(),gui.rolesDF);
+						if(fr.get(5000)) {
+							tt.done();
+							tt = trans.start("Load Data", Env.SUB);
+							if (fr.value != null) for (Role r : fr.value.getRole()) {
+								myRoles.add(r.getName());
+							}
+						} else {
+							gui.writeError(trans, fr, null);
+						}
+					} finally {
+						tt.done();
+					}
+					return null;
+				}
+			});
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		return myRoles;
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermHistory.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermHistory.java
new file mode 100644
index 0000000..f360b0d
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermHistory.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.History;
+import aaf.v2_0.History.Item;
+
+
+public class PermHistory extends Page {
+	static final String NAME="PermHistory";
+	static final String HREF = "/gui/permHistory";
+	static final String FIELDS[] = {"type","instance","action","dates"};
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, 
+		AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
+	
+	public PermHistory(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, FIELDS,
+			new BreadCrumbs(breadcrumbs),
+			new Table<AuthGUI,AuthzTrans>("History", gui.env.newTransNoAvg(),new Model(gui.env()),"class=std"),
+			new NamedCode(true, "content") {
+				@Override
+				public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+					final Slot sType = gui.env.slot(NAME+".type");
+					final Slot sInstance = gui.env.slot(NAME+".instance");
+					final Slot sAction = gui.env.slot(NAME+".action");
+					cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+							String type = trans.get(sType, null);
+							String instance = trans.get(sInstance,null);
+							String action = trans.get(sAction,null);
+							
+							// Use Javascript to make the table title more descriptive
+							hgen.js()
+							.text("var caption = document.querySelector(\".title\");")
+							.text("caption.innerHTML='History for Permission [ " + type + " ]';")						
+							.done();
+							
+							// Use Javascript to change Link Target to our last visited Detail page
+							String lastPage = PermDetail.HREF + "?type=" + type
+									+ "&instance=" + instance
+									+ "&action=" + action;
+							hgen.js()
+								.text("alterLink('permdetail', '"+lastPage + "');")							
+								.done();
+							
+							hgen.br();
+							hgen.leaf("a", "href=#advanced_search", "onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+								.divID("advanced_search", "style=display:none");
+							hgen.incr("table");
+								
+							addDateRow(hgen,"Start Date");
+							addDateRow(hgen,"End Date");
+							hgen.incr("tr").incr("td");
+							hgen.tagOnly("input", "type=button","value=Get History",
+									"onclick=datesURL('"+HREF+"?type=" + type
+									+ "&instance=" + instance
+									+ "&action=" + action+"');");
+							hgen.end().end();
+							hgen.end();
+							hgen.end();
+						}
+					});
+				}
+			}
+
+			);
+		
+	}
+	
+	private static void addDateRow(HTMLGen hgen, String s) {
+		hgen
+			.incr("tr")
+			.incr("td")
+			.incr("label", "for=month", "required").text(s+"*").end()
+			.end()
+			.incr("td")
+			.incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
+			.incr("option", "value=").text("Month").end();
+		for (Month m : Month.values()) {
+			if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
+				hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
+			} else {
+				hgen.incr("option", "value="+(m.ordinal()+1)).text(m.name()).end();
+			}
+		}
+		hgen.end()
+			.end()
+			.incr("td")
+			.tagOnly("input","type=number","id=year"+s.substring(0, s.indexOf(' ')),"required",
+					"value="+Calendar.getInstance().get(Calendar.YEAR), "min=1900", 
+					"max="+Calendar.getInstance().get(Calendar.YEAR),
+					"placeholder=Year").end()
+			.end();
+	}
+	
+	/**
+	 * Implement the Table Content for History
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		private static final String[] headers = new String[] {"Date","User","Memo"};
+		private Slot sType;
+		private Slot sDates;
+		
+		public Model(AuthzEnv env) {
+			sType = env.slot(NAME+".type");
+			sDates = env.slot(NAME+".dates");
+		}
+		
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String oName = trans.get(sType,null);
+			final String oDates = trans.get(sDates,null);
+			
+			if(oName==null) {
+				return Cells.EMPTY;
+			}
+			
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			String msg = null;
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						TimeTaken tt = trans.start("AAF Get History for Permission ["+oName+"]",Env.REMOTE);
+						try {
+							if (oDates != null) {
+								client.setQueryParams("yyyymm="+oDates);
+							}
+							Future<History> fh = client.read(
+								"/authz/hist/perm/"+oName,
+								gui.historyDF
+								);
+							
+							
+							if (fh.get(AuthGUI.TIMEOUT)) {
+								tt.done();
+								tt = trans.start("Load History Data", Env.SUB);
+								List<Item> histItems = fh.value.getItem();
+								
+								java.util.Collections.sort(histItems, new Comparator<Item>() {
+									@Override
+									public int compare(Item o1, Item o2) {
+										return o2.getTimestamp().compare(o1.getTimestamp());
+									}
+								});
+								
+								for (Item i : histItems) {
+									String user = i.getUser();
+									AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+											new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+									
+									rv.add(new AbsCell[] {
+											new TextCell(i.getTimestamp().toGregorianCalendar().getTime().toString()),
+											userCell,
+											new TextCell(i.getMemo())
+									});
+								}
+								
+							} else {
+								if (fh.code()==403) {
+									rv.add(new AbsCell[] {new TextCell("You may not view History of Permission [" + oName + "]", "colspan = 3", "class=center")});
+								} else {
+									rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***", "colspan = 3", "class=center")});
+								}
+							}
+						} finally {
+							tt.done();
+						}
+
+						return null;
+					}
+				});
+				
+			} catch (Exception e) {
+				trans.error().log(e);
+			}
+		return new Cells(rv,msg);
+		}
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermsShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermsShow.java
new file mode 100644
index 0000000..1bd3301
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermsShow.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Perm;
+import aaf.v2_0.Perms;
+
+/**
+ * Page content for My Permissions
+ * 
+ *
+ */
+public class PermsShow extends Page {
+	public static final String HREF = "/gui/myperms";
+	
+	public PermsShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, "MyPerms",HREF, NO_FIELDS,
+			new BreadCrumbs(breadcrumbs), 
+			new Table<AuthGUI,AuthzTrans>("Permissions",gui.env.newTransNoAvg(),new Model(), "class=std"));
+	}
+
+	/**
+	 * Implement the Table Content for Permissions by User
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[] {"Type","Instance","Action"};
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			TimeTaken tt = trans.start("AAF Perms by User",Env.REMOTE);
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						Future<Perms> fp = client.read("/authz/perms/user/"+trans.user(), gui.permsDF);
+						if(fp.get(5000)) {
+							TimeTaken ttld = trans.start("Load Data", Env.SUB);
+							try {
+								if(fp.value!=null) {	
+									for(Perm p : fp.value.getPerm()) {
+										AbsCell[] sa = new AbsCell[] {
+											new RefCell(p.getType(),PermDetail.HREF
+													+"?type="+p.getType()
+													+"&amp;instance="+p.getInstance()
+													+"&amp;action="+p.getAction()),
+											new TextCell(p.getInstance()),
+											new TextCell(p.getAction())
+										};
+										rv.add(sa);
+									}
+								} else {
+									gui.writeError(trans, fp, null);
+								}
+							} finally {
+								ttld.done();
+							}
+						}
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				trans.error().log(e);
+			} finally {
+				tt.done();
+			}
+			return new Cells(rv,null);
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RequestDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RequestDetail.java
new file mode 100644
index 0000000..43c2132
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RequestDetail.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.UUID;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Approval;
+import aaf.v2_0.Approvals;
+
+public class RequestDetail extends Page {
+	public static final String HREF = "/gui/requestdetail";
+	public static final String NAME = "RequestDetail";
+	private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+	public static final String[] FIELDS = {"ticket"};
+
+	public RequestDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME, HREF, FIELDS,
+				new BreadCrumbs(breadcrumbs),
+				new Table<AuthGUI,AuthzTrans>("Request Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+				);
+	}
+
+	/**
+	 * Implement the table content for Request Detail
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;
+		private static final String[] headers = new String[0];
+		private Slot sTicket;
+		public Model(AuthzEnv env) {
+			sTicket = env.slot(NAME+".ticket");
+		}
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			Cells rv=Cells.EMPTY;
+			final String ticket = trans.get(sTicket, null);
+			if(ticket!=null) {
+				try {
+					rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Cells>() {
+						@Override
+						public Cells code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+							TimeTaken tt = trans.start("AAF Approval Details",Env.REMOTE);
+							ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+							try {
+								Future<Approvals> fa = client.read(
+									"/authz/approval/ticket/"+ticket, 
+									gui.approvalsDF
+									);
+								
+								if(fa.get(AuthGUI.TIMEOUT)) {
+									if (!trans.user().equals(fa.value.getApprovals().get(0).getUser())) {
+										return Cells.EMPTY;
+									}
+									tt.done();
+									tt = trans.start("Load Data", Env.SUB);
+									boolean first = true;
+									for ( Approval approval : fa.value.getApprovals()) {
+										AbsCell[] approverLine = new AbsCell[4];
+										// only print common elements once
+										if (first) {
+											DateFormat createdDF = new SimpleDateFormat(DATE_TIME_FORMAT);
+											UUID id = UUID.fromString(approval.getId());
+											
+											rv.add(new AbsCell[]{new TextCell("Ticket ID:"),new TextCell(approval.getTicket(),"colspan=3")});
+											rv.add(new AbsCell[]{new TextCell("Memo:"),new TextCell(approval.getMemo(),"colspan=3")});
+											rv.add(new AbsCell[]{new TextCell("Requested On:"), 
+													new TextCell(createdDF.format((id.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH)/10000),"colspan=3")
+											});
+											rv.add(new AbsCell[]{new TextCell("Operation:"),new TextCell(decodeOp(approval.getOperation()),"colspan=3")});
+											String user = approval.getUser();
+											if (user.endsWith(CSP_ATT_COM)) {
+												rv.add(new AbsCell[]{new TextCell("User:"),
+														new RefCell(user,WEBPHONE + user.substring(0, user.indexOf("@")),"colspan=3")});
+											} else {
+												rv.add(new AbsCell[]{new TextCell("User:"),new TextCell(user,"colspan=3")});
+											}
+											
+											// headers for listing each approver
+											rv.add(new AbsCell[]{new TextCell(" ","colspan=4","class=blank_line")});
+											rv.add(new AbsCell[]{AbsCell.Null,
+													new TextCell("Approver","class=bold"), 
+													new TextCell("Type","class=bold"), 
+													new TextCell("Status","class=bold")});
+											approverLine[0] = new TextCell("Approvals:");
+											
+											first = false;
+										} else {
+										    approverLine[0] = AbsCell.Null;
+										}
+										
+										String approver = approval.getApprover();
+										String approverShort = approver.substring(0,approver.indexOf('@'));
+										
+										if (approver.endsWith(CSP_ATT_COM)) {
+											approverLine[1] = new RefCell(approver, WEBPHONE + approverShort);
+										} else {
+											approverLine[1] = new TextCell(approval.getApprover());
+										}
+										
+										String type = approval.getType();
+										if ("owner".equalsIgnoreCase(type)) {
+											type = "resource owner";
+										}
+										
+										approverLine[2] = new TextCell(type);
+										approverLine[3] = new TextCell(approval.getStatus());
+										rv.add(approverLine);
+									
+									}
+								} else {
+									rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
+								}
+							} finally {
+								tt.done();
+							}
+							return new Cells(rv,null);
+						}
+					});
+				} catch (Exception e) {
+					trans.error().log(e);
+				}
+			}
+			return rv;
+		}
+
+		private String decodeOp(String operation) {
+			if ("C".equalsIgnoreCase(operation)) {
+				return "Create";
+			} else if ("D".equalsIgnoreCase(operation)) {
+				return "Delete";
+			} else if ("U".equalsIgnoreCase(operation)) {
+				return "Update";
+			} else if ("G".equalsIgnoreCase(operation)) {
+				return "Grant";
+			} else if ("UG".equalsIgnoreCase(operation)) {
+				return "Un-Grant";
+			}
+			return operation;
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RoleDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleDetail.java
new file mode 100644
index 0000000..d45813e
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleDetail.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Pkey;
+import aaf.v2_0.Role;
+import aaf.v2_0.Roles;
+
+/**
+ * Detail Page for Permissions
+ * 
+ *
+ */
+public class RoleDetail extends Page {
+	public static final String HREF = "/gui/roledetail";
+	public static final String NAME = "RoleDetail";
+	private static final String BLANK = "";
+
+	public RoleDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME, HREF, new String[] {"role"},
+				new BreadCrumbs(breadcrumbs),
+				new Table<AuthGUI,AuthzTrans>("Role Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+				);
+	}
+
+	/**
+	 * Implement the table content for Permissions Detail
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[0];
+		private Slot role;
+		public Model(AuthzEnv env) {
+			role = env.slot(NAME+".role");
+		}
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String pRole = trans.get(role, null);
+			Cells rv = Cells.EMPTY;
+			if(pRole!=null) {
+				try { 
+					rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Cells>() {
+						@Override
+						public Cells code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+							ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+							rv.add(new AbsCell[]{new TextCell("Role:"),new TextCell(pRole)});
+							
+							TimeTaken tt = trans.start("AAF Role Details",Env.REMOTE);
+							try {
+								
+								Future<Roles> fr = client.read("/authz/roles/"+pRole,gui.rolesDF);
+								if(fr.get(AuthGUI.TIMEOUT)) {
+									tt.done();
+									tt = trans.start("Load Data", Env.SUB);
+									Role role = fr.value.getRole().get(0);
+									String desc = (role.getDescription()!=null?role.getDescription():BLANK);
+									rv.add(new AbsCell[]{new TextCell("Description:"),new TextCell(desc)});
+									boolean first=true;
+									for(Pkey r : role.getPerms()) {
+										if(first){
+											first=false;
+											rv.add(new AbsCell[] {
+													new TextCell("Associated Permissions:"),
+													new TextCell(r.getType() +
+															" | " + r.getInstance() +
+															" | " + r.getAction()
+															)
+												});
+										} else {
+											rv.add(new AbsCell[] {
+												AbsCell.Null,
+												new TextCell(r.getType() +
+														" | " + r.getInstance() +
+														" | " + r.getAction()
+														)
+											});
+										}
+									}
+									String historyLink = RoleHistory.HREF 
+											+ "?role=" + pRole;
+									rv.add(new AbsCell[] {new RefCell("See History",historyLink)});
+								} else {
+									rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
+								}
+							} finally {
+								tt.done();
+							}
+							return new Cells(rv,null);
+						}
+					});
+				} catch (Exception e) {
+					trans.error().log(e);
+				}
+			}
+			return rv;
+		}
+	}
+}		
+		
\ No newline at end of file
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RoleHistory.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleHistory.java
new file mode 100644
index 0000000..8531132
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleHistory.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.History;
+import aaf.v2_0.History.Item;
+
+
+public class RoleHistory extends Page {
+	static final String NAME="RoleHistory";
+	static final String HREF = "/gui/roleHistory";
+	static final String FIELDS[] = {"role","dates"};
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, 
+		AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
+	
+	public RoleHistory(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, FIELDS,
+			new BreadCrumbs(breadcrumbs),
+			new Table<AuthGUI,AuthzTrans>("History", gui.env.newTransNoAvg(),new Model(gui.env()),"class=std"),
+			new NamedCode(true, "content") {
+				@Override
+				public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+					final Slot role = gui.env.slot(NAME+".role");
+					cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+							String obRole = trans.get(role, null);
+							
+							// Use Javascript to make the table title more descriptive
+							hgen.js()
+							.text("var caption = document.querySelector(\".title\");")
+							.text("caption.innerHTML='History for Role [ " + obRole + " ]';")						
+							.done();
+							
+							// Use Javascript to change Link Target to our last visited Detail page
+							String lastPage = RoleDetail.HREF + "?role=" + obRole;
+							hgen.js()
+								.text("alterLink('roledetail', '"+lastPage + "');")							
+								.done();
+							
+							hgen.br();
+							hgen.leaf("a", "href=#advanced_search","onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+								.divID("advanced_search", "style=display:none");
+							hgen.incr("table");
+								
+							addDateRow(hgen,"Start Date");
+							addDateRow(hgen,"End Date");
+							hgen.incr("tr").incr("td");
+							hgen.tagOnly("input", "type=button","value=Get History",
+									"onclick=datesURL('"+HREF+"?role=" + obRole+"');");
+							hgen.end().end();
+							hgen.end();
+							hgen.end();
+						}
+					});
+				}
+			}
+
+			);
+		
+	}
+	
+	private static void addDateRow(HTMLGen hgen, String s) {
+		hgen
+			.incr("tr")
+			.incr("td")
+			.incr("label", "for=month", "required").text(s+"*").end()
+			.end()
+			.incr("td")
+			.incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
+			.incr("option", "value=").text("Month").end();
+		for (Month m : Month.values()) {
+			if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
+				hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
+			} else {
+				hgen.incr("option", "value="+(m.ordinal()+1)).text(m.name()).end();
+			}
+		}
+		hgen.end()
+			.end()
+			.incr("td")
+			.tagOnly("input","type=number","id=year"+s.substring(0, s.indexOf(' ')),"required",
+					"value="+Calendar.getInstance().get(Calendar.YEAR), "min=1900", 
+					"max="+Calendar.getInstance().get(Calendar.YEAR),
+					"placeholder=Year").end()
+			.end();
+	}
+	
+	
+	/**
+	 * Implement the Table Content for History
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		private static final String[] headers = new String[] {"Date","User","Memo"};
+		private Slot role;
+		private Slot dates;
+		
+		public Model(AuthzEnv env) {
+			role = env.slot(NAME+".role");
+			dates = env.slot(NAME+".dates");
+		}
+		
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String oName = trans.get(role,null);
+			final String oDates = trans.get(dates,null);
+			
+			Cells rv = Cells.EMPTY;
+			if(oName!=null) {
+				
+				try {
+					rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Cells>() {
+						@Override
+						public Cells code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+							ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+							TimeTaken tt = trans.start("AAF Get History for Namespace ["+oName+"]",Env.REMOTE);
+							String msg = null;
+							try {
+								if (oDates != null) {
+									client.setQueryParams("yyyymm="+oDates);
+								}
+								Future<History> fh = client.read("/authz/hist/role/"+oName,gui.historyDF);
+								if (fh.get(AuthGUI.TIMEOUT)) {
+									tt.done();
+									tt = trans.start("Load History Data", Env.SUB);
+									List<Item> histItems = fh.value.getItem();
+									
+									java.util.Collections.sort(histItems, new Comparator<Item>() {
+										@Override
+										public int compare(Item o1, Item o2) {
+											return o2.getTimestamp().compare(o1.getTimestamp());
+										}
+									});
+									
+									for (Item i : histItems) {
+										String user = i.getUser();
+										AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+												new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+										
+										rv.add(new AbsCell[] {
+												new TextCell(i.getTimestamp().toGregorianCalendar().getTime().toString()),
+												userCell,
+												new TextCell(i.getMemo())
+										});
+									}
+								} else {
+									if (fh.code()==403) {
+										rv.add(new AbsCell[] {new TextCell("You may not view History of Permission [" + oName + "]", "colspan = 3", "class=center")});
+									} else {
+										rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***", "colspan = 3", "class=center")});
+									}
+								}
+							} finally {
+								tt.done();
+							}	
+							return new Cells(rv,msg);
+						}
+					});
+				} catch (Exception e) {
+					trans.error().log(e);
+				}
+			}
+			return rv;
+		}
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RolesShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RolesShow.java
new file mode 100644
index 0000000..8b264df
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RolesShow.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+
+import aaf.v2_0.UserRole;
+import aaf.v2_0.UserRoles;
+
+
+/**
+ * Page content for My Roles
+ * 
+ *
+ */
+public class RolesShow extends Page {
+	public static final String HREF = "/gui/myroles";
+	private static final String DATE_TIME_FORMAT = "yyyy-MM-dd";
+	private static SimpleDateFormat expiresDF;
+	
+	static {
+		expiresDF = new SimpleDateFormat(DATE_TIME_FORMAT);
+	}
+	
+	public RolesShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, "MyRoles",HREF, NO_FIELDS,
+			new BreadCrumbs(breadcrumbs), 
+			new Table<AuthGUI,AuthzTrans>("Roles",gui.env.newTransNoAvg(),new Model(), "class=std"));
+	}
+
+	/**
+	 * Implement the Table Content for Permissions by User
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[] {"Role","Expires","Remediation","Actions"};
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			Cells rv = Cells.EMPTY;
+
+			try {
+				rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Cells>() {
+					@Override
+					public Cells code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+						TimeTaken tt = trans.start("AAF Roles by User",Env.REMOTE);
+						try {
+							Future<UserRoles> fur = client.read("/authz/userRoles/user/"+trans.user(),gui.userrolesDF);
+							if (fur.get(5000)) {
+								if(fur.value != null) for (UserRole u : fur.value.getUserRole()) {
+									if(u.getExpires().compare(Chrono.timeStamp()) < 0) {
+										AbsCell[] sa = new AbsCell[] {
+												new TextCell(u.getRole() + "*", "class=expired"),
+												new TextCell(expiresDF.format(u.getExpires().toGregorianCalendar().getTime()),"class=expired"),
+												new RefCell("Extend",
+														UserRoleExtend.HREF + "?user="+trans.user()+"&role="+u.getRole(), 
+														new String[]{"class=expired"}),
+												new RefCell("Remove",
+													UserRoleRemove.HREF + "?user="+trans.user()+"&role="+u.getRole(), 
+													new String[]{"class=expired"})
+														
+											};
+											rv.add(sa);
+									} else {
+										AbsCell[] sa = new AbsCell[] {
+												new RefCell(u.getRole(),
+														RoleDetail.HREF+"?role="+u.getRole()),
+												new TextCell(expiresDF.format(u.getExpires().toGregorianCalendar().getTime())),
+												AbsCell.Null,
+												new RefCell("Remove",
+														UserRoleRemove.HREF + "?user="+trans.user()+"&role="+u.getRole())
+											};
+											rv.add(sa);
+									}
+								}
+							}
+							
+						} finally {
+							tt.done();
+						}
+						return new Cells(rv,null);
+					}
+				});
+			} catch (Exception e) {
+				trans.error().log(e);
+			}
+			return rv;
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleExtend.java b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleExtend.java
new file mode 100644
index 0000000..e54787b
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleExtend.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+public class UserRoleExtend extends Page {
+	public static final String HREF = "/gui/urExtend";
+	static final String NAME = "Extend User Role";
+	static final String fields[] = {"user","role"};
+
+	public UserRoleExtend(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME, HREF, fields,
+				new BreadCrumbs(breadcrumbs),
+				new NamedCode(true, "content") {
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				final Slot sUser = gui.env.slot(NAME+".user");
+				final Slot sRole = gui.env.slot(NAME+".role");
+				
+				
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {						
+						final String user = trans.get(sUser, "");
+						final String role = trans.get(sRole, "");
+
+						TimeTaken tt = trans.start("Request to extend user role",Env.REMOTE);
+						try {
+							gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+								@Override
+								public Void code(Rcli<?> client)throws CadiException, ConnectException, APIException {
+									Future<Void> fv = client.setQueryParams("request=true").update("/authz/userRole/extend/"+user+"/"+role);
+									if(fv.get(5000)) {
+										// not sure if we'll ever hit this
+										hgen.p("Extended User ["+ user+"] in Role [" +role+"]");
+									} else {
+										if (fv.code() == 202 ) {
+											hgen.p("User ["+ user+"] in Role [" +role+"] Extension sent for Approval");
+										} else {
+											gui.writeError(trans, fv, hgen);
+										}
+									}
+									return null;
+								}
+							});
+						} catch (Exception e) {
+							trans.error().log(e);
+							e.printStackTrace();
+						} finally {
+							tt.done();
+						}
+						
+						
+					}
+				});
+			}
+			
+		});
+	}
+}
+
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleRemove.java b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleRemove.java
new file mode 100644
index 0000000..fd2123c
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleRemove.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+public class UserRoleRemove extends Page {
+	public static final String HREF = "/gui/urRemove";
+	static final String NAME = "Remove User Role";
+	static final String fields[] = {"user","role"};
+
+	public UserRoleRemove(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME, HREF, fields,
+				new BreadCrumbs(breadcrumbs),
+				new NamedCode(true, "content") {
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				final Slot sUser = gui.env.slot(NAME+".user");
+				final Slot sRole = gui.env.slot(NAME+".role");
+				
+				
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {						
+						final String user = trans.get(sUser, "");
+						final String role = trans.get(sRole, "");
+
+						TimeTaken tt = trans.start("Request a user role delete",Env.REMOTE);
+						try {
+							gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+								@Override
+								public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+									Future<Void> fv = client.setQueryParams("request=true").delete(
+												"/authz/userRole/"+user+"/"+role,Void.class);
+									
+									if(fv.get(5000)) {
+										// not sure if we'll ever hit this
+										hgen.p("User ["+ user+"] Removed from Role [" +role+"]");
+									} else {
+										if (fv.code() == 202 ) {
+											hgen.p("User ["+ user+"] Removal from Role [" +role+"] sent for Approval");
+										} else {
+											gui.writeError(trans, fv, hgen);
+										}
+									}
+									return null;
+								}
+							});
+						} catch (Exception e) {
+							e.printStackTrace();
+						} finally {
+							tt.done();
+						}
+					}
+				});
+			}
+			
+		});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/WebCommand.java b/authz-gui/src/main/java/com/att/authz/gui/pages/WebCommand.java
new file mode 100644
index 0000000..7c7bdb2
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/WebCommand.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class WebCommand extends Page {
+	public static final String HREF = "/gui/cui";
+	
+	public WebCommand(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, "Web Command Client",HREF, NO_FIELDS,
+				new BreadCrumbs(breadcrumbs),
+				new NamedCode(true, "content") {
+			@Override
+			public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+				hgen.leaf("p","id=help_msg")
+					.text("Questions about this page? ")
+					.leaf("a", "href=http://wiki.web.att.com/display/aaf/Web+CUI+Usage", "target=_blank")
+					.text("Click here")
+					.end()
+					.text(". Type 'help' below for a list of AAF commands")
+					.end()
+					
+					.divID("console_and_options");
+				hgen.divID("console_area");				
+				hgen.end(); //console_area
+				
+				hgen.divID("options_link", "class=closed");
+				hgen.img("src=../../theme/options_down.png", "onclick=handleDivHiding('options',this);", 
+						"id=options_img", "alt=Options", "title=Options")					
+					.end(); //options_link
+				
+				hgen.divID("options");
+				cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI,AuthzTrans>() {
+					@Override
+					public void code(AuthGUI state, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen xgen)
+							throws APIException, IOException {
+						switch(browser(trans,trans.env().slot(getBrowserType()))) {
+							case ie:
+							case ieOld:
+								// IE doesn't support file save
+								break;
+							default:
+								xgen.img("src=../../theme/AAFdownload.png", "onclick=saveToFile();",
+										"alt=Save log to file", "title=Save log to file");
+						}
+//						xgen.img("src=../../theme/AAFemail.png", "onclick=emailLog();",
+//								"alt=Email log to me", "title=Email log to me");
+						xgen.img("src=../../theme/AAF_font_size.png", "onclick=handleDivHiding('text_slider',this);", 
+								"id=fontsize_img", "alt=Change text size", "title=Change text size");
+						xgen.img("src=../../theme/AAF_details.png", "onclick=selectOption(this,0);", 
+								"id=details_img", "alt=Turn on/off details mode", "title=Turn on/off details mode");
+						xgen.img("src=../../theme/AAF_maximize.png", "onclick=maximizeConsole(this);",
+								"id=maximize_img", "alt=Maximize Console Window", "title=Maximize Console Window");
+					}	
+				});
+
+				hgen.divID("text_slider");
+				hgen.tagOnly("input", "type=button", "class=change_font", "onclick=buttonChangeFontSize('dec')", "value=-")
+					.tagOnly("input", "id=text_size_slider", "type=range", "min=75", "max=200", "value=100", 
+						"oninput=changeFontSize(this.value)", "onchange=changeFontSize(this.value)", "title=Change Text Size")
+					.tagOnly("input", "type=button", "class=change_font", "onclick=buttonChangeFontSize('inc')", "value=+")				
+					.end(); //text_slider
+
+				hgen.end(); //options
+				hgen.end(); //console_and_options
+				
+				hgen.divID("input_area");
+				hgen.tagOnly("input", "type=text", "id=command_field", 
+						"autocomplete=off", "autocorrect=off", "autocapitalize=off", "spellcheck=false",
+						"onkeypress=keyPressed()", "placeholder=Type your AAFCLI commands here", "autofocus")
+					.tagOnly("input", "id=submit", "type=button", "value=Submit", 
+							"onclick=http('put','../../gui/cui',getCommand(),callCUI);")
+					.end();
+
+				Mark callCUI = new Mark();
+				hgen.js(callCUI);
+				hgen.text("function callCUI(resp) {")
+					.text("moveCommandToDiv();")
+					.text("printResponse(resp);") 
+					.text("}");
+				hgen.end(callCUI);	
+			
+			}
+		});
+
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/AbsCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/AbsCell.java
new file mode 100644
index 0000000..eb91c22
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/AbsCell.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+public abstract class AbsCell {
+	private static final String[] NONE = new String[0];
+	protected static final String[] CENTER = new String[]{"class=center"};
+
+	/**
+	 * Write Cell Data with HTMLGen generator
+	 * @param hgen
+	 */
+	public abstract void write(HTMLGen hgen);
+	
+	public final static AbsCell Null = new AbsCell() {
+		@Override
+		public void write(final HTMLGen hgen) {
+		}
+	};
+	
+	public String[] attrs() {
+		return NONE;
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/ButtonCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/ButtonCell.java
new file mode 100644
index 0000000..4c270cf
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/ButtonCell.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+public class ButtonCell extends AbsCell {
+	private String[] attrs;
+	
+	public ButtonCell(String value, String ... attributes) {
+		attrs = new String[2+attributes.length];
+		attrs[0]="type=button";
+		attrs[1]="value="+value;
+		System.arraycopy(attributes, 0, attrs, 2, attributes.length);
+	}
+	@Override
+	public void write(HTMLGen hgen) {
+		hgen.incr("input",true,attrs).end();
+
+	}
+	
+	@Override
+	public String[] attrs() {
+		return AbsCell.CENTER;
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/RadioCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/RadioCell.java
new file mode 100644
index 0000000..b4fa644
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/RadioCell.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+public class RadioCell extends AbsCell {
+	private String[] attrs;
+	
+	public RadioCell(String name, String radioClass, String value, String ... attributes) {
+		attrs = new String[4+attributes.length];
+		attrs[0]="type=radio";
+		attrs[1]="name="+name;
+		attrs[2]="class="+radioClass;
+		attrs[3]="value="+value;
+		System.arraycopy(attributes, 0, attrs, 4, attributes.length);
+	}
+	
+	@Override
+	public void write(HTMLGen hgen) {
+		hgen.incr("input",true,attrs).end();
+	}
+
+	@Override
+	public String[] attrs() {
+		return AbsCell.CENTER;
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/RefCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/RefCell.java
new file mode 100644
index 0000000..4971983
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/RefCell.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import static com.att.xgen.html.HTMLGen.A;
+
+import com.att.xgen.html.HTMLGen;
+
+/**
+ * Write a Reference Link into a Cell
+ *
+ */
+public class RefCell extends AbsCell {
+	public final String name;
+	public final String href;
+	private String[] attrs;
+	
+	public RefCell(String name, String href, String... attributes) {
+		attrs = new String[attributes.length];
+		System.arraycopy(attributes, 0, attrs, 0, attributes.length);
+		this.name = name;
+		this.href = href;
+	}
+	
+	@Override
+	public void write(HTMLGen hgen) {
+		hgen.leaf(A,"href="+href).text(name);
+	}
+	
+	@Override
+	public String[] attrs() {
+		return attrs;
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/TextAndRefCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/TextAndRefCell.java
new file mode 100644
index 0000000..1c25361
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/TextAndRefCell.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import static com.att.xgen.html.HTMLGen.A;
+
+import com.att.xgen.html.HTMLGen;
+
+public class TextAndRefCell extends RefCell {
+
+	private String text;
+		
+	public TextAndRefCell(String text, String name, String href, String[] attributes) {
+		super(name, href, attributes);
+		this.text = text;
+	}
+
+	@Override
+	public void write(HTMLGen hgen) {
+		hgen.text(text);
+		hgen.leaf(A,"href="+href).text(name);
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/TextCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/TextCell.java
new file mode 100644
index 0000000..d098792
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/TextCell.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+/**
+ * Write Simple Text into a Cell
+ *
+ */
+public class TextCell extends AbsCell {
+	public final String name;
+	private String[] attrs;
+	
+	public TextCell(String name, String... attributes) {
+		attrs = new String[attributes.length];
+		System.arraycopy(attributes, 0, attrs, 0, attributes.length);
+		this.name = name;
+	}
+	
+	@Override
+	public void write(HTMLGen hgen) {
+		hgen.text(name);
+	}
+	
+	@Override
+	public String[] attrs() {
+		return attrs;
+	}
+}