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-batch/pom.xml b/authz-batch/pom.xml
new file mode 100644
index 0000000..a2233f0
--- /dev/null
+++ b/authz-batch/pom.xml
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>com.att.authz</groupId>
+		<artifactId>parent</artifactId>
+		<version>1.0.0-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+		
+	<artifactId>authz-batch</artifactId>
+	<name>Authz Batch</name>
+	<description>Batch Processing for Authz</description>
+	<packaging>jar</packaging>
+		<url>https://github.com/att/AAF</url>
+	<licenses>
+		<license>
+		<name>BSD License</name>
+		<url> </url>
+		</license>
+	</licenses>
+	<developers>
+		<developer>
+		<name>Jonathan Gathman</name>
+		<email></email>
+	<organization>ATT</organization>
+	<organizationUrl></organizationUrl>
+		</developer>
+	</developers>
+
+	<properties>
+		<maven.test.failure.ignore>false</maven.test.failure.ignore>
+		<project.swmVersion>1</project.swmVersion>
+	</properties>
+	
+	<dependencies>
+
+		<dependency>
+			<groupId>org.onap.aaf.inno</groupId>
+			<artifactId>env</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.onap.aaf.inno</groupId>
+			<artifactId>rosetta</artifactId>
+		</dependency>
+		
+ 		<dependency>
+	        <groupId>org.onap.aaf.cadi</groupId>
+	        <artifactId>cadi-core</artifactId>
+	    </dependency>
+
+ 		<dependency>
+	        <groupId>org.onap.aaf.cadi</groupId>
+	        <artifactId>cadi-aaf</artifactId>
+	    </dependency>
+
+
+
+		<!--  <dependency>
+			<groupId>com.att.authz</groupId>
+			<artifactId>authz-att</artifactId>
+			<exclusions>
+				<exclusion> 
+ 					<groupId>javax.servlet</groupId>
+        			<artifactId>servlet-api</artifactId>
+        		</exclusion>
+        		<exclusion>
+        			<groupId>org.onap.aaf.cadi</groupId>
+        			<artifactId>cadi-aaf</artifactId>
+        		</exclusion>
+        		<exclusion>
+			        <groupId>org.onap.aaf.cadi</groupId>
+			        <artifactId>cadi-core</artifactId>
+			    </exclusion>
+			    <exclusion>
+		        	<groupId>org.onap.aaf.cadi</groupId>
+		        	<artifactId>cadi-client</artifactId>
+		        </exclusion>
+		    </exclusions>
+        		
+		</dependency>   -->
+		
+		<dependency>
+			<groupId>com.att.authz</groupId>
+			<artifactId>authz-cass</artifactId>
+			<exclusions>
+				<exclusion> 
+ 					<groupId>javax.servlet</groupId>
+        			<artifactId>servlet-api</artifactId>
+        		</exclusion>
+        		<exclusion>
+        			<groupId>org.onap.aaf.cadi</groupId>
+        			<artifactId>cadi-aaf</artifactId>
+        		</exclusion>
+        		<exclusion>
+			        <groupId>org.onap.aaf.cadi</groupId>
+			        <artifactId>cadi-core</artifactId>
+			    </exclusion>
+			    <exclusion>
+		        	<groupId>org.onap.aaf.cadi</groupId>
+		        	<artifactId>cadi-client</artifactId>
+		        </exclusion>
+        		
+			</exclusions> 
+		</dependency>
+
+	  	<dependency>
+	    		<groupId>org.joda</groupId>
+	    		<artifactId>joda-time</artifactId>
+	    		<version>2.5</version>
+	  	</dependency>
+
+	  	<dependency>
+	    		<groupId>org.slf4j</groupId>
+	    		<artifactId>slf4j-log4j12</artifactId>
+	  	</dependency>
+	  	
+	  	<!-- Data Migration 
+	  	         <dependency>
+	    <groupId>com.oracle</groupId>
+	    <artifactId>ojdbc6</artifactId>
+	    <version>11.2.0</version>
+	  </dependency>
+	  
+	  <dependency>
+	    <groupId>com.opencsv</groupId>
+	    <artifactId>opencsv</artifactId>
+	    <version>3.3</version>
+	  </dependency>
+	  	-->
+	</dependencies>
+
+	<build>
+		<plugins>
+			 	<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-deploy-plugin</artifactId>
+					<configuration>
+						<skip>true</skip>
+					</configuration>
+			    	</plugin>
+			    
+				<plugin>
+					<artifactId>maven-assembly-plugin</artifactId>
+					<version>2.4</version>
+					
+					<configuration>
+						<classifier>tests</classifier>
+						<archive>
+							<manifestEntries>
+								<Sealed>true</Sealed>
+							</manifestEntries>
+						</archive>
+					</configuration>
+					<executions>
+						<execution>
+							<id>depends</id>
+							<phase>package</phase>
+							<goals>
+								<goal>single</goal>
+							</goals>
+							<configuration>
+						        <descriptorRefs>
+						          <descriptorRef>jar-with-dependencies</descriptorRef>
+						        </descriptorRefs>
+						        <archive>
+						          <manifest>
+						            <mainClass>com.att.authz.Batch</mainClass>
+						          </manifest>
+						        </archive>
+							</configuration>
+						</execution>
+						<execution>
+							<id>swm</id>
+							<phase>package</phase>
+							<goals>
+								<goal>single</goal>
+							</goals>
+				      		<configuration>
+				      			<finalName>authz-batch-${project.version}.${project.swmVersion}</finalName>
+					      		 <descriptors>
+					          		<descriptor>../authz-service/src/main/assemble/swm.xml</descriptor>
+					        	</descriptors>
+					        	<archive>
+						        </archive>
+				      		</configuration>
+						</execution>
+					</executions>
+				</plugin>
+		<plugin>
+			<groupId>org.apache.maven.plugins</groupId>
+			<artifactId>maven-javadoc-plugin</artifactId>
+			<configuration>
+			<failOnError>false</failOnError>
+			</configuration>
+			<executions>
+				<execution>
+					<id>attach-javadocs</id>
+					<goals>
+						<goal>jar</goal>
+					</goals>
+				</execution>
+			</executions>
+		</plugin> 
+	   
+	   
+	       <plugin>
+		      <groupId>org.apache.maven.plugins</groupId>
+		      <artifactId>maven-source-plugin</artifactId>
+		      <version>2.2.1</version>
+		      <executions>
+			<execution>
+			  <id>attach-sources</id>
+			  <goals>
+			    <goal>jar-no-fork</goal>
+			  </goals>
+			</execution>
+		      </executions>
+		    </plugin>
+	
+
+	<plugin>
+	    <groupId>org.apache.maven.plugins</groupId>
+	    <artifactId>maven-gpg-plugin</artifactId>
+	    <version>1.5</version>
+	    <executions>
+		<execution>
+		    <id>sign-artifacts</id>
+		    <phase>verify</phase>
+		    <goals>
+			<goal>sign</goal>
+		    </goals>
+		</execution>
+	    </executions>
+	  </plugin> 
+			
+		<plugin>
+			<groupId>org.sonatype.plugins</groupId>
+			<artifactId>nexus-staging-maven-plugin</artifactId>
+			<version>1.6.7</version>
+			<extensions>true</extensions>
+			<configuration>
+			<serverId>ossrhdme</serverId>
+			<nexusUrl>https://oss.sonatype.org/</nexusUrl>
+			<autoReleaseAfterClose>true</autoReleaseAfterClose>
+			</configuration>
+		</plugin>
+			</plugins>
+	</build>
+</project>
diff --git a/authz-batch/src/main/config/authBatch.props b/authz-batch/src/main/config/authBatch.props
new file mode 100644
index 0000000..cfe75e3
--- /dev/null
+++ b/authz-batch/src/main/config/authBatch.props
@@ -0,0 +1,36 @@
+##
+## AUTHZ Batch (authz-batch) Properties
+##
+## DISCOVERY (DME2) Parameters on the Command Line
+AFT_LATITUDE=_AFT_LATITUDE_
+AFT_LONGITUDE=_AFT_LONGITUDE_
+AFT_ENVIRONMENT=_AFT_ENVIRONMENT_
+DEPLOYED_VERSION=_ARTIFACT_VERSION_
+
+
+DRY_RUN=false
+
+## Pull in common/security properties
+
+cadi_prop_files=_COMMON_DIR_/com.att.aaf.props;_COMMON_DIR_/com.att.aaf.common.props
+
+
+## -------------------------------------
+## Batch specific Settings
+## -------------------------------------
+SPECIAL_NAMES=testunused,testid,unknown
+
+
+## ----------------------------------------------
+## Email Server settings
+## ----------------------------------------------
+#Sender's email ID needs to be mentioned
+mailFromUserId=DL-aaf-support@att.com
+mailHost=smtp.it.att.com
+
+ALERT_TO_ADDRESS=DL-aaf-support@att.com
+
+PASSWORD_RESET_URL=_AUTHZ_GUI_URL_/gui/passwd
+APPROVALS_URL=_AUTHZ_GUI_URL_/gui/approve
+
+
diff --git a/authz-batch/src/main/config/log4j.properties b/authz-batch/src/main/config/log4j.properties
new file mode 100644
index 0000000..169460c
--- /dev/null
+++ b/authz-batch/src/main/config/log4j.properties
@@ -0,0 +1,84 @@
+###############################################################################
+# 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.rootLogger=INFO,FA
+log4j.logger.aspr=INFO,aspr
+log4j.additivity.aspr=false
+log4j.logger.authz-batch=INFO,authz-batch
+log4j.logger.sync=INFO,sync
+log4j.additivity.sync=false
+log4j.logger.jobchange=INFO,jobchange
+log4j.additivity.jobchange=false
+log4j.logger.validateuser=INFO,validateuser
+log4j.additivity.validateuser=false
+
+
+log4j.appender.FA=org.apache.log4j.RollingFileAppender
+log4j.appender.FA.File=${LOG4J_FILENAME_authz-batch}
+log4j.appender.FA.MaxFileSize=10000KB
+log4j.appender.FA.MaxBackupIndex=7
+log4j.appender.FA.layout=org.apache.log4j.PatternLayout 
+log4j.appender.FA.layout.ConversionPattern=%d %p [%c] - %m %n
+
+log4j.appender.stderr=org.apache.log4j.ConsoleAppender
+log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
+log4j.appender.stderr.layout.ConversionPattern=%d %p [%c] - %m %n
+log4j.appender.stderr.Target=System.err
+
+log4j.appender.authz-batch=org.apache.log4j.DailyRollingFileAppender 
+log4j.appender.authz-batch.encoding=UTF-8
+log4j.appender.authz-batch.layout=org.apache.log4j.PatternLayout
+log4j.appender.authz-batch.layout.ConversionPattern=%d [%p] %m %n
+log4j.appender.authz-batch.File=${LOG4J_FILENAME_authz-batch}
+log4j.appender.authz-batch.DatePattern='.'yyyy-MM
+
+log4j.appender.aspr=org.apache.log4j.DailyRollingFileAppender 
+log4j.appender.aspr.encoding=UTF-8
+log4j.appender.aspr.layout=org.apache.log4j.PatternLayout
+log4j.appender.aspr.layout.ConversionPattern=%d [%p] %m %n
+log4j.appender.aspr.File=${LOG4J_FILENAME_aspr}
+log4j.appender.aspr.DatePattern='.'yyyy-MM
+
+
+log4j.appender.jobchange=org.apache.log4j.RollingFileAppender
+log4j.appender.jobchange.File=${LOG4J_FILENAME_jobchange}
+log4j.appender.jobchange.MaxFileSize=10000KB
+log4j.appender.jobchange.MaxBackupIndex=7
+log4j.appender.jobchange.layout=org.apache.log4j.PatternLayout 
+log4j.appender.jobchange.layout.ConversionPattern=%d %p [%c] - %m %n
+
+log4j.appender.validateuser=org.apache.log4j.RollingFileAppender
+log4j.appender.validateuser.File=${LOG4J_FILENAME_validateuser}
+log4j.appender.validateuser.MaxFileSize=10000KB
+log4j.appender.validateuser.MaxBackupIndex=7
+log4j.appender.validateuser.layout=org.apache.log4j.PatternLayout 
+log4j.appender.validateuser.layout.ConversionPattern=%d %p [%c] - %m %n
+
+log4j.appender.sync=org.apache.log4j.DailyRollingFileAppender 
+log4j.appender.sync.encoding=UTF-8
+log4j.appender.sync.layout=org.apache.log4j.PatternLayout
+log4j.appender.sync.layout.ConversionPattern=%d [%p] %m %n
+log4j.appender.sync.File=${LOG4J_FILENAME_sync}
+log4j.appender.sync.DatePattern='.'yyyy-MM
+
+# General Apache libraries
+log4j.logger.org.apache=WARN
+
diff --git a/authz-batch/src/main/java/com/att/authz/Batch.java b/authz-batch/src/main/java/com/att/authz/Batch.java
new file mode 100644
index 0000000..a31d55f
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/Batch.java
@@ -0,0 +1,471 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Constructor;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.text.SimpleDateFormat;
+import java.util.GregorianCalendar;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TimeZone;
+
+import org.apache.log4j.Logger;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.org.Organization;
+import com.att.authz.org.OrganizationException;
+import com.att.authz.org.OrganizationFactory;
+import com.att.dao.CassAccess;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.StaticSlot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.impl.Log4JLogTarget;
+import org.onap.aaf.inno.env.log4j.LogFileNamer;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.Statement;
+
+public abstract class Batch {
+	private static StaticSlot ssargs;
+
+	protected static final String STARS = "*****";
+
+    protected final Cluster cluster; 
+    protected static AuthzEnv env;
+    protected static Session session;
+    protected static Logger aspr;
+    private static Set<String> specialNames = null;
+    protected static boolean dryRun; 
+	protected static String batchEnv;
+
+	public static final String CASS_ENV = "CASS_ENV";
+    protected final static String PUNT="punt";
+    protected final static String VERSION="VERSION";
+    public final static String GUI_URL="GUI_URL";
+    
+    protected final static String ORA_URL="ora_url";
+    protected final static String ORA_PASSWORD="ora_password";
+
+
+    
+    protected Batch(AuthzEnv env) throws APIException, IOException {
+    	// TODO  - Property Driven Organization
+//    	try {
+//			// att = new ATT(env);
+//		} catch (OrganizationException e) {
+//			throw new APIException(e);
+//		}
+
+    	// Be able to change Environments
+    	// load extra properties, i.e.
+    	// PERF.cassandra.clusters=....
+    	batchEnv = env.getProperty(CASS_ENV);
+    	if(batchEnv != null) {
+    		batchEnv = batchEnv.trim();
+    		env.info().log("Redirecting to ",batchEnv,"environment");
+    		String str;
+    		for(String key : new String[]{
+    				CassAccess.CASSANDRA_CLUSTERS,
+    				CassAccess.CASSANDRA_CLUSTERS_PORT,
+    				CassAccess.CASSANDRA_CLUSTERS_USER_NAME,
+    				CassAccess.CASSANDRA_CLUSTERS_PASSWORD,
+    				VERSION,GUI_URL,PUNT,
+    				// TEMP
+    				ORA_URL, ORA_PASSWORD
+    				}) {
+    			if((str = env.getProperty(batchEnv+'.'+key))!=null) {
+    			    env.setProperty(key, str);
+    			}
+    		}
+    	}
+
+    	// Setup for Dry Run
+        cluster = CassAccess.cluster(env,batchEnv);
+        env.info().log("cluster name - ",cluster.getClusterName());
+        String dryRunStr = env.getProperty( "DRY_RUN" );
+        if ( dryRunStr == null || dryRunStr.equals("false") ) {
+		    dryRun = false;
+		} else {
+            dryRun = true;
+            env.info().log("dryRun set to TRUE");
+        }
+
+        // Special names to allow behaviors beyond normal rules
+        String names = env.getProperty( "SPECIAL_NAMES" );
+        if ( names != null )
+        {
+            env.info().log("Loading SPECIAL_NAMES");
+            specialNames = new HashSet<String>();
+            for (String s :names.split(",") )
+            {
+                env.info().log("\tspecial: " + s );
+                specialNames.add( s.trim() );
+            }
+        }
+    }
+
+    protected abstract void run(AuthzTrans trans);
+    protected abstract void _close(AuthzTrans trans);
+    
+    public String[] args() {
+    	return (String[])env.get(ssargs);
+    }
+	
+    public boolean isDryRun()
+    {
+        return( dryRun );
+    }
+    
+	public boolean isSpecial(String user) {
+		if (specialNames != null && specialNames.contains(user)) {
+			env.info().log("specialName: " + user);
+
+			return (true);
+		} else {
+			return (false);
+		}
+	}
+	
+	public boolean isMechID(String user) {
+		if (user.matches("m[0-9][0-9][0-9][0-9][0-9]")) {
+			return (true);
+		} else {
+			return (false);
+		}
+	}
+
+	protected PrintStream fallout(PrintStream _fallout, String logType)
+			throws IOException {
+		PrintStream fallout = _fallout;
+		if (fallout == null) {
+			File dir = new File("logs");
+			if (!dir.exists()) {
+				dir.mkdirs();
+			}
+
+			File f = null;
+			// String os = System.getProperty("os.name").toLowerCase();
+			long uniq = System.currentTimeMillis();
+
+			f = new File(dir, getClass().getSimpleName() + "_" + logType + "_"
+					+ uniq + ".log");
+
+			fallout = new PrintStream(new FileOutputStream(f, true));
+		}
+		return fallout;
+	}
+
+	public Organization getOrgFromID(AuthzTrans trans, String user) {
+		Organization org;
+		try {
+			org = OrganizationFactory.obtain(trans.env(),user.toLowerCase());
+		} catch (OrganizationException e1) {
+			trans.error().log(e1);
+			org=null;
+		}
+
+		if (org == null) {
+			PrintStream fallout = null;
+
+			try {
+				fallout = fallout(fallout, "Fallout");
+				fallout.print("INVALID_ID,");
+				fallout.println(user);
+			} catch (Exception e) {
+				env.error().log("Could not write to Fallout File", e);
+			}
+			return (null);
+		}
+
+		return (org);
+	}
+	
+	public static Row executeDeleteQuery(Statement stmt) {
+		Row row = null;
+		if (!dryRun) {
+			row = session.execute(stmt).one();
+		}
+
+		return (row);
+
+	}
+        
+	public static int acquireRunLock(String className) {
+		Boolean testEnv = true;
+		String envStr = env.getProperty("AFT_ENVIRONMENT");
+
+		if (envStr != null) {
+			if (envStr.equals("AFTPRD")) {
+				testEnv = false;
+			}
+		} else {
+			env.fatal()
+					.log("AFT_ENVIRONMENT property is required and was not found. Exiting.");
+			System.exit(1);
+		}
+
+		if (testEnv) {
+			env.info().log("TESTMODE: skipping RunLock");
+			return (1);
+		}
+
+		String hostname = null;
+		try {
+			hostname = InetAddress.getLocalHost().getHostName();
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+			env.warn().log("Unable to get hostname");
+			return (0);
+		}
+
+		ResultSet existing = session.execute(String.format(
+				"select * from authz.run_lock where class = '%s'", className));
+
+		for (Row row : existing) {
+			long curr = System.currentTimeMillis();
+			ByteBuffer lastRun = row.getBytesUnsafe(2); // Can I get this field
+														// by name?
+
+			long interval = (1 * 60 * 1000); // @@ Create a value in props file
+												// for this
+			long prev = lastRun.getLong();
+
+			if ((curr - prev) <= interval) {
+				env.warn().log(
+						String.format("Too soon! Last run was %d minutes ago.",
+								((curr - prev) / 1000) / 60));
+				env.warn().log(
+						String.format("Min time between runs is %d minutes ",
+								(interval / 1000) / 60));
+				env.warn().log(
+						String.format("Last ran on machine: %s at %s",
+								row.getString("host"), row.getDate("start")));
+				return (0);
+			} else {
+				env.info().log("Delete old lock");
+				deleteLock(className);
+			}
+		}
+
+		GregorianCalendar current = new GregorianCalendar();
+
+		// We want our time in UTC, hence "+0000"
+		SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss+0000");
+		fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
+
+		String cql = String
+				.format("INSERT INTO authz.run_lock (class,host,start) VALUES ('%s','%s','%s') IF NOT EXISTS",
+						className, hostname, fmt.format(current.getTime()));
+
+		env.info().log(cql);
+
+		Row row = session.execute(cql).one();
+		if (!row.getBool("[applied]")) {
+			env.warn().log("Lightweight Transaction failed to write lock.");
+			env.warn().log(
+					String.format("host with lock: %s, running at %s",
+							row.getString("host"), row.getDate("start")));
+			return (0);
+		}
+		return (1);
+	}
+	
+    private static void deleteLock( String className) {
+        Row row = session.execute( String.format( "DELETE FROM authz.run_lock WHERE class = '%s' IF EXISTS", className ) ).one();
+        if (! row.getBool("[applied]")) {
+            env.info().log( "delete failed" );
+        }
+    }
+
+    private static void transferVMProps(AuthzEnv env, String ... props) {
+		String value;
+		for(String key : props) {
+			if((value = System.getProperty(key))!=null) {
+			    env.setProperty(key, value);
+			}
+		}
+		
+	}
+	
+	protected int count(String str, char c) {
+		int count=str==null||str.isEmpty()?0:1;
+		for(int i=str.indexOf(c);i>=0;i=str.indexOf(c,i+1)) {
+			++count;
+		}
+		return count;
+	}
+
+	public final void close(AuthzTrans trans) {
+	    _close(trans);
+	    cluster.close();
+	}
+
+	public static void main(String[] args) {
+	        Properties props = new Properties();
+	        InputStream is=null;
+	        String filename;
+	        String propLoc;
+	        try {
+	            File f = new File("etc/authBatch.props");
+	            try {
+	                if(f.exists()) {
+	                	filename = f.getCanonicalPath();
+	                    is = new FileInputStream(f);
+	                    propLoc=f.getPath();
+	                } else {
+	                    URL rsrc = ClassLoader.getSystemResource("authBatch.props");
+	                    filename = rsrc.toString();
+	                    is = rsrc.openStream();
+	                    propLoc=rsrc.getPath();
+	                }
+	                props.load(is);
+	            } finally {
+	                if(is==null) {
+	                    System.err.println("authBatch.props must exist in etc dir, or in Classpath");
+	                    System.exit(1);
+	                }
+	                is.close();
+	            }
+		
+	            env = new AuthzEnv(props);
+	            
+	            transferVMProps(env,CASS_ENV,"DRY_RUN","NS","Organization");
+				
+	            // Flow all Env Logs to Log4j, with ENV
+	            
+	        	LogFileNamer lfn;
+	        	if((batchEnv=env.getProperty(CASS_ENV))==null) {
+	        		lfn = new LogFileNamer("logs/").noPID();
+	        	} else {
+	        		lfn = new LogFileNamer("logs/" + batchEnv+'/').noPID();
+	        	}
+	        	
+	        	lfn.setAppender("authz-batch");
+	        	lfn.setAppender("aspr|ASPR");
+	        	lfn.setAppender("sync");
+	        	lfn.setAppender("jobchange");
+	        	lfn.setAppender("validateuser");
+	    		aspr = Logger.getLogger("aspr");
+	            Log4JLogTarget.setLog4JEnv("authz-batch", env);
+	            if(filename!=null) {
+	            	env.init().log("Instantiated properties from",filename);
+	            }
+	
+				
+	            // Log where Config found
+	            env.info().log("Configuring from",propLoc);
+	            propLoc=null;
+		
+	            Batch batch = null;
+	            // setup ATTUser and Organization Slots before starting this:
+	            //TODO Property Driven Organization
+//	            env.slot(ATT.ATT_USERSLOT);
+//	            OrganizationFactory.setDefaultOrg(env, ATT.class.getName());
+	            AuthzTrans trans = env.newTrans();
+	            
+	            TimeTaken tt = trans.start("Total Run", Env.SUB);
+	            try {
+	            	int len = args.length;
+	                if(len>0) {
+	                	String toolName = args[0];
+	                	len-=1;
+	                	if(len<0)len=0;
+	                	String nargs[] = new String[len];
+	                	if(len>0) {
+	                		System.arraycopy(args, 1, nargs, 0, len);
+	                	}
+	                	
+	                	env.put(ssargs=env.staticSlot("ARGS"), nargs);
+	                	
+	                    /*
+	                     * Add New Batch Programs (inherit from Batch) here
+	                     */
+	
+	                    if( JobChange.class.getSimpleName().equals(toolName)) {
+	                        aspr.info( "Begin jobchange processing" );
+	                        batch = new JobChange(trans);
+	                    }
+	////                    else if( ValidateUsers.class.getSimpleName().equals(toolName)) {
+	////                        aspr.info( "Begin ValidateUsers processing" );
+	////                        batch = new ValidateUsers(trans);
+	//                    }
+	                    else if( UserRoleDataGeneration.class.getSimpleName().equals(toolName)) {
+	                    	// This job duplicates User Role add/delete History items 
+	                    	// so that we can search them by Role. Intended as a one-time
+	                    	// script! but written as batch job because Java has better
+	                    	// UUID support. Multiple runs will generate multiple copies of 
+	                    	// these history elements!
+	                    	aspr.info( "Begin User Role Data Generation Processing ");
+	                    	batch = new UserRoleDataGeneration(trans);
+	                    } else {  // Might be a Report, Update or Temp Batch
+	                    	Class<?> cls;
+	                    	String classifier = "";
+	                    	try {
+	                    		cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.update."+toolName);
+	                    		classifier = "Update:";
+	                    	} catch(ClassNotFoundException e) {
+	                    		try {
+	                    			cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.reports."+toolName);
+	                        		classifier = "Report:";
+	                    		} catch (ClassNotFoundException e2) {
+	                        		try {
+	                        			cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.temp."+toolName);
+	                            		classifier = "Temp Utility:";
+	                        		} catch (ClassNotFoundException e3) {
+	                        			cls = null;
+	                        		}
+	                    		}
+	                    	}
+	                    	if(cls!=null) {
+	                    		Constructor<?> cnst = cls.getConstructor(new Class[]{AuthzTrans.class});
+	                    		batch = (Batch)cnst.newInstance(trans);
+		                    	env.info().log("Begin",classifier,toolName);
+	                    	}
+	                    }
+	
+	                    if(batch==null) {
+	                        trans.error().log("No Batch named",toolName,"found");
+	                    }
+	                    /*
+	                     * End New Batch Programs (inherit from Batch) here
+	                     */
+	
+	                } 
+	                if(batch!=null) {
+	                    batch.run(trans);
+	                }
+	            } finally {
+	            	tt.done();
+	                if(batch!=null) {
+	                    batch.close(trans);
+	                }
+	                StringBuilder sb = new StringBuilder("Task Times\n");
+	                trans.auditTrail(4, sb, AuthzTrans.REMOTE);
+	                trans.info().log(sb);
+	            }
+	        } catch (Exception e) {
+	            e.printStackTrace(System.err);
+	            // Exceptions thrown by DB aren't stopping the whole process.
+	            System.exit(1);
+	        }
+	    }
+
+
+}
+
diff --git a/authz-batch/src/main/java/com/att/authz/BatchException.java b/authz-batch/src/main/java/com/att/authz/BatchException.java
new file mode 100644
index 0000000..7247503
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/BatchException.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz;
+
+public class BatchException extends Exception {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -3877245367723491192L;
+
+	public BatchException() {
+	}
+
+	public BatchException(String message) {
+		super(message);
+	}
+
+	public BatchException(Throwable cause) {
+		super(cause);
+	}
+
+	public BatchException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	public BatchException(String message, Throwable cause,
+			boolean enableSuppression, boolean writableStackTrace) {
+		super(message, cause, enableSuppression, writableStackTrace);
+	}
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/CassBatch.java b/authz-batch/src/main/java/com/att/authz/CassBatch.java
new file mode 100644
index 0000000..f251582
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/CassBatch.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+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.impl.Log4JLogTarget;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.exceptions.InvalidQueryException;
+
+public abstract class CassBatch extends Batch {
+
+	protected CassBatch(AuthzTrans trans, String log4JName) throws APIException, IOException {
+		super(trans.env());
+		// Flow all Env Logs to Log4j
+		Log4JLogTarget.setLog4JEnv(log4JName, env);
+		
+		TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+		try {
+			session = cluster.connect();
+		} finally {
+			tt.done();
+		}
+	}
+
+	@Override
+	protected void _close(AuthzTrans trans) {
+	    session.close();
+		trans.info().log("Closed Session");
+	}
+
+	public ResultSet executeQuery(String cql) {
+		return executeQuery(cql,"");
+	}
+
+	public ResultSet executeQuery(String cql, String extra) {
+		if(isDryRun() && !cql.startsWith("SELECT")) {
+			if(extra!=null)env.info().log("Would query" + extra + ": " + cql);
+		} else {
+			if(extra!=null)env.info().log("query" + extra + ": " + cql);
+			try {
+				return session.execute(cql);
+			} catch (InvalidQueryException e) {
+				if(extra==null) {
+					env.info().log("query: " + cql);
+				}
+				throw e;
+			}
+		} 
+		return null;
+	}
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/FileCassBatch.java b/authz-batch/src/main/java/com/att/authz/FileCassBatch.java
new file mode 100644
index 0000000..1044052
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/FileCassBatch.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.DirectoryIteratorException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import org.onap.aaf.inno.env.APIException;
+
+public abstract class FileCassBatch extends CassBatch {
+
+	public FileCassBatch(AuthzTrans trans, String log4jName) throws APIException, IOException {
+		super(trans, log4jName);
+	}
+	
+	protected List<File> findAllFiles(String regex) {
+		List<File> files = new ArrayList<File>();
+		FileSystem fileSystem = FileSystems.getDefault();
+		PathMatcher pathMatcher = fileSystem.getPathMatcher("glob:" + regex);
+		Path path = Paths.get(System.getProperty("user.dir"), "data");
+
+		try {
+			DirectoryStream<Path> directoryStream = Files.newDirectoryStream(
+					path, regex);
+			for (Path file : directoryStream) {
+				if (pathMatcher.matches(file.getFileName())) {
+					files.add(file.toFile());
+				}
+			}
+		} catch (IOException ex) {
+			ex.printStackTrace();
+		} catch (DirectoryIteratorException ex) {
+			ex.printStackTrace();
+		}
+
+		return files;
+	}
+
+
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/JobChange.java b/authz-batch/src/main/java/com/att/authz/JobChange.java
new file mode 100644
index 0000000..e5672e6
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/JobChange.java
@@ -0,0 +1,743 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+// test for case where I'm an admin
+
+package com.att.authz;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.org.Organization;
+import com.att.authz.org.OrganizationFactory;
+import org.onap.aaf.inno.env.APIException;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class JobChange extends Batch
+{
+    private class UserRole
+    {
+        String user;
+        String role;
+    }
+    private class UserCred
+    {
+        String user;
+        String ns;
+    }
+    
+    private class NamespaceOwner
+    {
+        String user;
+        String ns;
+        boolean responsible;
+        int ownerCount;
+    }
+    
+
+    private AuthzTrans myTrans;
+
+	private Map<String, ArrayList<UserRole>> rolesMap = new HashMap<String, ArrayList<UserRole>>();
+	private Map<String, ArrayList<NamespaceOwner>> ownersMap = new HashMap<String, ArrayList<NamespaceOwner>>();
+    private Map<String, ArrayList<UserCred>> credsMap = new HashMap<String, ArrayList<UserCred>>();
+    
+    
+    public static void createDirectory( String dir )
+    {
+        File f = new File( dir );
+
+        if ( ! f.exists())
+        {
+            env.info().log( "creating directory: " + dir );
+            boolean result = false;
+
+            try
+            {
+                f.mkdir();
+                result = true;
+            } catch(SecurityException e){
+                e.printStackTrace();
+            }        
+            if(result) {    
+                System.out.println("DIR created");  
+            }
+        }        
+    }
+    
+    public static String getJobChangeDataFile()
+    {
+        File outFile = null;
+        BufferedWriter writer = null;
+        BufferedReader reader = null;
+        String line;
+        boolean errorFlag = false;
+
+        try
+        {
+            createDirectory( "etc" );
+            
+            outFile = new File("etc/jobchange." + getCurrentDate() );
+            if (!outFile.exists())
+            {
+                outFile.createNewFile();
+            }
+            else
+            {
+                return( "etc/jobchange." + getCurrentDate() );
+            }
+			
+            env.info().log("Creating the local file with the webphone data");
+
+
+
+            writer = new BufferedWriter(new FileWriter(
+                                            outFile.getAbsoluteFile()));
+
+            URL u = new URL(  "ftp://thprod37.sbc.com/jobchange_Delta.dat" );
+            reader = new BufferedReader(new InputStreamReader(
+                                            new BufferedInputStream(u.openStream())));
+            while ((line = reader.readLine()) != null) {
+                writer.write(line + "\n");
+            }
+			
+            writer.close();
+            reader.close();
+            
+            env.info().log("Finished fetching the data from the webphone ftp site.");
+            return( "etc/jobchange." + getCurrentDate() );
+            
+        } catch (MalformedURLException e) {
+            env.error().log("Could not open the remote job change data file.", e);
+            errorFlag = true;
+
+        } catch (IOException e) {
+            env.error().log(
+                "Error while opening or writing to the local data file.", e);
+            errorFlag = true;
+
+        } catch (Exception e) {
+            env.error().log("Error while fetching the data file.", e);
+            errorFlag = true;
+
+        } finally {
+            if (errorFlag)
+                outFile.delete();
+        }
+		return null;
+    }
+
+    public static String getCurrentDate()
+    {
+        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
+        Date now = new Date();
+        String strDate = sdfDate.format(now);
+        return strDate;
+    }
+
+    public void loadUsersFromCred()
+    {
+        String query = "select id,ns from authz.cred" ;
+                                      
+        env.info().log( "query: " + query );
+
+        Statement stmt = new SimpleStatement( query );
+        ResultSet results = session.execute(stmt);
+
+        Iterator<Row> iter = results.iterator();
+        while( iter.hasNext() )
+        {
+            Row row = iter.next();
+            String user = row.getString( "id" );
+            String ns = row.getString( "ns" );
+            String simpleUser = user.substring( 0, user.indexOf( "@" ) );
+
+            if ( isMechID( simpleUser ) )
+            {
+                continue;
+            }
+            else if ( credsMap.get( simpleUser ) == null )
+            {
+                credsMap.put( simpleUser, new ArrayList<UserCred>() );
+                
+                UserCred newEntry = new UserCred();
+                newEntry.user = user;
+                newEntry.ns = ns;
+            
+                credsMap.get( simpleUser ).add( newEntry );
+            }
+            else 
+            {
+                UserCred newEntry = new UserCred();
+                newEntry.user = user;
+                newEntry.ns = ns;
+            
+                credsMap.get( simpleUser ).add( newEntry );
+            }
+                
+            env.debug().log( String.format( "\tUser: %s NS: %s", user, ns ) );
+        }
+    }
+
+    public void loadUsersFromRoles()
+    {
+        String query = "select user,role from authz.user_role" ;
+                                      
+        env.info().log( "query: " + query );
+
+        Statement stmt = new SimpleStatement( query );
+        ResultSet results = session.execute(stmt);
+        int total=0, flagged=0;
+
+        Iterator<Row> iter = results.iterator();
+        while( iter.hasNext() )
+        {
+            Row row = iter.next();
+            String user = row.getString( "user" );
+            String role = row.getString( "role" );
+            String simpleUser = user.substring( 0, user.indexOf( "@" ) );
+
+            if ( isMechID( simpleUser ) )
+            {
+                continue;
+            }
+            else if ( rolesMap.get( simpleUser ) == null )
+            {
+                rolesMap.put( simpleUser, new ArrayList<UserRole>() );
+                
+                UserRole newEntry = new UserRole();
+                newEntry.user = user;
+                newEntry.role = role;
+            
+                rolesMap.get( simpleUser ).add( newEntry );
+            }
+            else
+            {
+                UserRole newEntry = new UserRole();
+                newEntry.user = user;
+                newEntry.role = role;
+            
+                rolesMap.get( simpleUser ).add( newEntry );
+            }
+                
+            env.debug().log( String.format( "\tUser: %s Role: %s", user, role ) );
+
+            ++total;
+        }
+        env.info().log( String.format( "rows read: %d expiring: %d", total, flagged ) );
+    }
+
+    public void loadOwnersFromNS()
+    {
+        String query = "select name,admin,responsible from authz.ns" ;
+                                      
+        env.info().log( "query: " + query );
+
+        Statement stmt = new SimpleStatement( query );
+        ResultSet results = session.execute(stmt);
+
+        Iterator<Row> iter = results.iterator();
+        while( iter.hasNext() )
+        {
+            Row row = iter.next();
+            Set<String> responsibles = row.getSet( "responsible", String.class );
+
+            for ( String user : responsibles )
+            {
+                env.info().log( String.format( "Found responsible %s", user ) );
+                String simpleUser = user.substring( 0, user.indexOf( "@" ) );
+
+                if ( isMechID( simpleUser ) )
+                {
+                    continue;
+                }
+                else if ( ownersMap.get( simpleUser ) == null )
+                {
+                    ownersMap.put( simpleUser, new ArrayList<NamespaceOwner>() );
+
+                    NamespaceOwner newEntry = new NamespaceOwner();
+                    newEntry.user = user;
+                    newEntry.ns   = row.getString( "name" );
+                    newEntry.ownerCount = responsibles.size();
+                    newEntry.responsible = true;
+                    ownersMap.get( simpleUser ).add( newEntry );
+                }
+                else 
+                {
+                    NamespaceOwner newEntry = new NamespaceOwner();
+                    newEntry.user = user;
+                    newEntry.ns = row.getString( "name" );
+                    newEntry.ownerCount = responsibles.size();
+                    newEntry.responsible = true;                    
+                    ownersMap.get( simpleUser ).add( newEntry );
+                }
+            }                
+            Set<String> admins = row.getSet( "admin", String.class );
+
+            for ( String user : admins )
+            {
+                env.info().log( String.format( "Found admin %s", user ) );
+                String simpleUser = user.substring( 0, user.indexOf( "@" ) );
+
+                if ( isMechID( simpleUser ) )
+                {
+                    continue;
+                }
+                else if ( ownersMap.get( simpleUser ) == null )
+                {
+                    ownersMap.put( simpleUser, new ArrayList<NamespaceOwner>() );
+
+                    NamespaceOwner newEntry = new NamespaceOwner();
+                    newEntry.user = user;
+                    newEntry.ns   = row.getString( "name" );
+                    newEntry.responsible = false;
+                    newEntry.ownerCount = -1; //                     
+                    ownersMap.get( simpleUser ).add( newEntry );
+                }
+                else 
+                {
+                    NamespaceOwner newEntry = new NamespaceOwner();
+                    newEntry.user = user;
+                    newEntry.ns = row.getString( "name" );
+                    newEntry.responsible = false;
+                    newEntry.ownerCount = -1; //                                         
+                    ownersMap.get( simpleUser ).add( newEntry );
+                }
+            }                
+
+        }
+    }
+
+	/**
+	 * Processes the specified JobChange data file obtained from Webphone. Each line is 
+	 * read and processed and any fallout is written to the specified fallout file. 
+	 * If fallout file already exists it is deleted and a new one is created. A
+	 * comparison of the supervisor id in the job data file is done against the one returned 
+	 * by the authz service and if the supervisor Id has changed then the record is updated
+	 * using the authz service. An email is sent to the new supervisor to approve the roles 
+	 * assigned to the user.
+	 * 
+	 * @param fileName - name of the file to process including its path
+	 * @param falloutFileName - the file where the fallout entries have to be written
+	 * @param validDate - the valid effective date when the user had moved to the new supervisor
+	 * @throws Exception
+	 */
+	public void processJobChangeDataFile(String fileName,
+                                         String falloutFileName, Date validDate) throws Exception
+    {
+        
+		BufferedWriter writer = null;
+
+		try {
+
+            env.info().log("Reading file: " + fileName );
+
+            FileInputStream fstream = new FileInputStream(fileName);
+            BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+
+            String strLine;
+
+            while ((strLine = br.readLine()) != null)   {
+                processLine( strLine, writer );
+            }
+
+            br.close();
+			
+			
+		} catch (IOException e) {
+            env.error().log( "Error while reading from the input data file: " + e );
+			throw e;
+        }
+    }
+
+    public void handleAdminChange( String user )
+    {
+        ArrayList<NamespaceOwner> val = ownersMap.get( user );
+        
+        for ( NamespaceOwner r : val )
+        {
+            env.info().log( "handleAdminChange: " + user );
+            AuthzTrans trans = env.newTransNoAvg();
+
+            
+            if ( r.responsible )
+            {
+                env.info().log( String.format( "delete from NS owner: %s, NS: %s, count: %s",
+                                           r.user, r.ns, r.ownerCount ) );
+
+                aspr.info( String.format( "action=DELETE_NS_OWNER, user=%s, ns=%s",
+                                      r.user, r.ns ) );
+                if ( r.ownerCount < 2 )
+                {
+                    // send warning email to aaf-support, after this deletion, no owner for NS
+                    ArrayList<String> toAddress = new ArrayList<String>();
+                    toAddress.add( "XXX_EMAIL" );
+                
+                    env.warn().log( "removing last owner from namespace" );
+
+                    Organization org = null;
+                    org = getOrgFromID( myTrans, org, toAddress.get(0) );
+
+                    env.info().log( "calling getOrgFromID with " + toAddress.get(0) );
+
+                    if ( org != null )
+                    {
+                        try
+                        {
+                            aspr.info( String.format( "action=EMAIL_NO_OWNER_NS to=%s, user=%s, ns=%s",
+                                                      toAddress.get(0), r.user, r.ns ) );
+                            org.sendEmail( trans, toAddress,
+                                           new ArrayList<String>(),
+                                           String.format( "WARNING: no owners for AAF namespace '%s'", r.ns ), // subject:
+                                           String.format( "AAF recieved a jobchange notification for user %s who was the owner of the '%s' namespace. Please identify a new owner for this namespace and update AAF.", r.user, r.ns ), // body of msg
+                                           true );
+                        } catch (Exception e) {
+                            env.error().log("calling sendEmail()");
+                        
+                            e.printStackTrace();
+                        }
+                    }
+                    else
+                    {
+                        env.error().log( "Failed getOrgFromID" );
+                    }
+                }
+            }
+            else
+            {
+                env.info().log( String.format( "delete from NS admin: %s, NS: %s",
+                                           r.user, r.ns ) );
+
+                aspr.info( String.format( "action=DELETE_NS_ADMIN, user=%s, ns=%s",
+                                          r.user, r.ns ) );
+            }                    
+            
+            String field = (r.responsible == true) ? "responsible" : "admin";
+            
+            String query = String.format( "update authz.ns set %s = %s - {'%s'} where name = '%s'",
+                                          field, field, r.user, r.ns ) ;                                   
+            env.info().log( "query: " + query );
+            Statement stmt = new SimpleStatement( query );
+            /*Row row = */session.execute(stmt).one();
+            
+            String attribQuery = String.format( "delete from authz.ns_attrib where ns = '%s' AND type='%s' AND name='%s'",
+        			r.ns, field, r.user);
+            env.info().log( "ns_attrib query: " + attribQuery);
+            Statement attribStmt = new SimpleStatement( attribQuery );
+            /*Row attribRow = */session.execute(attribStmt).one();
+            
+        }
+    }
+
+    public void handleRoleChange( String user )
+    {
+        ArrayList<UserRole> val = rolesMap.get( user );
+        
+        for ( UserRole r : val )
+        {
+            env.info().log( "handleRoleChange: " + user );
+
+            env.info().log( String.format( "delete from %s from user_role: %s",
+                                           r.user, r.role ) );
+
+            aspr.info( String.format( "action=DELETE_FROM_ROLE, user=%s, role=%s",
+                                      r.user, r.role ) );
+
+
+            String query = String.format( "delete from authz.user_role where user = '%s' and role = '%s'",
+                                          r.user, r.role );
+                                      
+            env.info().log( "query: " + query );
+
+            Statement stmt = new SimpleStatement( query );
+            /* Row row = */ session.execute(stmt).one();
+
+        }
+    }
+    
+    public void handleCredChange( String user )
+    {
+        ArrayList<UserCred> val = credsMap.get( user );
+        
+        for ( UserCred r : val )
+        {
+            env.info().log( "handleCredChange: " + user );
+
+            env.info().log( String.format( "delete user %s cred from ns: %s",
+                                           r.user, r.ns ) );
+
+            aspr.info( String.format( "action=DELETE_FROM_CRED, user=%s, ns=%s",
+                                      r.user, r.ns ) );
+
+            String query = String.format( "delete from authz.cred where id = '%s'",
+                                          r.user );
+                                      
+            env.info().log( "query: " + query );
+
+            Statement stmt = new SimpleStatement( query );
+            /*Row row = */session.execute(stmt).one();
+
+        }
+
+    }
+    
+    public boolean processLine(String line, BufferedWriter writer) throws IOException
+    {
+        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd");
+        boolean errorFlag = false;
+        String errorMsg = "";
+
+        try
+        {
+            String[] phoneInfo = line.split( "\\|" );
+
+            if ((phoneInfo != null) && (phoneInfo.length >= 8)
+                && (!phoneInfo[0].startsWith("#")))
+            {
+                String user = phoneInfo[0];
+                String newSupervisor = phoneInfo[7];
+                Date effectiveDate = sdfDate.parse(phoneInfo[8].trim());
+
+                env.debug().log( String.format( "checking user: %s, newSupervisor: %s, date: %s",
+                                                user, newSupervisor, effectiveDate ) );
+                    
+                // Most important case, user is owner of a namespace
+                //
+                if ( ownersMap.get( user ) != null )
+                {
+                    env.info().log( String.format( "Found %s as a namespace admin/owner", user ) );
+                    handleAdminChange( user );
+                }
+
+                if ( credsMap.get( user ) != null )
+                {
+                    env.info().log( String.format( "Found %s in cred table", user ) );
+                    handleCredChange( user );
+                }
+
+                if ( rolesMap.get( user ) != null )
+                {
+                    env.info().log( String.format( "Found %s in a role ", user ) );
+                    handleRoleChange( user );
+                }
+            }
+                
+            else if (phoneInfo[0].startsWith("#"))
+            {
+                return true;
+            }
+            else
+            {
+                env.warn().log("Can't parse. Skipping the line." + line);
+                errorFlag = true;
+            }
+        } catch (Exception e) {
+            errorFlag = true;
+            errorMsg = e.getMessage();
+            env.error().log( "Error while processing line:" + line +  e );
+            e.printStackTrace();
+        } finally {
+            if (errorFlag) {
+                env.info().log( "Fallout enrty being written for line:" + line );
+                writer.write(line + "|Failed to update supervisor for user:" + errorMsg + "\n");
+            }
+        }
+        return true;
+    }
+
+
+	public JobChange(AuthzTrans trans) throws APIException, IOException {
+		super( trans.env() );
+        myTrans = trans;
+		session = cluster.connect();
+	}
+
+    public Organization getOrgFromID( AuthzTrans trans, Organization _org, String user ) {
+	Organization org = _org;
+        if ( org == null || ! user.endsWith( org.getRealm() ) ) {
+            int idx = user.lastIndexOf('.');
+            if ( idx > 0 )
+                idx = user.lastIndexOf( '.', idx-1 );
+
+            org = null;
+            if ( idx > 0 ) {
+                try {
+                    org = OrganizationFactory.obtain( trans.env(), user.substring( idx+1 ) );
+                } catch (Exception e) {
+                    trans.error().log(e,"Failure Obtaining Organization");
+                }
+            }
+
+            if ( org == null ) {
+                PrintStream fallout = null;
+
+                try {
+                    fallout= fallout(fallout, "Fallout");
+                    fallout.print("INVALID_ID,");
+                    fallout.println(user);
+                } catch (Exception e) {
+                    env.error().log("Could not write to Fallout File",e);
+                } 
+                return( null );
+            }
+        }
+        return( org );
+    }        
+
+    public void dumpOwnersMap()
+    {
+        for ( Map.Entry<String, ArrayList<NamespaceOwner>> e : ownersMap.entrySet() )
+        {
+            String key = e.getKey();
+            ArrayList<NamespaceOwner> values = e.getValue();
+
+            env.info().log( "ns user: " + key );
+
+            for ( NamespaceOwner r : values )
+            {
+                env.info().log( String.format( "\tNS-user: %s, NS-name: %s, ownerCount: %d",
+                                               r.user, r.ns, r.ownerCount ) );
+
+            }
+        }
+    }
+
+    public void dumpRolesMap()
+    {
+        for ( Map.Entry<String, ArrayList<UserRole>> e : rolesMap.entrySet() )
+        {
+            String key = e.getKey();
+            ArrayList<UserRole> values = e.getValue();
+
+            env.info().log( "user: " + key );
+
+            for ( UserRole r : values )
+            {
+                env.info().log( String.format( "\trole-user: %s, role-name: %s",
+                                                r.user, r.role ) );
+            }
+        }
+    }
+    public void dumpCredMap()
+    {
+        for ( Map.Entry<String, ArrayList<UserCred>> e : credsMap.entrySet() )
+        {
+            String key = e.getKey();
+            ArrayList<UserCred> values = e.getValue();
+
+            env.info().log( "user: " + key );
+
+            for ( UserCred r : values )
+            {
+                env.info().log( String.format( "\tcred-user: %s, ns: %s",
+                                                r.user, r.ns ) );
+            }
+
+        }
+    }
+
+	@Override
+	protected void run (AuthzTrans trans)
+	{
+        if ( acquireRunLock( this.getClass().getName() ) != 1 ) {
+                env.warn().log( "Cannot acquire run lock, exiting" );
+                System.exit( 1 );
+        }
+
+		try {
+//            Map<String,EmailMsg> email = new HashMap<String,EmailMsg>();
+
+            try
+            {
+                String workingDir = System.getProperty("user.dir");
+                env.info().log( "Process jobchange file. PWD is " + workingDir );
+                
+                loadUsersFromRoles();
+                loadOwnersFromNS();
+                loadUsersFromCred();
+
+                dumpRolesMap();
+                dumpOwnersMap();
+                dumpCredMap();
+                
+                String fname = getJobChangeDataFile();
+                
+                if ( fname == null )
+                {
+                    env.warn().log("getJobChangedatafile returned null");
+                }
+                else
+                {
+                    env.info().log("done with FTP");
+                }
+				processJobChangeDataFile( fname, "fallout", null );
+			}
+            catch (Exception e)
+            {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+            
+
+		} catch (IllegalArgumentException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+		} catch (SecurityException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+		}
+	}
+
+/*
+    private class EmailMsg {
+        private boolean urgent = false;
+        public String url;
+        public Organization org;
+        public String summary;
+
+        public EmailMsg() {
+            org = null;
+            summary = "";
+        }
+
+        public boolean getUrgent() {
+            return( this.urgent );
+        }
+
+        public void setUrgent( boolean val ) {
+            this.urgent = val;
+        }
+        public void setOrg( Organization newOrg ) {
+            this.org = newOrg;
+        }
+        public Organization getOrg() {
+            return( this.org );
+        }
+    }
+*/
+	@Override
+	protected void _close(AuthzTrans trans) {
+        session.close();
+	}
+}
+
+
diff --git a/authz-batch/src/main/java/com/att/authz/UserRoleDataGeneration.java b/authz-batch/src/main/java/com/att/authz/UserRoleDataGeneration.java
new file mode 100644
index 0000000..df537c2
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/UserRoleDataGeneration.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Random;
+import java.util.UUID;
+
+import com.att.authz.env.AuthzTrans;
+import org.onap.aaf.inno.env.APIException;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class UserRoleDataGeneration extends Batch {
+
+	protected UserRoleDataGeneration(AuthzTrans trans) throws APIException,	IOException {
+		super(trans.env());
+		session = cluster.connect();
+
+	}
+
+	@Override
+	protected void run(AuthzTrans trans) {
+		
+		String query = "select * from authz.history" ;
+        
+        env.info().log( "query: " + query );
+
+        Statement stmt = new SimpleStatement( query );
+        ResultSet results = session.execute(stmt);
+        int total=0;
+
+        Iterator<Row> iter = results.iterator();
+
+		Random rand = new Random();
+		
+		int min = 1;
+		int max = 32;
+        
+        while( iter.hasNext() ) {
+        	Row row = iter.next();
+        	if (row.getString("target").equals("user_role")) {
+        		int randomNum = rand.nextInt((max - min) + 1) + min;
+        		
+        		String newId = modifiedTimeuid(row.getUUID("id").toString(), randomNum);
+        		String subject = row.getString("subject");
+        		String newSubject = subject.split("\\|")[1];
+ 
+        		String newInsert = insertStmt(row, newId, "role", newSubject);
+           		Statement statement = new SimpleStatement(newInsert);
+           		session.executeAsync(statement);
+
+           		total++;        		
+        	}
+        }
+        
+        env.info().log(total+ " history elements inserted for user roles");
+    
+	}
+
+	private String insertStmt(Row row, String newId, String newTarget, String newSubject) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("INSERT INTO authz.history (id,action,memo,reconstruct,subject,target,user,yr_mon) VALUES (");
+		sb.append(newId+",");
+		sb.append("'"+row.getString("action")+"',");
+		sb.append("'"+row.getString("memo")+"',");
+		sb.append("null,");
+		sb.append("'"+newSubject+"',");
+		sb.append("'"+newTarget+"',");
+		sb.append("'"+row.getString("user")+"',");
+		sb.append(row.getInt("yr_mon"));
+		sb.append(")");
+		
+		return sb.toString();
+	}
+
+	private String modifiedTimeuid(String origTimeuuid, int rand) {
+		UUID uuid = UUID.fromString(origTimeuuid);
+		
+		long bottomBits = uuid.getLeastSignificantBits();
+		long newBottomBits = bottomBits + (1 << rand);
+		if (newBottomBits - bottomBits == 0)
+			env.info().log("Duplicate!\t"+uuid + " not duplicated for role history function.");
+		
+		UUID newUuid = new UUID(uuid.getMostSignificantBits(),newBottomBits);
+		return newUuid.toString();
+	}
+
+	@Override
+	protected void _close(AuthzTrans trans) {
+        session.close();
+        aspr.info( "End UserRoleDataGeneration processing" );
+
+	}
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/Action.java b/authz-batch/src/main/java/com/att/authz/actions/Action.java
new file mode 100644
index 0000000..f69bb22
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/Action.java
@@ -0,0 +1,11 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+
+public interface Action<T,RV> {
+	public Result<RV> exec(AuthzTrans trans, T ur);
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/ActionDAO.java b/authz-batch/src/main/java/com/att/authz/actions/ActionDAO.java
new file mode 100644
index 0000000..f0d10a8
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/ActionDAO.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.dao.CassAccess;
+import com.att.dao.aaf.hl.Function;
+import com.att.dao.aaf.hl.Question;
+import org.onap.aaf.inno.env.APIException;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+
+public abstract class ActionDAO<T,RV> implements Action<T,RV> {
+	protected final Question q; 
+	protected final Function f;
+	private boolean clean;
+
+	public ActionDAO(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+		q = new Question(trans, cluster, CassAccess.KEYSPACE, false);
+		f = new Function(trans,q);
+		clean = true;
+	}
+	
+	public ActionDAO(AuthzTrans trans, ActionDAO<?,?> predecessor) {
+		q = predecessor.q;
+		f = new Function(trans,q);
+		clean = false;
+	}
+	
+	public Session getSession(AuthzTrans trans) throws APIException, IOException {
+		return q.historyDAO.getSession(trans);
+	}
+
+	public void close(AuthzTrans trans) {
+		if(clean) {
+			q.close(trans);
+		}
+	}
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/ActionPuntDAO.java b/authz-batch/src/main/java/com/att/authz/actions/ActionPuntDAO.java
new file mode 100644
index 0000000..3f521f1
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/ActionPuntDAO.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import com.att.authz.env.AuthzTrans;
+import org.onap.aaf.inno.env.APIException;
+import com.datastax.driver.core.Cluster;
+
+public abstract class ActionPuntDAO<T, RV> extends ActionDAO<T, RV> {
+	private static final SecureRandom random = new SecureRandom();
+	private int months, range;
+	protected static final Date now = new Date();
+
+	public ActionPuntDAO(AuthzTrans trans, Cluster cluster, int months, int range) throws APIException, IOException {
+		super(trans, cluster);
+		this.months = months;
+		this.range = range;
+	}
+
+	public ActionPuntDAO(AuthzTrans trans, ActionDAO<?, ?> predecessor, int months, int range) {
+		super(trans, predecessor);
+		this.months = months;
+		this.range = range;
+	}
+	
+
+	protected Date puntDate() {
+		GregorianCalendar temp = new GregorianCalendar();
+		temp.setTime(now);
+		if(range>0) {
+			int forward = months+Math.abs(random.nextInt()%range);
+			temp.add(GregorianCalendar.MONTH, forward);
+			temp.add(GregorianCalendar.DAY_OF_MONTH, (random.nextInt()%30)-15);
+		}
+		return temp.getTime();
+		
+	}
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/CredDelete.java b/authz-batch/src/main/java/com/att/authz/actions/CredDelete.java
new file mode 100644
index 0000000..80c6755
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/CredDelete.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.CredDAO;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class CredDelete extends ActionDAO<CredDAO.Data,Void> {
+	
+	public CredDelete(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+		super(trans, cluster);
+	}
+
+	public CredDelete(AuthzTrans trans, ActionDAO<?,?> adao) {
+		super(trans, adao);
+	}
+
+	@Override
+	public Result<Void> exec(AuthzTrans trans, CredDAO.Data cred) {
+		Result<Void> rv = q.credDAO.delete(trans, cred, true); // need to read for undelete
+		trans.info().log("Deleted:",cred.id,CredPrint.type(cred.type),Chrono.dateOnlyStamp(cred.expires));
+		return rv;
+	}
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/CredPrint.java b/authz-batch/src/main/java/com/att/authz/actions/CredPrint.java
new file mode 100644
index 0000000..3e8c294
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/CredPrint.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.CredDAO;
+import org.onap.aaf.inno.env.util.Chrono;
+
+public class CredPrint implements Action<CredDAO.Data,Void> {
+	private String text;
+
+	public CredPrint(String text) {
+		this.text = text;
+	}
+
+	@Override
+	public Result<Void> exec(AuthzTrans trans, CredDAO.Data cred) {
+		trans.info().log(text,cred.id,type(cred.type),Chrono.dateOnlyStamp(cred.expires));
+		return Result.ok();
+	}
+	
+	
+	public static String type(int type) {
+		switch(type) {
+			case CredDAO.BASIC_AUTH: // 1
+					return "OLD";
+			case CredDAO.BASIC_AUTH_SHA256: // 2 
+					return "U/P"; 
+			case CredDAO.CERT_SHA256_RSA: // 200
+					return "Cert"; 
+			default: 
+				return "Unknown";
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/CredPunt.java b/authz-batch/src/main/java/com/att/authz/actions/CredPunt.java
new file mode 100644
index 0000000..0805e9b
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/CredPunt.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.CredDAO;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class CredPunt extends ActionPuntDAO<CredDAO.Data,Void> {
+	
+	public CredPunt(AuthzTrans trans, Cluster cluster, int months, int range) throws IOException, APIException {
+		super(trans,cluster,months,range);
+	}
+
+	public CredPunt(AuthzTrans trans, ActionDAO<?,?> adao, int months, int range) throws IOException {
+		super(trans, adao, months,range);
+	}
+
+	public Result<Void> exec(AuthzTrans trans, CredDAO.Data cdd) {
+		Result<Void> rv = null;
+		Result<List<CredDAO.Data>> read = q.credDAO.read(trans, cdd);
+		if(read.isOKhasData()) {
+			for(CredDAO.Data data : read.value) {
+				Date from = data.expires;
+				data.expires = puntDate();
+				if(data.expires.before(from)) {
+					trans.error().printf("Error: %s is before %s", Chrono.dateOnlyStamp(data.expires), Chrono.dateOnlyStamp(from));
+				} else {
+					rv = q.credDAO.update(trans, data);
+					trans.info().log("Updated Cred",cdd.id, CredPrint.type(cdd.type), "from",Chrono.dateOnlyStamp(from),"to",Chrono.dateOnlyStamp(data.expires));
+				}
+			}
+		}
+		if(rv==null) {
+			rv=Result.err(read);
+		}
+		return rv;
+	}
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/Email.java b/authz-batch/src/main/java/com/att/authz/actions/Email.java
new file mode 100644
index 0000000..df491df
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/Email.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization;
+
+public class Email implements Action<Organization,Void>{
+	protected final List<String> toList;
+	protected final List<String> ccList;
+	private final String[] defaultCC;
+	protected String subject;
+	private String preamble;
+	private Message msg;
+	private String sig;
+	protected String lineIndent="  ";
+
+	
+	public Email(String ... defaultCC) {
+		toList = new ArrayList<String>();
+		this.defaultCC = defaultCC;
+		ccList = new ArrayList<String>();
+		clear();
+	}
+	
+	public Email clear() {
+		toList.clear();
+		ccList.clear();
+		for(String s: defaultCC) {
+			ccList.add(s);
+		}
+		return this;
+	}
+	
+
+	public void indent(String indent) {
+		lineIndent = indent;
+	}
+	
+	public void preamble(String format, Object ... args) {
+		preamble = String.format(format, args);
+	}
+
+	public Email addTo(Collection<String> users) {
+		toList.addAll(users);
+		return this;
+	}
+
+	public Email addTo(String email) {
+		toList.add(email);
+		return this;
+	}
+	
+	
+	public Email subject(String format, Object ... args) {
+		subject = String.format(format, args);
+		return this;
+	}
+	
+	
+	public Email signature(String format, Object ... args) {
+		sig = String.format(format, args);
+		return this;
+	}
+	
+	public void msg(Message msg) {
+		this.msg = msg;
+	}
+	
+	@Override
+	public Result<Void> exec(AuthzTrans trans, Organization org) {
+		StringBuilder sb = new StringBuilder();
+		if(preamble!=null) {
+			sb.append(lineIndent);
+			sb.append(preamble);
+			sb.append("\n\n");
+		}
+		
+		if(msg!=null) {
+			msg.msg(sb,lineIndent);
+			sb.append("\n");
+		}
+
+		if(sig!=null) {
+			sb.append(sig);
+			sb.append("\n");
+		}
+
+		return exec(trans,org,sb);
+	}
+
+	protected Result<Void> exec(AuthzTrans trans, Organization org, StringBuilder sb) {
+		try {
+			/* int status = */
+			org.sendEmail(trans,
+				toList, 
+				ccList, 
+				subject, 
+				sb.toString(), 
+				false);
+		} catch (Exception e) {
+			return Result.err(Result.ERR_ActionNotCompleted,e.getMessage());
+		}
+		return Result.ok();
+
+	}
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/EmailPrint.java b/authz-batch/src/main/java/com/att/authz/actions/EmailPrint.java
new file mode 100644
index 0000000..5b356ce
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/EmailPrint.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.PrintStream;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization;
+
+public class EmailPrint extends Email {
+
+	public EmailPrint(String... defaultCC) {
+		super(defaultCC);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.att.authz.actions.Email#exec(com.att.authz.org.Organization, java.lang.StringBuilder)
+	 */
+	@Override
+	protected Result<Void> exec(AuthzTrans trans, Organization org, StringBuilder msg) {
+		PrintStream out = System.out;
+		boolean first = true;
+		out.print("To: ");
+		for(String s: toList) {
+			if(first) {first = false;}
+			else {out.print(',');}
+			out.print(s);
+		}
+		out.println();
+		
+		first = true;
+		out.print("CC: ");
+		for(String s: ccList) {
+			if(first) {first = false;}
+			else {out.print(',');}
+			out.print(s);
+		}
+		out.println();
+
+		out.print("Subject: ");
+		out.println(subject);
+		out.println();
+		
+		out.println(msg);
+		return Result.ok();
+
+	}
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/FADelete.java b/authz-batch/src/main/java/com/att/authz/actions/FADelete.java
new file mode 100644
index 0000000..b61ac7d
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/FADelete.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Future;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.ApprovalDAO;
+import com.att.dao.aaf.cass.FutureDAO;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class FADelete extends ActionDAO<Future,Void> {
+	public FADelete(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+		super(trans, cluster);
+	}
+	
+	public FADelete(AuthzTrans trans, ActionDAO<?,?> adao) {
+		super(trans, adao);
+	}
+
+	@Override
+	public Result<Void> exec(AuthzTrans trans, Future f) {
+		FutureDAO.Data fdd = new FutureDAO.Data();
+		fdd.id=f.id;
+		Result<Void> rv = q.futureDAO.delete(trans, fdd, true); // need to read for undelete
+		if(rv.isOK()) {
+			trans.info().log("Deleted:",f.id,f.memo,"expiring on",Chrono.dateOnlyStamp(f.expires));
+		} else {
+			trans.info().log("Failed to Delete Approval");
+		}
+		
+		Result<List<ApprovalDAO.Data>> ral = q.approvalDAO.readByTicket(trans, f.id);
+		if(ral.isOKhasData()) {
+			for(ApprovalDAO.Data add : ral.value) {
+				rv = q.approvalDAO.delete(trans, add, false);
+				if(rv.isOK()) {
+					trans.info().log("Deleted: Approval",add.id,"on ticket",add.ticket,"for",add.approver);
+				} else {
+					trans.info().log("Failed to Delete Approval");
+				}
+			}
+		}
+		return rv;
+	}
+	
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/FAPrint.java b/authz-batch/src/main/java/com/att/authz/actions/FAPrint.java
new file mode 100644
index 0000000..c2ec50a
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/FAPrint.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Future;
+import com.att.authz.layer.Result;
+import org.onap.aaf.inno.env.util.Chrono;
+
+public class FAPrint implements Action<Future,Void> {
+	private String text;
+
+	public FAPrint(String text) {
+		this.text = text;
+	}
+
+	@Override
+	public Result<Void> exec(AuthzTrans trans, Future f) {
+		trans.info().log(text,f.id,f.memo,"expiring on",Chrono.dateOnlyStamp(f.expires));
+		return Result.ok();
+	}
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/Key.java b/authz-batch/src/main/java/com/att/authz/actions/Key.java
new file mode 100644
index 0000000..89b7c6f
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/Key.java
@@ -0,0 +1,8 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+public interface Key<HELPER> {
+	public String key(HELPER H);
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/Message.java b/authz-batch/src/main/java/com/att/authz/actions/Message.java
new file mode 100644
index 0000000..2aca4ea
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/Message.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Message {
+	public final List<String> lines;
+		
+	public Message() {
+		lines = new ArrayList<String>();
+	}
+
+	public void clear() {
+		lines.clear();
+	}
+	
+	public void line(String format, Object ... args) {
+		lines.add(String.format(format, args));
+	}
+
+	public void msg(StringBuilder sb, String lineIndent) {
+		if(lines.size()>0) {
+			for(String line : lines) {
+				sb.append(lineIndent);
+				sb.append(line);
+				sb.append('\n');
+			}
+		}
+	}
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URAdd.java b/authz-batch/src/main/java/com/att/authz/actions/URAdd.java
new file mode 100644
index 0000000..fd3962f
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URAdd.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.UserRoleDAO;
+import com.att.dao.aaf.cass.UserRoleDAO.Data;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class URAdd extends ActionDAO<UserRole,UserRoleDAO.Data> {
+	public URAdd(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+		super(trans, cluster);
+	}
+	
+	public URAdd(AuthzTrans trans, ActionDAO<?,?> adao) {
+		super(trans, adao);
+	}
+
+	@Override
+	public Result<Data> exec(AuthzTrans trans, UserRole ur) {
+		UserRoleDAO.Data urd = new UserRoleDAO.Data();
+		urd.user = ur.user;
+		urd.role = ur.role;
+		urd.ns=ur.ns;
+		urd.rname = ur.rname;
+		urd.expires = ur.expires;
+		Result<Data> rv = q.userRoleDAO.create(trans, urd);
+		trans.info().log("Added:",ur.role,ur.user,"on",Chrono.dateOnlyStamp(ur.expires));
+		return rv;
+	}
+	
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URDelete.java b/authz-batch/src/main/java/com/att/authz/actions/URDelete.java
new file mode 100644
index 0000000..e3bd40a
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URDelete.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.UserRoleDAO;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class URDelete extends ActionDAO<UserRole,Void> {
+	public URDelete(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+		super(trans, cluster);
+	}
+	
+	public URDelete(AuthzTrans trans, ActionDAO<?,?> adao) {
+		super(trans, adao);
+	}
+
+	@Override
+	public Result<Void> exec(AuthzTrans trans, UserRole ur) {
+		UserRoleDAO.Data urd = new UserRoleDAO.Data();
+		urd.user = ur.user;
+		urd.role = ur.role;
+		Result<Void> rv = q.userRoleDAO.delete(trans, urd, true); // need to read for undelete
+		trans.info().log("Deleted:",ur.role,ur.user,"on",Chrono.dateOnlyStamp(ur.expires));
+		return rv;
+	}
+	
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URFutureApprove.java b/authz-batch/src/main/java/com/att/authz/actions/URFutureApprove.java
new file mode 100644
index 0000000..6af3e12
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URFutureApprove.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization.Expiration;
+import com.att.authz.org.Organization.Identity;
+import com.att.dao.aaf.cass.FutureDAO;
+import com.att.dao.aaf.cass.NsDAO;
+import com.att.dao.aaf.hl.Function;
+import com.att.dao.aaf.hl.Question;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class URFutureApprove extends ActionDAO<UserRole, List<Identity>> implements Action<UserRole,List<Identity>>, Key<UserRole> {
+	private final Date start, expires;
+
+	public URFutureApprove(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+		super(trans,cluster);
+		GregorianCalendar gc = new GregorianCalendar();
+		start = gc.getTime();
+		expires = trans.org().expiration(gc, Expiration.Future).getTime();
+	}
+	
+	public URFutureApprove(AuthzTrans trans, ActionDAO<?,?> adao) {
+		super(trans, adao);
+		GregorianCalendar gc = new GregorianCalendar();
+		start = gc.getTime();
+		expires = trans.org().expiration(gc, Expiration.Future).getTime();
+	}
+
+	@Override
+	public Result<List<Identity>> exec(AuthzTrans trans, UserRole ur) {
+		Result<NsDAO.Data> rns = q.deriveNs(trans, ur.ns);
+		if(rns.isOK()) {
+			
+			FutureDAO.Data data = new FutureDAO.Data();
+			data.id=null; // let Create function assign UUID
+			data.target=Function.FOP_USER_ROLE;
+			
+			data.memo = key(ur);
+			data.start = start;
+			data.expires = expires;
+			try {
+				data.construct = ur.to().bytify();
+			} catch (IOException e) {
+				return Result.err(e);
+			}
+			Result<List<Identity>> rapprovers = f.createFuture(trans, data, Function.FOP_USER_ROLE, ur.user, rns.value, "U");
+			return rapprovers;
+		} else {
+			return Result.err(rns);
+		}
+	}
+	
+	@Override
+	public String key(UserRole ur) {
+		String expire;
+		if(expires.before(start)) {
+			expire = "' - EXPIRED ";
+		} else {
+			expire = "' - expiring ";
+		}
+		
+		if(Question.OWNER.equals(ur.rname)) {
+			return "Re-Validate Ownership for AAF Namespace '" + ur.ns + expire + Chrono.dateOnlyStamp(ur.expires);
+		} else if(Question.ADMIN.equals(ur.rname)) {
+			return "Re-Validate as Administrator for AAF Namespace '" + ur.ns + expire + Chrono.dateOnlyStamp(ur.expires);
+		} else {
+			return "Re-Approval in Role '" + ur.role + expire + Chrono.dateOnlyStamp(ur.expires);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URFuturePrint.java b/authz-batch/src/main/java/com/att/authz/actions/URFuturePrint.java
new file mode 100644
index 0000000..ea5a8bf
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URFuturePrint.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization.Identity;
+import org.onap.aaf.inno.env.util.Chrono;
+
+
+public class URFuturePrint implements  Action<UserRole,List<Identity>> {
+	private String text;
+	private final static List<Identity> rv = new ArrayList<Identity>();
+
+	public URFuturePrint(String text) {
+		this.text = text;
+	}
+
+	@Override
+	public Result<List<Identity>> exec(AuthzTrans trans, UserRole ur) {
+		trans.info().log(text,ur.user,"to",ur.role,"on",Chrono.dateOnlyStamp(ur.expires));
+		return Result.ok(rv);
+	}}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URPrint.java b/authz-batch/src/main/java/com/att/authz/actions/URPrint.java
new file mode 100644
index 0000000..8092567
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URPrint.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import org.onap.aaf.inno.env.util.Chrono;
+
+public class URPrint implements Action<UserRole,Void> {
+	private String text;
+
+	public URPrint(String text) {
+		this.text = text;
+	}
+
+	@Override
+	public Result<Void> exec(AuthzTrans trans, UserRole ur) {
+		trans.info().log(text,ur.user,"to",ur.role,"expiring on",Chrono.dateOnlyStamp(ur.expires));
+		return Result.ok();
+	}
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URPunt.java b/authz-batch/src/main/java/com/att/authz/actions/URPunt.java
new file mode 100644
index 0000000..e76852f
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URPunt.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.UserRoleDAO;
+import com.att.dao.aaf.cass.UserRoleDAO.Data;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class URPunt extends ActionPuntDAO<UserRole,Void> {
+	public URPunt(AuthzTrans trans, Cluster cluster, int months, int range) throws APIException, IOException {
+		super(trans,cluster, months, range);
+	}
+
+	public URPunt(AuthzTrans trans, ActionDAO<?,?> adao, int months, int range) {
+		super(trans, adao, months, range);
+	}
+
+	public Result<Void> exec(AuthzTrans trans, UserRole ur) {
+		Result<List<Data>> read = q.userRoleDAO.read(trans, ur.user, ur.role);
+		if(read.isOK()) {
+			for(UserRoleDAO.Data data : read.value) {
+				Date from = data.expires;
+				data.expires = puntDate();
+				if(data.expires.before(from)) {
+					trans.error().printf("Error: %s is before %s", Chrono.dateOnlyStamp(data.expires), Chrono.dateOnlyStamp(from));
+				} else {
+					q.userRoleDAO.update(trans, data);
+					trans.info().log("Updated User",ur.user,"and Role", ur.role, "from",Chrono.dateOnlyStamp(from),"to",Chrono.dateOnlyStamp(data.expires));
+				}
+			}
+			return Result.ok();
+		} else {
+			return Result.err(read);
+		}
+	}
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/AafEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/AafEntryConverter.java
new file mode 100644
index 0000000..4f05f20
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/AafEntryConverter.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import java.util.Set;
+
+public abstract class AafEntryConverter {
+
+	protected String formatSet(Set<String> set) {
+		if (set==null || set.isEmpty()) return "";
+		StringBuilder sb = new StringBuilder();
+		int curr = 0;
+		sb.append("{");
+		for (String s : set) {
+			sb.append("'");
+			sb.append(s);
+			sb.append("'");
+			if (set.size() != curr + 1) {
+				sb.append(",");
+			}
+			curr++;
+		}
+		sb.append("}");
+		return sb.toString();
+	}
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/CredEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/CredEntryConverter.java
new file mode 100644
index 0000000..96c8812
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/CredEntryConverter.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import com.att.dao.aaf.cass.CredDAO;
+import com.datastax.driver.core.utils.Bytes;
+import com.googlecode.jcsv.writer.CSVEntryConverter;
+
+public class CredEntryConverter extends AafEntryConverter implements CSVEntryConverter<CredDAO.Data> {
+	private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ssZ";
+	
+	@Override
+	public String[] convertEntry(CredDAO.Data cd) {
+		String[] columns = new String[5];
+		
+		columns[0] = cd.id;
+		columns[1] = String.valueOf(cd.type);
+		DateFormat df = new SimpleDateFormat(DATE_FORMAT);
+		columns[2] = df.format(cd.expires);
+		columns[3] = Bytes.toHexString(cd.cred);
+		columns[4] = (cd.ns==null)?"":cd.ns;
+		
+		return columns;
+	}
+}
diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/NsEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/NsEntryConverter.java
new file mode 100644
index 0000000..e9cd91c
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/NsEntryConverter.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import com.att.dao.aaf.cass.NsDAO;
+import com.googlecode.jcsv.writer.CSVEntryConverter;
+
+public class NsEntryConverter extends AafEntryConverter implements CSVEntryConverter<NsDAO.Data> {
+
+	@Override
+	public String[] convertEntry(NsDAO.Data nsd) {
+		String[] columns = new String[5];
+		
+		columns[0] = nsd.name;
+		// JG changed from "scope" to "type"
+		columns[1] = String.valueOf(nsd.type);
+		//TODO Chris: need to look at this 
+//		columns[2] = formatSet(nsd.admin);
+//		columns[3] = formatSet(nsd.responsible);
+//		columns[4] = nsd.description==null?"":nsd.description;
+		columns[5] = nsd.description==null?"":nsd.description;
+		
+		return columns;
+	}
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/PermEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/PermEntryConverter.java
new file mode 100644
index 0000000..afabdfd
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/PermEntryConverter.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import com.att.dao.aaf.cass.PermDAO;
+import com.googlecode.jcsv.writer.CSVEntryConverter;
+
+public class PermEntryConverter extends AafEntryConverter implements CSVEntryConverter<PermDAO.Data>  {
+
+		@Override
+		public String[] convertEntry(PermDAO.Data pd) {
+			String[] columns = new String[6];
+			
+			columns[0] = pd.ns;
+			columns[1] = pd.type;
+			columns[2] = pd.instance;
+			columns[3] = pd.action;
+			columns[4] = formatSet(pd.roles);
+			columns[5] = pd.description==null?"":pd.description;
+			
+			return columns;
+		}
+}
diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/RoleEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/RoleEntryConverter.java
new file mode 100644
index 0000000..51389bd
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/RoleEntryConverter.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import com.att.dao.aaf.cass.RoleDAO;
+import com.googlecode.jcsv.writer.CSVEntryConverter;
+
+public class RoleEntryConverter extends AafEntryConverter implements CSVEntryConverter<RoleDAO.Data>  {
+
+	@Override
+	public String[] convertEntry(RoleDAO.Data rd) {
+		String[] columns = new String[4];
+		
+		columns[0] = rd.ns;
+		columns[1] = rd.name;
+		columns[2] = formatSet(rd.perms);
+		columns[3] = rd.description==null?"":rd.description;
+		
+		return columns;
+	}
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/UserRoleEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/UserRoleEntryConverter.java
new file mode 100644
index 0000000..0b2a956
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/UserRoleEntryConverter.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import com.att.dao.aaf.cass.UserRoleDAO;
+import com.googlecode.jcsv.writer.CSVEntryConverter;
+
+public class UserRoleEntryConverter extends AafEntryConverter implements CSVEntryConverter<UserRoleDAO.Data> {
+	private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ssZ";
+	
+	@Override
+	public String[] convertEntry(UserRoleDAO.Data urd) {
+		String[] columns = new String[3];
+		
+		columns[0] = urd.user;
+		columns[1] = urd.role;
+		DateFormat df = new SimpleDateFormat(DATE_FORMAT);
+		columns[2] = df.format(urd.expires);
+		
+		return columns;
+	}
+}
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Approver.java b/authz-batch/src/main/java/com/att/authz/helpers/Approver.java
new file mode 100644
index 0000000..0cac97b
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Approver.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.att.authz.actions.Message;
+import com.att.authz.org.Organization;
+
+public class Approver {
+	public String name;
+	public Organization org;
+	public Map<String, Integer> userRequests;
+	
+	public Approver(String approver, Organization org) {
+		this.name = approver;
+		this.org = org;
+		userRequests = new HashMap<String, Integer>();
+	}
+	
+	public void addRequest(String user) {
+		if (userRequests.get(user) == null) {
+		    userRequests.put(user, 1);
+		} else {
+			Integer curCount = userRequests.remove(user);
+			userRequests.put(user, curCount+1);
+		}
+	}
+	
+	/**
+	 * @param sb
+	 * @return
+	 */
+	public void build(Message msg) {
+		msg.clear();
+		msg.line("You have %d total pending approvals from the following users:", userRequests.size());
+		for (Map.Entry<String, Integer> entry : userRequests.entrySet()) {
+			msg.line("  %s (%d)",entry.getKey(),entry.getValue());
+		}
+	}
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Creator.java b/authz-batch/src/main/java/com/att/authz/helpers/Creator.java
new file mode 100644
index 0000000..1fe513e
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Creator.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import com.datastax.driver.core.Row;
+
+public abstract class Creator<T> {
+	public abstract T create(Row row);
+	public abstract String select();
+	
+	public String query(String where) {
+		StringBuilder sb = new StringBuilder(select());
+		if(where!=null) {
+			sb.append(" WHERE ");
+			sb.append(where);
+		}
+		sb.append(';');
+		return sb.toString();
+	}
+
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Cred.java b/authz-batch/src/main/java/com/att/authz/helpers/Cred.java
new file mode 100644
index 0000000..a7717ae
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Cred.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Cred  {
+    public static final TreeMap<String,Cred> data = new TreeMap<String,Cred>();
+
+	public final String id;
+	public final List<Instance> instances;
+	
+	public Cred(String id) {
+		this.id = id;
+		instances = new ArrayList<Instance>();
+	}
+	
+	public static class Instance {
+		public final int type;
+		public final Date expires;
+		public final Integer other;
+		
+		public Instance(int type, Date expires, Integer other) {
+			this.type = type;
+			this.expires = expires;
+			this.other = other;
+		}
+	}
+	
+	public Date last(final int type) {
+		Date last = null;
+		for(Instance i : instances) {
+			if(i.type==type && (last==null || i.expires.after(last))) {
+				last = i.expires;
+			}
+		}
+		return last;
+	}
+
+	
+	public Set<Integer> types() {
+		Set<Integer> types = new HashSet<Integer>();
+		for(Instance i : instances) {
+			types.add(i.type);
+		}
+		return types;
+	}
+
+	public static void load(Trans trans, Session session ) {
+		load(trans, session,"select id, type, expires, other from authz.cred;");
+		
+	}
+
+	public static void loadOneNS(Trans trans, Session session, String ns ) {
+		load(trans, session,"select id, type, expires, other from authz.cred WHERE ns='" + ns + "';");
+	}
+
+	private static void load(Trans trans, Session session, String query) {
+
+        trans.info().log( "query: " + query );
+        TimeTaken tt = trans.start("Read Creds", Env.REMOTE);
+       
+        ResultSet results;
+		try {
+	        Statement stmt = new SimpleStatement( query );
+	        results = session.execute(stmt);
+        } finally {
+        	tt.done();
+        }
+		int count = 0;
+        try {
+	        Iterator<Row> iter = results.iterator();
+	        Row row;
+	        tt = trans.start("Load Roles", Env.SUB);
+	        try {
+		        while(iter.hasNext()) {
+		        	++count;
+		        	row = iter.next();
+		        	String id = row.getString(0);
+		        	Cred cred = data.get(id);
+		        	if(cred==null) {
+		        		cred = new Cred(id);
+		        		data.put(id, cred);
+		        	}
+		        	cred.instances.add(new Instance(row.getInt(1), row.getDate(2), row.getInt(3)));
+		        }
+	        } finally {
+	        	tt.done();
+	        }
+        } finally {
+        	trans.info().log("Found",count,"creds");
+        }
+
+
+	}
+	public String toString() {
+		StringBuilder sb = new StringBuilder(id);
+		sb.append('[');
+		for(Instance i : instances) {
+			sb.append('{');
+			sb.append(i.type);
+			sb.append(",\"");
+			sb.append(i.expires);
+			sb.append("\"}");
+		}
+		sb.append(']');
+		return sb.toString();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		return id.hashCode();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		return id.equals(obj);
+	}
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Future.java b/authz-batch/src/main/java/com/att/authz/helpers/Future.java
new file mode 100644
index 0000000..d658535
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Future.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Future {
+	public static final List<Future> data = new ArrayList<Future>();
+	public static final TreeMap<String,List<Future>> byMemo = new TreeMap<String,List<Future>>();
+	
+	public final UUID id;
+	public final String memo, target;
+	public final Date start, expires;
+	public Future(UUID id, String memo, String target, Date start, Date expires) {
+		this.id = id;
+		this.memo = memo;
+		this.target = target;
+		this.start = start;
+		this.expires = expires;
+	}
+
+	public static void load(Trans trans, Session session, Creator<Future> creator) {
+		trans.info().log( "query: " + creator.select() );
+		ResultSet results;
+		TimeTaken tt = trans.start("Load Futures", Env.REMOTE);
+		try {
+	        Statement stmt = new SimpleStatement(creator.select());
+	        results = session.execute(stmt);
+		} finally {
+			tt.done();
+		}
+		
+		int count = 0;
+		tt = trans.start("Process Futures", Env.SUB);
+		try {
+        	for(Row row : results.all()) {
+        		++count;
+        		Future f = creator.create(row);
+        		data.add(f);
+        		
+        		List<Future> lf = byMemo.get(f.memo);
+        		if(lf == null) {
+        			lf = new ArrayList<Future>();
+        			byMemo.put(f.memo, lf);
+        		}
+        		lf.add(f);
+        		
+        	}
+		} finally {
+			trans.info().log("Found",count,"Futures");
+		}
+	}
+	
+	public static Creator<Future> v2_0_15 = new Creator<Future>() {
+		@Override
+		public Future create(Row row) {
+			return new Future(row.getUUID(0),row.getString(1),row.getString(2),
+					row.getDate(3),row.getDate(4));
+		}
+
+		@Override
+		public String select() {
+			return "select id,memo,target,start,expires from authz.future";
+		}
+	};
+	
+	public static void delete(List<Future> fl) {
+		if(fl==null || fl.isEmpty()) {
+			return;
+		}
+		for(Future f : fl) {
+			data.remove(f);
+		}
+		// Faster to start over, then look for entries.
+		byMemo.clear();
+		for(Future f : data) {
+			List<Future> lf = byMemo.get(f.memo);
+			if(lf == null) {
+				lf = new ArrayList<Future>();
+				byMemo.put(f.memo, lf);
+			}
+			lf.add(f);
+		}
+	}
+}
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/InputIterator.java b/authz-batch/src/main/java/com/att/authz/helpers/InputIterator.java
new file mode 100644
index 0000000..02fdc16
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/InputIterator.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Iterator;
+
+public class InputIterator implements Iterable<String> {
+	private BufferedReader in;
+	private final PrintStream out;
+	private final String prompt, instructions;
+	
+	public InputIterator(BufferedReader in, PrintStream out, String prompt, String instructions) {
+		this.in = in;
+		this.out = out;
+		this.prompt = prompt;
+		this.instructions = instructions;
+	}
+	
+	@Override
+	public Iterator<String> iterator() {
+		out.println(instructions);
+		return new Iterator<String>() {
+			String input;
+			@Override
+			public boolean hasNext() {
+				out.append(prompt);
+				try {
+					input = in.readLine();
+				} catch (IOException e) {
+					input = null;
+					return false;
+				}
+				return input.length()>0;
+			}
+
+			@Override
+			public String next() {
+				return input;
+			}
+
+			@Override
+			public void remove() {
+			}
+		};
+	}
+}
+
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/MiscID.java b/authz-batch/src/main/java/com/att/authz/helpers/MiscID.java
new file mode 100644
index 0000000..b553009
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/MiscID.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.att.authz.BatchException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class MiscID  {
+	public static final TreeMap<String,MiscID> data = new TreeMap<String,MiscID>();
+	/*
+	Sample Record
+	aad890|mj9030|20040902|20120207
+
+	**** Field Definitions ****
+	MISCID - AT&T Miscellaneous ID - Non-User ID (Types: Internal Mechanized ID, External Mechanized ID, Datagate ID, Customer ID, Vendor ID, Exchange Mail ID, CLEC ID, Specialized ID, Training ID)
+	SPONSOR_ATTUID - ATTUID of MiscID Sponsor (Owner)
+	CREATE_DATE - Date when MiscID was created 
+	LAST_RENEWAL_DATE - Date when MiscID Sponsorship was last renewed
+	*/
+	public String id,sponsor,created,renewal;
+
+	private static final String fieldString = "id,created,sponsor,renewal";
+	
+	/**
+	 * Load a Row of Strings (from CSV file).
+	 * 
+	 * Be CAREFUL that the Row lists match the Fields above!!!  If this changes, change
+	 * 1) This Object
+	 * 2) DB "suits.cql"
+	 * 3) Alter existing Tables
+	 * @param row
+	 * @throws BatchException 
+	 * @throws IllegalAccessException 
+	 * @throws IllegalArgumentException 
+	 */
+	public void set(String row []) throws BatchException {
+		if(row.length<4) {throw new BatchException("Row of MiscID_XRef is too short");}
+		id      = row[0];
+		sponsor = row[1];
+		created = row[2];
+		renewal = row[3];
+	}
+
+	public void set(Row row) {
+		id      = row.getString(0);
+		sponsor = row.getString(1);
+		created = row.getString(2);
+		renewal = row.getString(3);
+	}
+	
+
+	public static void load(Trans trans, Session session ) {
+		load(trans, session,"SELECT " + fieldString + " FROM authz.miscid;",data);
+	}
+
+	public static void load(Trans trans, Session session, Map<String,MiscID> map ) {
+		load(trans, session,"SELECT " + fieldString + " FROM authz.miscid;",map);
+	}
+
+	public static void loadOne(Trans trans, Session session, String id ) {
+		load(trans, session,"SELECT " + fieldString + " FROM authz.miscid WHERE id ='" + id + "';", data);
+	}
+
+	public static void load(Trans trans, Session session, String query, Map<String,MiscID> map) {
+        trans.info().log( "query: " + query );
+        TimeTaken tt = trans.start("Read MiscID", Env.REMOTE);
+       
+        ResultSet results;
+		try {
+	        Statement stmt = new SimpleStatement( query );
+	        results = session.execute(stmt);
+        } finally {
+        	tt.done();
+        }
+		int count = 0;
+        try {
+	        tt = trans.start("Load Map", Env.SUB);
+	        try {
+	        	for( Row row : results.all()) {
+		        	MiscID miscID = new MiscID();
+		        	miscID.set(row);
+		        	data.put(miscID.id,miscID);
+		        	++count;
+		        }
+			} finally {
+	        	tt.done();
+	        }
+        } finally {
+        	trans.info().log("Found",count,"miscID records");
+        }
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		return id.hashCode();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if(obj!=null && obj instanceof MiscID) {
+			return id.equals(((MiscID)obj).id);
+		}
+		return false;
+	}
+
+	public StringBuilder insertStmt() throws IllegalArgumentException, IllegalAccessException {
+		StringBuilder sb = new StringBuilder("INSERT INTO authz.miscid (");
+		sb.append(fieldString);
+		sb.append(") VALUES ('");
+		sb.append(id);
+		sb.append("','");
+		sb.append(sponsor);
+		sb.append("','");
+		sb.append(created);
+		sb.append("','");
+		sb.append(renewal);
+		sb.append("')");
+		return sb;
+	}
+	
+	public StringBuilder updateStmt(MiscID source) {
+		StringBuilder sb = null;
+		if(id.equals(source.id)) {
+			sb = addField(sb,"sponser",sponsor,source.sponsor);
+			sb = addField(sb,"created",created,source.created);
+			sb = addField(sb,"renewal",renewal,source.renewal);
+		}
+		if(sb!=null) {
+			sb.append(" WHERE id='");
+			sb.append(id);
+			sb.append('\'');
+		}
+		return sb;
+	}
+
+	private StringBuilder addField(StringBuilder sb, String name, String a, String b) {
+		if(!a.equals(b)) {
+			if(sb==null) {
+				sb = new StringBuilder("UPDATE authz.miscid SET ");		
+			} else {
+				sb.append(',');
+			}
+			sb.append(name);
+			sb.append("='");
+			sb.append(b);
+			sb.append('\'');
+		}
+		return sb;
+	}
+
+		
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/NS.java b/authz-batch/src/main/java/com/att/authz/helpers/NS.java
new file mode 100644
index 0000000..f8c5975
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/NS.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class NS implements Comparable<NS> {
+	public final static Map<String,NS> data = new TreeMap<String,NS>();
+
+	public final String name, description, parent;
+	public final int scope,type;
+
+	public NS(String name, String description, String parent, int type, int scope) {
+		this.name = name;
+		this.description = description;
+		this.parent = parent;
+		this.scope = scope;
+		this.type = type;
+	}
+	
+	public static void load(Trans trans, Session session, Creator<NS> creator) {
+		load(trans,session,
+				"select name, description, parent, type, scope from authz.ns;"
+				,creator);
+	}
+	
+	public static void loadOne(Trans trans, Session session, Creator<NS> creator, String ns) {
+	    load(trans,session,
+				("select name, description, parent, type, scope from authz.ns WHERE name='"+ns+"';")
+				,creator
+				);
+	}
+
+	private static void load(Trans trans, Session session, String query, Creator<NS> creator) {
+        trans.info().log( "query: " + query );
+        ResultSet results;
+        TimeTaken tt;
+
+        tt = trans.start("Read Namespaces", Env.REMOTE);
+        try {
+	        Statement stmt = new SimpleStatement( query );
+	        results = session.execute(stmt);
+        } finally {
+        	tt.done();
+        }
+        
+
+        try {
+	        Iterator<Row> iter = results.iterator();
+	        Row row;
+	        tt = trans.start("Load Namespaces", Env.SUB);
+	        try {
+		        while(iter.hasNext()) {
+		        	row = iter.next();
+		        	NS ns = creator.create(row);
+		        	data.put(ns.name,ns);
+		        }
+	        } finally {
+	        	tt.done();
+	        }
+        } finally {
+        	trans.info().log("Found",data.size(),"Namespaces");
+        }
+
+	}
+
+	public String toString() {
+		return name;
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		return name.hashCode();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		return name.equals(obj);
+	}
+
+	@Override
+	public int compareTo(NS o) {
+		return name.compareTo(o.name);
+	}
+	
+	public static class NSSplit {
+		public String ns;
+		public String other;
+		public NSSplit(String s, int dot) {
+			ns = s.substring(0,dot);
+			other = s.substring(dot+1);
+		}
+	}
+	public static NSSplit deriveParent(String dotted) {
+		if(dotted==null)return null;
+		for(int idx = dotted.lastIndexOf('.');idx>=0; idx=dotted.lastIndexOf('.',idx-1)) {
+			if(data.get(dotted.substring(0, idx))!=null) {
+				return new NSSplit(dotted,idx);
+			}
+		}
+		return null;
+	}
+	
+	public static Creator<NS> v2_0_11 = new Creator<NS> () {
+		@Override
+		public NS create(Row row) {
+			return new NS(row.getString(0),row.getString(1), row.getString(2),row.getInt(3),row.getInt(4));
+		}
+		
+		@Override
+		public String select() {
+			return "SELECT name, description, parent, type, scope FROM authz.ns ";
+		}
+	};
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Notification.java b/authz-batch/src/main/java/com/att/authz/helpers/Notification.java
new file mode 100644
index 0000000..501edfa
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Notification.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TreeMap;
+
+import com.att.authz.actions.Message;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.org.EmailWarnings;
+import com.att.authz.org.Organization;
+import com.att.authz.org.Organization.Notify;
+import com.att.authz.org.Organization.Identity;
+import com.att.authz.org.OrganizationException;
+import com.att.authz.org.OrganizationFactory;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Notification {
+	
+    public static final TreeMap<String,List<Notification>> data = new TreeMap<String,List<Notification>>();
+    public static final long now = System.currentTimeMillis();
+    
+    public final String user;
+	public final Notify type;
+	public final Date last;
+	public final int checksum;
+	public Message msg;
+	private int current;
+	public Organization org;
+	public int count;
+	private long graceEnds,lastdays;
+	
+	private Notification(String user, int type, Date last, int checksum) {
+		this.user = user;
+		this.type = Notify.from(type);
+		this.last = last;
+		this.checksum = checksum;
+		current = 0;
+		count = 0;
+	}
+	
+	private Notification(String user, Notify type, Date last, int checksum) {
+		this.user = user;
+		this.type = type;
+		this.last = last;
+		this.checksum = checksum;
+		current = 0;
+		count = 0;
+	}
+	
+	public static void load(Trans trans, Session session, Creator<Notification> creator ) {
+		trans.info().log( "query: " + creator.select() );
+        TimeTaken tt = trans.start("Load Notify", Env.REMOTE);
+       
+        ResultSet results;
+		try {
+	        Statement stmt = new SimpleStatement(creator.select());
+	        results = session.execute(stmt);
+        } finally {
+        	tt.done();
+        }
+		int count = 0;
+        tt = trans.start("Process Notify", Env.SUB);
+
+        try {
+        	for(Row row : results.all()) {
+        		++count;
+		        try {
+		        	Notification not = creator.create(row);
+		        	List<Notification> ln = data.get(not.user);
+		        	if(ln==null) {
+		        		ln = new ArrayList<Notification>();
+		        		data.put(not.user, ln);
+		        	}
+		        	ln.add(not);
+		        } finally {
+		        	tt.done();
+		        }
+        	}
+        } finally {
+        	tt.done();
+        	trans.info().log("Found",count,"Notify Records");
+        }
+	}
+	
+	public static Notification get(String user, Notify type) {
+		List<Notification> ln = data.get(user);
+		if(ln!=null) {
+	    	for(Notification n : ln) {
+	    		if(type.equals(n.type)) {
+	    			return n;
+	    		}
+	    	}
+		}
+		return null;
+	}
+
+	private static Notification getOrCreate(String user, Notify type) {
+		List<Notification> ln = data.get(user);
+		Notification n = null;
+		if(ln==null) {
+			ln = new ArrayList<Notification>();
+			data.put(user, ln);
+		} else {
+			for(Notification n2 : ln) {
+	    		if(type.equals(n2.type)) {
+	    			n=n2;
+	    			break;
+	    		}
+	    	}
+		}
+		if(n==null) {
+			n = new Notification(user, type, new Date(), 0);
+			ln.add(n);
+		}
+		return n;
+	}
+	
+	public static Notification add(AuthzTrans trans, UserRole ur) {
+		Notification n = getOrCreate(ur.user,Notify.RoleExpiration);
+		if(n.org==null) {
+			try {
+				n.org = OrganizationFactory.obtain(trans.env(), ur.ns);
+			} catch (OrganizationException e) {
+				trans.error().log(ur.ns, " does not have a Namespace");
+			}
+		}
+		
+		if(n.count==0) {
+			EmailWarnings ew = n.org.emailWarningPolicy();
+			n.graceEnds = ew.roleEmailInterval();
+			n.lastdays = ew.emailUrgentWarning();
+		}
+		++n.count;
+
+		/*
+		StringBuilder sb = new StringBuilder();
+		sb.append("ID: ");
+		sb.append(ur.user);
+		User ouser;
+		try {
+			ouser = n.org.getUser(trans, ur.user);
+			if(ouser!=null) {
+				sb.append(" (");
+				sb.append(ouser.fullName());
+				sb.append(')');
+			}
+		} catch (Exception e) {
+		}
+		sb.append("  Role: ");
+		sb.append(ur.role);
+		sb.append("  Expire");
+		if(now<ur.expires.getTime()) {
+			sb.append("s: ");
+		} else {
+			sb.append("d: ");
+		}
+		sb.append(Chrono.dateOnlyStamp(ur.expires));
+		sb.append("\n  If you wish to extend, type\n");
+		sb.append("\trole user extend ");
+		sb.append(ur.role);
+		sb.append(' ');
+		sb.append(ur.user);
+		sb.append("\n  If you wish to delete, type\n");
+		sb.append("\trole user del ");
+		sb.append(ur.role);
+		sb.append(' ');
+		sb.append(ur.user);
+		sb.append('\n');
+		n.msg.add(sb.toString());
+		n.current=0;
+		*/
+		return n;
+	}
+
+	public static Notification addApproval(AuthzTrans trans, Identity ou) {
+		Notification n = getOrCreate(ou.id(),Notify.Approval);
+		if(n.org==null) {
+			n.org = ou.org();
+		}
+		if(n.count==0) { // first time.
+			EmailWarnings ew = n.org.emailWarningPolicy();
+			n.graceEnds = ew.apprEmailInterval();
+			n.lastdays = ew.emailUrgentWarning();
+		}
+		++n.count;
+		return n;
+	}
+
+	public static Creator<Notification> v2_0_14 = new Creator<Notification>() {
+		@Override
+		public Notification create(Row row) {
+			return new Notification(row.getString(0), row.getInt(1), row.getDate(2),row.getInt(3));
+		}
+
+		@Override
+		public String select() {
+			return "select user,type,last,checksum from authz.notify";
+		}
+	};
+
+	public void set(Message msg) {
+		this.msg = msg; 
+	}
+
+	public int checksum() {
+		if(current==0) {
+			for(String l : msg.lines) {
+				for(byte b : l.getBytes()) {
+					current+=b;
+				}
+			}
+		}
+		return current;
+	}
+	
+	public boolean update(AuthzTrans trans, Session session, boolean dryRun) {
+		String update = update();
+		if(update!=null) {
+			if(dryRun) {
+				trans.info().log(update);
+			} else {
+				session.execute(update);
+			}
+			return true; // Updated info, expect to notify
+		}
+		return false;
+	}
+
+	/** 
+	 * Returns an Update String for CQL if there is data.
+	 * 
+	 * Returns null if nothing to update
+	 * @return
+	 */
+	private String update() {
+		// If this has been done before, there is no change in checkSum and the last time notified is within GracePeriod
+		if(checksum!=0 && checksum()==checksum && now < last.getTime()+graceEnds && now > last.getTime()+lastdays) {
+			return null;
+		} else {
+			return "UPDATE authz.notify SET last = '" +
+					Chrono.dateOnlyStamp(last) +
+					"', checksum=" +
+					current +
+					" WHERE user='" +
+					user + 
+					"' AND type=" +
+					type.getValue() +
+					";";
+		}
+	}
+
+//	public void text(Email email) {
+//		for(String s : msg) {
+//			email.line(s);
+//		}
+//	}
+//
+	public String toString() {
+		return "\"" + user + "\",\"" + type.name() + "\",\""  + Chrono.dateOnlyStamp(last);
+	}
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/NsAttrib.java b/authz-batch/src/main/java/com/att/authz/helpers/NsAttrib.java
new file mode 100644
index 0000000..fa0bd28
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/NsAttrib.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class NsAttrib  {
+	public static final List<NsAttrib> data = new ArrayList<NsAttrib>();
+    public static final TreeMap<String,List<NsAttrib>> byKey = new TreeMap<String,List<NsAttrib>>();
+    public static final TreeMap<String,List<NsAttrib>> byNS = new TreeMap<String,List<NsAttrib>>();
+
+	public final String ns,key,value;
+	
+	public NsAttrib(String ns, String key, String value) {
+		this.ns = ns;
+		this.key = key;
+		this.value = value;
+	}
+	
+	public static void load(Trans trans, Session session, Creator<NsAttrib> creator ) {
+		trans.info().log( "query: " + creator.select() );
+        ResultSet results;
+        TimeTaken tt = trans.start("Load NsAttributes", Env.REMOTE);
+		try {
+	        Statement stmt = new SimpleStatement(creator.select());
+	        results = session.execute(stmt);
+        } finally {
+        	tt.done();
+        }
+		int count = 0;
+        tt = trans.start("Process NsAttributes", Env.SUB);
+
+        try {
+        	for(Row row : results.all()) {
+        		++count;
+	        	NsAttrib ur = creator.create(row);
+	        	data.add(ur);
+	        	
+	        	List<NsAttrib> lna = byKey.get(ur.key);
+	        	if(lna==null) {
+	        		lna = new ArrayList<NsAttrib>();
+		        	byKey.put(ur.key, lna);
+	        	}
+	        	lna.add(ur);
+	        	
+	        	lna = byNS.get(ur.ns);
+	        	if(lna==null) {
+	        		lna = new ArrayList<NsAttrib>();
+		        	byNS.put(ur.ns, lna);
+	        	}
+	        	lna.add(ur);
+        	}
+        } finally {
+        	tt.done();
+        	trans.info().log("Found",count,"NS Attributes");
+        }
+	}
+
+	public static Creator<NsAttrib> v2_0_11 = new Creator<NsAttrib>() {
+		@Override
+		public NsAttrib create(Row row) {
+			return new NsAttrib(row.getString(0), row.getString(1), row.getString(2));
+		}
+
+		@Override
+		public String select() {
+			return "select ns,key,value from authz.ns_attrib";
+		}
+	};
+
+
+	public String toString() {
+		return "\"" + ns + "\",\"" + key + "\",\""  + value;
+	}
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Perm.java b/authz-batch/src/main/java/com/att/authz/helpers/Perm.java
new file mode 100644
index 0000000..41c41a8
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Perm.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Perm implements Comparable<Perm> {
+    public static final TreeMap<Perm,Set<String>> data = new TreeMap<Perm,Set<String>>();
+    public static final TreeMap<String,Perm> keys = new TreeMap<String,Perm>();
+
+	public final String ns, type, instance, action,description;
+	private String fullType = null, fullPerm = null, encode = null;
+	public final Set<String> roles;
+	
+	public String encode() {
+		if(encode == null) {
+			encode = ns + '|' + type + '|' + instance + '|' + action;
+		}
+		return encode;
+	}
+	
+	public String fullType() {
+		if(fullType==null) {
+			fullType = ns + '.' + type;
+		}
+		return fullType;
+	}
+	
+	public String fullPerm() {
+		if(fullPerm==null) {
+			fullPerm = ns + '.' + type  + '|' + instance + '|' + action;
+		}
+		return fullPerm;
+	}
+	
+	public Perm(String ns, String type, String instance, String action, String description, Set<String> roles) {
+		this.ns = ns;
+		this.type = type;
+		this.instance = instance;
+		this.action = action;
+		this.description = description;
+		// 2.0.11
+//		this.full = encode();//ns+'.'+type+'|'+instance+'|'+action;
+		this.roles = roles;
+	}
+
+	public static void load(Trans trans, Session session) {
+        load(trans, session, "select ns, type, instance, action, description, roles from authz.perm;");
+	}
+	
+	public static void loadOneNS(Trans trans, Session session, String ns) {
+        load(trans, session, "select ns, type, instance, action, description, roles from authz.perm WHERE ns='" + ns + "';");
+        
+	}
+
+	private static void load(Trans trans, Session session, String query) {
+        //
+        trans.info().log( "query: " + query );
+        TimeTaken tt = trans.start("Read Perms", Env.REMOTE);
+        ResultSet results;
+		try {
+	        Statement stmt = new SimpleStatement( query );
+	        results = session.execute(stmt);
+        } finally {
+        	tt.done();
+        }
+
+        try {
+	        Iterator<Row> iter = results.iterator();
+	        Row row;
+	        tt = trans.start("Load Perms", Env.SUB);
+	        try {
+		        while(iter.hasNext()) {
+		        	row = iter.next();
+		        	Perm pk = new Perm(row.getString(0),row.getString(1),row.getString(2),row.getString(3), row.getString(4), row.getSet(5,String.class));
+		        	keys.put(pk.encode(), pk);
+		        	data.put(pk,pk.roles);
+		        }
+	        } finally {
+	        	tt.done();
+	        }
+        } finally {
+        	trans.info().log("Found",data.size(),"perms");
+        }
+	}
+
+	public String toString() {
+		return encode();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		return encode().hashCode();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		return encode().equals(obj);
+	}
+
+	@Override
+	public int compareTo(Perm o) {
+		return encode().compareTo(o.encode());
+	}
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Role.java b/authz-batch/src/main/java/com/att/authz/helpers/Role.java
new file mode 100644
index 0000000..fd57f5c
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Role.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Role implements Comparable<Role> {
+    public static final TreeMap<Role,Set<String>> data = new TreeMap<Role,Set<String>>();
+    public static final TreeMap<String,Role> keys = new TreeMap<String,Role>();
+
+	public final String ns, name, description;
+	private String full, encode;
+	public final Set<String> perms;
+	
+	public Role(String full) {
+		ns = name = description = "";
+		this.full = full;
+		perms = new HashSet<String>();
+	}
+	
+	public Role(String ns, String name, String description,Set<String> perms) {
+		this.ns = ns;
+		this.name = name;
+		this.description = description;
+		this.full = null;
+		this.encode = null;
+		this.perms = perms;
+	}
+	
+	public String encode() {
+		if(encode==null) {
+			encode = ns + '|' + name;
+		} 
+		return encode;
+	}
+
+	public String fullName() {
+		if(full==null) {
+			full = ns + '.' + name;
+		} 
+		return full;
+	}
+
+	public static void load(Trans trans, Session session ) {
+		load(trans,session,"select ns, name, description, perms from authz.role;");
+	}
+
+	public static void loadOneNS(Trans trans, Session session, String ns ) {
+		load(trans,session,"select ns, name, description, perms from authz.role WHERE ns='" + ns + "';");
+	}
+
+	private static void load(Trans trans, Session session, String query) {
+        trans.info().log( "query: " + query );
+        TimeTaken tt = trans.start("Read Roles", Env.REMOTE);
+       
+        ResultSet results;
+		try {
+	        Statement stmt = new SimpleStatement( query );
+	        results = session.execute(stmt);
+        } finally {
+        	tt.done();
+        }
+
+        try {
+	        Iterator<Row> iter = results.iterator();
+	        Row row;
+	        tt = trans.start("Load Roles", Env.SUB);
+	        try {
+		        while(iter.hasNext()) {
+		        	row = iter.next();
+		        	Role rk =new Role(row.getString(0),row.getString(1), row.getString(2),row.getSet(3,String.class));
+		        	keys.put(rk.encode(), rk);
+		        	data.put(rk,rk.perms);
+		        }
+	        } finally {
+	        	tt.done();
+	        }
+        } finally {
+        	trans.info().log("Found",data.size(),"roles");
+        }
+
+
+	}
+	public String toString() {
+		return encode();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		return encode().hashCode();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		return encode().equals(obj);
+	}
+
+	@Override
+	public int compareTo(Role o) {
+		return encode().compareTo(o.encode());
+	}
+
+	public static String fullName(String role) {
+		return role.replace('|', '.');
+	}
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/UserRole.java b/authz-batch/src/main/java/com/att/authz/helpers/UserRole.java
new file mode 100644
index 0000000..fa23d13
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/UserRole.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+
+import com.att.dao.aaf.cass.UserRoleDAO;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class UserRole implements Cloneable {
+	public static final List<UserRole> data = new ArrayList<UserRole>();
+    public static final TreeMap<String,List<UserRole>> byUser = new TreeMap<String,List<UserRole>>();
+    public static final TreeMap<String,List<UserRole>> byRole = new TreeMap<String,List<UserRole>>();
+
+	public final String user, role, ns, rname;
+	public final Date expires;
+
+	public UserRole(String user, String ns, String rname, Date expires) {
+		this.user = user;
+		this.role = ns + '.' + rname;
+		this.ns = ns;
+		this.rname = rname;
+		this.expires = expires;
+	}
+
+	public UserRole(String user, String role, String ns, String rname, Date expires) {
+		this.user = user;
+		this.role = role;
+		this.ns = ns;
+		this.rname = rname;
+		this.expires = expires;
+	}
+
+	public static void load(Trans trans, Session session, Creator<UserRole> creator ) {
+		load(trans,session,creator,null);
+	}
+
+	public static void loadOneRole(Trans trans, Session session, Creator<UserRole> creator, String role) {
+		load(trans,session,creator,"role='" + role +"' ALLOW FILTERING;");
+	}
+	
+	public static void loadOneUser(Trans trans, Session session, Creator<UserRole> creator, String user ) {
+		load(trans,session,creator,"role='"+ user +"';");
+	}
+
+	private static void load(Trans trans, Session session, Creator<UserRole> creator, String where) {
+		String query = creator.query(where);
+		trans.info().log( "query: " + query );
+        TimeTaken tt = trans.start("Read UserRoles", Env.REMOTE);
+       
+        ResultSet results;
+		try {
+	        Statement stmt = new SimpleStatement( query );
+	        results = session.execute(stmt);
+        } finally {
+        	tt.done();
+        }
+		int count = 0;
+        try {
+	        Iterator<Row> iter = results.iterator();
+	        Row row;
+	        tt = trans.start("Load UserRole", Env.SUB);
+	        try {
+		        while(iter.hasNext()) {
+		        	++count;
+		        	row = iter.next();
+		        	UserRole ur = creator.create(row);
+		        	data.add(ur);
+		        	
+		        	List<UserRole> lur = byUser.get(ur.user);
+		        	if(lur==null) {
+		        		lur = new ArrayList<UserRole>();
+			        	byUser.put(ur.user, lur);
+		        	}
+		        	lur.add(ur);
+		        	
+		        	lur = byRole.get(ur.role);
+		        	if(lur==null) {
+		        		lur = new ArrayList<UserRole>();
+			        	byRole.put(ur.role, lur);
+		        	}
+		        	lur.add(ur);
+		        }
+	        } finally {
+	        	tt.done();
+	        }
+        } finally {
+        	trans.info().log("Found",count,"UserRoles");
+        }
+
+
+	}
+
+	public static Creator<UserRole> v2_0_11 = new Creator<UserRole>() {
+		@Override
+		public UserRole create(Row row) {
+			return new UserRole(row.getString(0), row.getString(1), row.getString(2),row.getString(3),row.getDate(4));
+		}
+
+		@Override
+		public String select() {
+			return "select user,role,ns,rname,expires from authz.user_role";
+		}
+	};
+
+	public UserRoleDAO.Data to() {
+		UserRoleDAO.Data urd = new UserRoleDAO.Data();
+		urd.user = user;
+		urd.role = role;
+		urd.ns = ns;
+		urd.rname = rname;
+		urd.expires = expires;
+		return urd;
+	}
+	
+	public String toString() {
+		return "\"" + user + "\",\"" + role + "\",\""  + ns + "\",\"" + rname + "\",\""+ Chrono.dateOnlyStamp(expires);
+	}
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/reports/ApprNotify.java b/authz-batch/src/main/java/com/att/authz/reports/ApprNotify.java
new file mode 100644
index 0000000..79bdb5b
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/ApprNotify.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.att.authz.Batch;
+import com.att.authz.actions.Email;
+import com.att.authz.actions.Message;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Approver;
+import com.att.authz.helpers.Notification;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization;
+import com.att.authz.org.Organization.Identity;
+import com.att.authz.org.OrganizationException;
+import com.att.authz.org.OrganizationFactory;
+import com.att.dao.CassAccess;
+import com.att.dao.aaf.cass.ApprovalDAO;
+import com.att.dao.aaf.cass.ApprovalDAO.Data;
+import org.onap.aaf.inno.env.APIException;
+
+public class ApprNotify extends Batch {
+	private final ApprovalDAO apprDAO;
+	private Result<List<Data>> rladd;
+	private Email email;
+
+	public ApprNotify(AuthzTrans trans) throws APIException, IOException {
+		super(trans.env());
+		apprDAO = new ApprovalDAO(trans, cluster, CassAccess.KEYSPACE);
+		session = apprDAO.getSession(trans);
+		rladd = apprDAO.readByStatus(trans,"pending");
+		if(isDryRun()) {
+			email = new Email();//EmailPrint();
+		} else {
+			email = new Email();
+		}
+		email.subject("AAF Approval Notification (ENV: %s)",batchEnv);
+		email.preamble("AAF is the AT&T System for Fine-Grained Authorizations.  "
+				+ "You are being asked to Approve in the %s environment before AAF Actions can be taken. \n\n"
+				+ "  Please follow this link:\n\n\t%s/approve"
+				,batchEnv,env.getProperty(GUI_URL));
+
+		Notification.load(trans, session, Notification.v2_0_14);
+	}
+	
+	@Override
+	protected void run(AuthzTrans trans) {
+		if(rladd.isOK()) {
+			if(rladd.isEmpty()) {
+				trans.warn().log("No Pending Approvals to Process");
+			} else {
+				Organization org=null;
+				//Map<String,Organization> users = new HashMap<String,Organization>();
+				Map<String,Approver> users = new TreeMap<String,Approver>();
+				
+				for(Data data : rladd.value) {
+					// We've already seen this approver. Simply add the new request to him.
+					try {
+						Approver approver = users.get(data.approver);
+						if(approver==null) {
+							org = OrganizationFactory.obtain(trans.env(), data.approver);
+							approver = new Approver(data.approver, org);
+							users.put(data.approver, approver);
+						}
+						approver.addRequest(data.user);
+					} catch (OrganizationException e) {
+						trans.error().log(e);
+					}
+				}
+	
+				// Notify
+				Message msg = new Message();
+				for(Approver approver : users.values()) {
+					try {
+						Notification n = Notification.addApproval(trans, org.getIdentity(trans, approver.name));
+						approver.build(msg);
+						n.set(msg);
+						if(n.update(trans, session, isDryRun())) {
+							Identity user = n.org.getIdentity(trans, approver.name);
+							email.clear();
+							email.addTo(user.email());
+							email.msg(msg);
+							email.exec(trans, n.org);
+						}
+					} catch (OrganizationException e) {
+						trans.error().log(e);
+					}
+				}
+			}
+		} else {
+			trans.error().log('[',rladd.status,']',rladd.details);
+		}
+	}
+	
+	@Override
+	protected void _close(AuthzTrans trans) {
+		apprDAO.close(trans);
+	}
+	
+	
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckCred.java b/authz-batch/src/main/java/com/att/authz/reports/CheckCred.java
new file mode 100644
index 0000000..58cc074
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/CheckCred.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+
+import com.att.authz.Batch;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Cred;
+import com.att.authz.helpers.Cred.Instance;
+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;
+
+public class CheckCred extends Batch{
+
+	public CheckCred(AuthzTrans trans) throws APIException, IOException {
+		super(trans.env());
+		TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+		try {
+			session = cluster.connect();
+		} finally {
+			tt.done();
+		}
+    	
+		Cred.load(trans, session);
+	}
+
+	@Override
+	protected void run(AuthzTrans trans) {
+		String query;
+		for(Cred cred : Cred.data.values()) {
+			for(Instance inst : cred.instances) {
+				if(inst.other==0) {
+					if(dryRun) {
+	    				trans.warn().log("Ensuring 'other' is numeric");
+	        		} else {
+	       		        query = "UPDATE authz.cred SET other=0 WHERE "
+	       		        			+ "id='" + cred.id   
+	       		        			+ "' AND type=" + inst.type
+	       		        			+ " AND expires='" + Chrono.dateStamp(inst.expires)
+	       		        			+ "';";
+	       		        session.execute(query);
+	       		        trans.warn().log("resetting 'other'",query);
+					}
+				}
+			}
+		}
+
+	}        
+		/*
+        /// Evaluate 
+		for(UserRole urKey : UserRole.data) {
+        	NSSplit nss = NS.deriveParent(urKey.role);
+        	if(nss==null && NS.data.size()>0 ) { // there is no Namespace for this UserRole
+        		if(dryRun) {
+					trans.warn().printf("Would delete %s %s, which has no corresponding Namespace",urKey.user,urKey.role);
+        		} else {
+	   		        query = "DELETE FROM authz.user_role WHERE "
+			        			+ "user='" + urKey.user 
+			        			+ "' AND role='" + urKey.role
+			        			+ "';";
+			        session.execute(query);
+					trans.warn().printf("Deleting %s %s, which has no corresponding Namespace",urKey.user,urKey.role);
+        		}
+        	} else if(urKey.ns == null || urKey.rname == null || !urKey.role.equals(urKey.ns+'.'+urKey.rname)) {
+        		if(dryRun) {
+    				trans.warn().log(urKey,"needs to be split and added to Record (", urKey.ns, urKey.rname,")");
+        		} else {
+       		        query = "UPDATE authz.user_role SET ns='" + nss.ns 
+       		        			+ "', rname='" + nss.other
+       		        			+ "' WHERE "
+       		        			+ "user='" + urKey.user 
+       		        			+ "' AND role='" + urKey.role
+       		        			+ "';";
+       		        session.execute(query);
+       		        trans.warn().log("Setting ns and rname",query);
+				}
+			}
+		}
+	}
+	*/
+	@Override
+	protected void _close(AuthzTrans trans) {
+        session.close();
+        aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+	}
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckNS.java b/authz-batch/src/main/java/com/att/authz/reports/CheckNS.java
new file mode 100644
index 0000000..b4572b4
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/CheckNS.java
@@ -0,0 +1,425 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.att.authz.Batch;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.NS;
+import com.att.authz.helpers.NsAttrib;
+import com.att.authz.helpers.Perm;
+import com.att.authz.helpers.Role;
+import com.att.dao.aaf.cass.NsType;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+public class CheckNS extends Batch{
+
+	public CheckNS(AuthzTrans trans) throws APIException, IOException {
+		super(trans.env());
+		TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+		try {
+			session = cluster.connect();
+		} finally {
+			tt.done();
+		}
+        NS.load(trans, session,NS.v2_0_11);
+		Role.load(trans, session);
+		Perm.load(trans, session);
+		NsAttrib.load(trans, session, NsAttrib.v2_0_11);
+	}
+
+	@Override
+	protected void run(AuthzTrans trans) {
+		
+		String msg;
+		String query;
+        trans.info().log(STARS, msg = "Checking for NS type mis-match", STARS);
+		TimeTaken tt = trans.start(msg, Env.SUB);
+		try {
+			for(NS ns : NS.data.values()) {
+				if(ns.description==null) {
+					trans.warn().log("Namepace description is null. Changing to empty string.");
+					if(dryRun) {
+						trans.warn().log("Namepace description is null. Changing to empty string");
+					} else {
+	       		        query = "UPDATE authz.ns SET description='' WHERE name='" + ns.name +"';";
+	       		        session.execute(query);
+					}
+				}
+				int scope = count(ns.name,'.');
+				NsType nt;
+				switch(scope) {
+					case 0:
+						nt = NsType.DOT;
+						break;
+					case 1:
+						nt = NsType.ROOT;
+						break;
+					case 2:
+						nt = NsType.COMPANY;
+						break;
+					default:
+						nt = NsType.APP;
+						break;
+				}
+				if(ns.type!=nt.type || ns.scope !=scope) {
+					if(dryRun) {
+						trans.warn().log("Namepace",ns.name,"has no type.  Should change to ",nt.name());
+					} else {
+	       		        query = "UPDATE authz.ns SET type=" + nt.type + ", scope=" + scope + " WHERE name='" + ns.name +"';";
+						trans.warn().log("Namepace",ns.name,"changing to",nt.name()+":",query);
+	       		        session.execute(query);
+					}
+				}
+			}
+		} finally {
+			tt.done();
+		}
+		
+
+        trans.info().log(STARS, msg = "Checking for NS admin/owner mis-match", STARS);
+		tt = trans.start(msg, Env.SUB);
+		try {
+	        /// Evaluate 
+	        for(NS nk : NS.data.values()) {
+	        	//String name; 
+	        	String roleAdmin = nk.name+"|admin";
+	        	String roleAdminPrev = nk.name+".admin";
+	        	String roleOwner = nk.name+"|owner";
+	        	String roleOwnerPrev = nk.name+".owner";
+	        	String permAll = nk.name+"|access|*|*";
+	        	String permAllPrev = nk.name+".access|*|*";
+	        	String permRead = nk.name+"|access|*|read";
+	        	String permReadPrev = nk.name+".access|*|read";
+	        	// Admins
+	        	
+	        	Role rk = Role.keys.get(roleAdmin); // accomodate new role key
+	        	// Role Admin should exist 
+	        	if(rk==null) {
+	        		if(dryRun) {
+	        			trans.warn().log(nk.name + " is missing role: " + roleAdmin);
+	        		} else {
+	       		        query = "INSERT INTO authz.role(ns, name, description, perms) VALUES ('"
+	       		        		+ nk.name 
+	       		        		+ "','admin','Automatic Administration',"
+	       		        		+ "{'" + nk.name + "|access|*|*'});";
+	       		        session.execute(query);
+	       		        env.info().log(query);
+	       		        
+	       		        
+	       		        if(Role.keys.get(roleAdminPrev)!=null) {
+			    			query = "UPDATE authz.role set perms = perms + "
+			   		        		+ "{'" + roleAdminPrev + "'} "
+			   		        		+ "WHERE ns='"+ nk.name + "' AND "
+			   		        		+ "name='admin'"
+			   		        		+ ";";
+		       		        session.execute(query);
+		       		        env.info().log(query);
+	       		        }
+	        		}
+	        	} else {
+	               	// Role Admin should be linked to Perm All 
+	        		if(!rk.perms.contains(permAll)) {
+		        		if(dryRun) {
+		        			trans.warn().log(roleAdmin,"is not linked to",permAll);
+		        		} else {
+			    			query = "UPDATE authz.role set perms = perms + "
+			   		        		+ "{'" + nk.name + "|access|*|*'} "
+			   		        		+ "WHERE ns='"+ nk.name + "' AND "
+			   		        		+ "name='admin'"
+			   		        		+ ";";
+			   		        session.execute(query);
+			   		        env.info().log(query);
+			   		        
+			   		        if(rk.perms.contains(permAllPrev)) {
+				    			query = "UPDATE authz.role set perms = perms - "
+				   		        		+ "{'" + nk.name + ".access|*|*'} "
+				   		        		+ "WHERE ns='"+ nk.name + "' AND "
+				   		        		+ "name='admin'"
+				   		        		+ ";";
+				   		        session.execute(query);
+				   		        env.info().log(query);
+			   		        }
+		        		}
+	        		}
+	               	// Role Admin should not be linked to Perm Read 
+	        		if(rk.perms.contains(permRead)) {
+		        		if(dryRun) {
+		        			trans.warn().log(roleAdmin,"should not be linked to",permRead);
+		        		} else {
+			    			query = "UPDATE authz.role set perms = perms - "
+			   		        		+ "{'" + nk.name + "|access|*|read'} "
+			   		        		+ "WHERE ns='"+ nk.name + "' AND "
+			   		        		+ "name='admin'"
+			   		        		+ ";";
+			   		        session.execute(query);
+			   		        env.info().log(query);
+		        		}
+	        		}
+	        	}
+	        	
+	        	Perm pk = Perm.keys.get(permAll);
+	        	if(pk==null) {
+	    			trans.warn().log(nk.name + " is missing perm: " + permAll);
+	        		if(!dryRun) {
+	       		        query = "INSERT INTO authz.perm(ns, type,instance,action,description, roles) VALUES ('"
+	       		        		+ nk.name 
+	       		        		+ "','access','*','*','Namespace Write',"
+	       		        		+ "{'" + nk.name + "|admin'});";
+	       		        session.execute(query);
+	       		        env.info().log(query);
+	
+	        		}
+	        	} else {
+		        	// PermALL should be linked to Role Admin
+		        	if(!pk.roles.contains(roleAdmin)) {
+	        			trans.warn().log(permAll,"is not linked to",roleAdmin);
+		        		if(!dryRun) {
+			    			query = "UPDATE authz.perm set roles = roles + "
+			   		        		+ "{'" + nk.name + "|admin'} WHERE "
+			   		        		+ "ns='"+ pk.ns + "' AND "
+			   		        		+ "type='access' AND instance='*' and action='*'"
+			   		        		+ ";";
+			   		        session.execute(query);
+			   		        env.info().log(query);
+			   		        
+			   		        if(pk.roles.contains(roleAdminPrev)) {
+				    			query = "UPDATE authz.perm set roles = roles - "
+				   		        		+ "{'" + nk.name + ".admin'} WHERE "
+				   		        		+ "ns='"+ pk.ns + "' AND "
+				   		        		+ "type='access' AND instance='*' and action='*'"
+				   		        		+ ";";
+				   		        session.execute(query);
+				   		        env.info().log(query);
+
+			   		        }
+		        		}
+		        	}
+		        	
+		        	// PermALL should be not linked to Role Owner
+		        	if(pk.roles.contains(roleOwner)) {
+		        		trans.warn().log(permAll,"should not be linked to",roleOwner);
+		        		if(!dryRun) {
+			    			query = "UPDATE authz.perm set roles = roles - "
+			   		        		+ "{'" + nk.name + "|owner'} WHERE "
+			   		        		+ "ns='"+ pk.ns + "' AND "
+			   		        		+ "type='access' AND instance='*' and action='*'"
+			   		        		+ ";";
+			   		        session.execute(query);
+			   		        env.info().log(query);
+		        		}
+		        	}
+	
+	        	}
+	
+	        	
+	        	
+	        	// Owner
+	        	rk = Role.keys.get(roleOwner);
+	        	if(rk==null) {
+	    			trans.warn().log(nk.name + " is missing role: " + roleOwner);
+	        		if(!dryRun) {
+	       		        query = "INSERT INTO authz.role(ns, name, description, perms) VALUES('"
+	       		        		+ nk.name 
+	       		        		+ "','owner','Automatic Owners',"
+	       		        		+ "{'" + nk.name + "|access|*|read'});";
+	       		        session.execute(query);
+	       		        env.info().log(query);
+	
+	        		}
+	        	} else { 
+		        	// Role Owner should be linked to permRead
+		        	if(!rk.perms.contains(permRead)) {
+	        			trans.warn().log(roleOwner,"is not linked to",permRead);
+		        		if(!dryRun) {
+			    			query = "UPDATE authz.role set perms = perms + "
+			   		        		+ "{'" + nk.name + "|access|*|read'} "
+			   		        		+ "WHERE ns='"+ nk.name + "' AND "
+			   		        		+ "name='owner'"
+			   		        		+ ";";
+			   		        session.execute(query);
+			   		        env.info().log(query);
+			   		        
+			   		        if(rk.perms.contains(permReadPrev)) {
+				    			query = "UPDATE authz.role set perms = perms - "
+				   		        		+ "{'" + nk.name + ".access|*|read'} "
+				   		        		+ "WHERE ns='"+ nk.name + "' AND "
+				   		        		+ "name='owner'"
+				   		        		+ ";";
+				   		        session.execute(query);
+				   		        env.info().log(query);
+
+			   		        }
+		        		}
+		        	}
+	               	// Role Owner should not be linked to PermAll 
+	        		if(rk.perms.contains(permAll)) {
+	        			trans.warn().log(roleAdmin,"should not be linked to",permAll);
+		        		if(!dryRun) {
+			    			query = "UPDATE authz.role set perms = perms - "
+			   		        		+ "{'" + nk.name + "|access|*|*'} "
+			   		        		+ "WHERE ns='"+ nk.name + "' AND "
+			   		        		+ "name='admin'"
+			   		        		+ ";";
+			   		        session.execute(query);
+			   		        env.info().log(query);
+		        		}
+	        		}
+	
+	        	}
+	
+	        	pk = Perm.keys.get(permRead);
+	        	if(pk==null) {
+	       			trans.warn().log(nk.name + " is missing perm: " + permRead);
+	           		if(!dryRun) {
+	       		        query = "INSERT INTO authz.perm(ns, type,instance,action,description, roles) VALUES ('"
+	       		        		+ nk.name 
+	       		        		+ "','access','*','read','Namespace Read',"
+	       		        		+ "{'" + nk.name + "|owner'});";
+	       		        session.execute(query);
+	       		        env.info().log(query);
+	        		}
+	        	} else {
+	        		// PermRead should be linked to roleOwner
+	        		if(!pk.roles.contains(roleOwner)) {
+	        			trans.warn().log(permRead, "is not linked to", roleOwner);
+	        			if(!dryRun) {
+			    			query = "UPDATE authz.perm set roles = roles + "
+			   		        		+ "{'" + nk.name + "|owner'} WHERE "
+			   		        		+ "ns='"+ pk.ns + "' AND "
+			   		        		+ "type='access' AND instance='*' and action='read'"
+			   		        		+ ";";
+			   		        session.execute(query);
+			   		        env.info().log(query);
+			   		        
+			   		        if(pk.roles.contains(roleOwnerPrev)) {
+				    			query = "UPDATE authz.perm set roles = roles - "
+				   		        		+ "{'" + nk.name + ".owner'} WHERE "
+				   		        		+ "ns='"+ pk.ns + "' AND "
+				   		        		+ "type='access' AND instance='*' and action='read'"
+				   		        		+ ";";
+				   		        session.execute(query);
+				   		        env.info().log(query);
+
+			   		        }
+		        		}
+		        	}
+		        	// PermRead should be not linked to RoleAdmin
+		        	if(pk.roles.contains(roleAdmin)) {
+		        		if(dryRun) {
+		        			trans.warn().log(permRead,"should not be linked to",roleAdmin);
+		        		} else {
+			    			query = "UPDATE authz.perm set roles = roles - "
+			   		        		+ "{'" + nk.name + "|admin'} WHERE "
+			   		        		+ "ns='"+ pk.ns + "' AND "
+			   		        		+ "type='access' AND instance='*' and action='read'"
+			   		        		+ ";";
+			   		        session.execute(query);
+			   		        env.info().log(query);
+		        		}
+		        	}
+	        	}
+	
+	
+	        	int dot = nk.name.lastIndexOf('.');
+	        	String parent;
+	        	if(dot<0) {
+	        		parent = ".";
+	        	} else {
+	        		parent = nk.name.substring(0, dot);
+	        	}
+	        	
+	        	if(!parent.equals(nk.parent)) {
+	        		if(dryRun) {
+	        			trans.warn().log(nk.name + " is missing namespace data");
+	        		} else {
+		   		        query = "UPDATE authz.ns SET parent='"+parent+"'" +
+		   		        		" WHERE name='" + nk.name + "';";
+		   		        session.execute(query);
+		   		        env.info().log(query);
+	        		}
+	        	}
+	        
+	        // During Migration:
+	        List<NsAttrib> swm = NsAttrib.byNS.get(nk.name);
+	        boolean hasSwmV1 = false;
+	        if(swm!=null) {for(NsAttrib na : swm) {
+	        	if("swm".equals(na.key) && "v1".equals(na.value)) {
+	        		hasSwmV1=true;
+	        		break;
+	        	}
+	        }}
+	        String roleMem = nk.name+"|member";
+	        Role rm = Role.keys.get(roleMem); // Accommodate new role key
+	        if(rm==null && hasSwmV1) {
+	        	query = "INSERT INTO authz.role(ns, name, description, perms) VALUES ('"
+   		        		+ nk.name 
+   		        		+ "','member','Member',"
+   		        		+ "{'" + nk.name + "|access|*|read'});";
+   		        session.execute(query);
+	   		     query = "UPDATE authz.role set perms = perms + "
+			        		+ "{'" + nk.name + "|access|*|read'} "
+			        		+ "WHERE ns='"+ nk.name + "' AND "
+			        		+ "name='member'"
+			        		+ ";";
+	     		session.execute(query);
+	     		env.info().log(query);
+	        }
+	        if(rm!=null)  {
+	        	if(!rm.perms.contains(permRead)) {
+	        		if(isDryRun()) {
+	        		     env.info().log(nk.name+"|member needs " + nk.name + "|access|*|read");
+	        		} else {
+		        		query = "UPDATE authz.perm set roles = roles + "
+		   		        		+ "{'" + nk.name + "|member'} WHERE "
+		   		        		+ "ns='"+ pk.ns + "' AND "
+		   		        		+ "type='access' AND instance='*' and action='read'"
+		   		        		+ ";";
+		        		session.execute(query);
+		        		env.info().log(query);
+		        		query = "UPDATE authz.role set perms = perms + "
+		   		        		+ "{'" + nk.name + "|access|*|read'"
+		   		        		+ (hasSwmV1?",'"+nk.name+"|swm.star|*|*'":"")
+		   		        			+ "} "
+		   		        		+ "WHERE ns='"+ nk.name + "' AND "
+		   		        		+ "name='member'"
+		   		        		+ ";";
+		        		session.execute(query);
+		        		env.info().log(query);
+		        		if(hasSwmV1) {
+			        		query = "UPDATE authz.perm set roles = roles + "
+			   		        		+ "{'" + nk.name + "|member'} WHERE "
+			   		        		+ "ns='"+ pk.ns + "' AND "
+			   		        		+ "type='swm.star' AND instance='*' and action='*'"
+			   		        		+ ";";
+			        		session.execute(query);
+			        		env.info().log(query);
+		        		}
+	        		}
+	        	}
+	        }
+	        
+
+	        
+	        // Best Guess Owner
+	        
+//	        owner = Role.keys.get(ns.)
+	        }
+		} finally {
+			tt.done();
+		}
+	
+	}
+
+
+	@Override
+	protected void _close(AuthzTrans trans) {
+        session.close();
+        aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+	}
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckRolePerm.java b/authz-batch/src/main/java/com/att/authz/reports/CheckRolePerm.java
new file mode 100644
index 0000000..2df123d
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/CheckRolePerm.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+import java.util.Set;
+
+import com.att.authz.Batch;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.NS;
+import com.att.authz.helpers.Perm;
+import com.att.authz.helpers.Role;
+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.Split;
+
+public class CheckRolePerm extends Batch{
+
+	public CheckRolePerm(AuthzTrans trans) throws APIException, IOException {
+		super(trans.env());
+		TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+		try {
+			session = cluster.connect();
+		} finally {
+			tt.done();
+		}
+		NS.load(trans,session,NS.v2_0_11);
+		Role.load(trans, session);
+		Perm.load(trans, session);
+	}
+
+	@Override
+	protected void run(AuthzTrans trans) {
+        // Run for Roles
+        trans.info().log("Checking for Role/Perm mis-match");
+		
+		String query;
+        /// Evaluate from Role side
+        for(Role roleKey : Role.data.keySet()) {
+        	for(String perm : Role.data.get(roleKey)) {
+        		Perm pk = Perm.keys.get(perm);
+        		if(pk==null) {
+    				NS ns=null;
+        			String msg = perm + " in role " + roleKey.fullName() + " does not exist";
+        			String newPerm;
+        			String[] s = Split.split('|', perm);
+        			if(s.length==3) {
+	    				int i;
+	    				String find = s[0];
+	    				for(i=find.lastIndexOf('.');ns==null && i>=0;i=find.lastIndexOf('.', i-1)) {
+	    					ns = NS.data.get(find.substring(0,i));
+	    				}
+	    				if(ns==null) {
+	    					newPerm = perm;
+	    				} else {
+	    					newPerm = ns.name + '|' + s[0].substring(i+1) + '|' + s[1] + '|' + s[2];
+	    				}
+        			} else {
+        				newPerm = perm;
+        			}
+        			if(dryRun) {
+        				if(ns==null) {
+        					trans.warn().log(msg, "- would remove role from perm;");
+        				} else {
+        					trans.warn().log(msg, "- would update role in perm;");
+        				}
+					} else {
+        				if(ns!=null) {
+            				query = "UPDATE authz.role SET perms = perms + {'" +
+            						newPerm + "'}" 
+		       		        		+ (roleKey.description==null?", description='clean'":"")
+		       		        		+ " WHERE "
+		       		        		+ "ns='" + roleKey.ns 
+		       		        		+ "' AND name='" + roleKey.name + "';";
+		       		        trans.warn().log("Fixing role in perm",query);   
+		       		        session.execute(query);
+        				}
+
+	       		        query = "UPDATE authz.role SET perms = perms - {'"
+	       		        		+ perm.replace("'", "''") + "'}"
+	       		        		+ (roleKey.description==null?", description='clean'":"")
+	       		        		+ " WHERE "
+	       		        		+ "ns='" + roleKey.ns 
+	       		        		+ "' AND name='" + roleKey.name + "';";
+	       		        session.execute(query);
+	       		        trans.warn().log(msg, "- removing role from perm");
+//       		        env.info().log( "query: " + query );
+        			}
+        		} else {
+	        		Set<String> p_roles = Perm.data.get(pk);
+	        		if(p_roles!=null && !p_roles.contains(roleKey.encode())) {
+	       				String msg = perm + " does not have role: " + roleKey;
+	        			if(dryRun) {
+					    trans.warn().log(msg,"- should add this role to this perm;");
+					} else {
+		       		        query = "update authz.perm set roles = roles + {'"
+		       		        		+ roleKey.encode() + "'}"
+		       		        		+ (pk.description==null?", description=''":"")
+		       		        		+ " WHERE "
+		       		        		+ "ns='" + pk.ns
+		       		        		+ "' AND type='" + pk.type
+		       		        		+ "' AND instance='" + pk.instance
+		       		        		+ "' AND action='" + pk.action 
+		       		        		+ "';";
+		       		        session.execute(query);
+		       		        trans.warn().log(msg,"- adding perm to role");
+	        			}
+	       				
+	        		}
+        		}
+        	}
+        }
+
+        for(Perm permKey : Perm.data.keySet()) {
+        	for(String role : Perm.data.get(permKey)) {
+        		Role rk = Role.keys.get(role);
+        		if(rk==null) {
+        			String s = role + " in perm " + permKey.encode() + " does not exist";
+        			if(dryRun) {
+				    trans.warn().log(s,"- would remove perm from role;");
+				} else {
+	       		        query = "update authz.perm set roles = roles - {'"
+	       		        		+ role.replace("'","''") + "'}"
+	       		        		+ (permKey.description==null?", description='clean'":"")
+	       		        		+ " WHERE "
+	       		        		+ "ns='" + permKey.ns
+	       		        		+ "' AND type='" + permKey.type
+	       		        		+ "' AND instance='" + permKey.instance
+	       		        		+ "' AND action='" + permKey.action + "';";
+	       		        session.execute(query);
+	       		        trans.warn().log(s,"- removing role from perm");
+        			}
+        		} else {
+	        		Set<String> r_perms = Role.data.get(rk);
+	        		if(r_perms!=null && !r_perms.contains(permKey.encode())) {
+	       				String s ="Role '" + role + "' does not have perm: '" + permKey + '\'';
+	        			if(dryRun) {
+					    trans.warn().log(s,"- should add this perm to this role;");
+					} else {
+		       		        query = "update authz.role set perms = perms + {'"
+		       		        		+ permKey.encode() + "'}"
+		       		        		+ (rk.description==null?", description=''":"")
+		       		        		+ " WHERE "
+		       		        		+ "ns='" + rk.ns
+		       		        		+ "' AND name='" + rk.name + "';";
+		       		        session.execute(query);
+		       		        trans.warn().log(s,"- adding role to perm");
+	        			}
+	        		}
+        		}
+        	}
+        }
+
+	}
+
+
+	@Override
+	protected void _close(AuthzTrans trans) {
+        session.close();
+        aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+	}
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckUR.java b/authz-batch/src/main/java/com/att/authz/reports/CheckUR.java
new file mode 100644
index 0000000..5064140
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/CheckUR.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+
+import com.att.authz.Batch;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.NS;
+import com.att.authz.helpers.NS.NSSplit;
+import com.att.authz.helpers.UserRole;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+public class CheckUR extends Batch{
+
+	public CheckUR(AuthzTrans trans) throws APIException, IOException {
+		super(trans.env());
+		TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+		try {
+			session = cluster.connect();
+		} finally {
+			tt.done();
+		}
+    	NS.load(trans, session,NS.v2_0_11);
+		UserRole.load(trans, session,UserRole.v2_0_11);
+	}
+
+	@Override
+	protected void run(AuthzTrans trans) {
+        trans.info().log("Get All Namespaces");
+
+		
+		String query;
+        
+        /// Evaluate 
+		for(UserRole urKey : UserRole.data) {
+        	NSSplit nss = NS.deriveParent(urKey.role);
+        	if(nss==null && NS.data.size()>0 ) { // there is no Namespace for this UserRole
+        		if(dryRun) {
+					trans.warn().printf("Would delete %s %s, which has no corresponding Namespace",urKey.user,urKey.role);
+        		} else {
+	   		        query = "DELETE FROM authz.user_role WHERE "
+			        			+ "user='" + urKey.user 
+			        			+ "' AND role='" + urKey.role
+			        			+ "';";
+			        session.execute(query);
+					trans.warn().printf("Deleting %s %s, which has no corresponding Namespace",urKey.user,urKey.role);
+        		}
+        	} else if(urKey.ns == null || urKey.rname == null || !urKey.role.equals(urKey.ns+'.'+urKey.rname)) {
+        		if(dryRun) {
+    				trans.warn().log(urKey,"needs to be split and added to Record (", urKey.ns, urKey.rname,")");
+        		} else {
+       		        query = "UPDATE authz.user_role SET ns='" + nss.ns 
+       		        			+ "', rname='" + nss.other
+       		        			+ "' WHERE "
+       		        			+ "user='" + urKey.user 
+       		        			+ "' AND role='" + urKey.role
+       		        			+ "';";
+       		        session.execute(query);
+       		        trans.warn().log("Setting ns and rname",query);
+				}
+			}
+		}
+	}
+	
+	@Override
+	protected void _close(AuthzTrans trans) {
+        session.close();
+        aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+	}
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/Expiring.java b/authz-batch/src/main/java/com/att/authz/reports/Expiring.java
new file mode 100644
index 0000000..79f3759
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/Expiring.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import com.att.authz.Batch;
+import com.att.authz.actions.Action;
+import com.att.authz.actions.ActionDAO;
+import com.att.authz.actions.CredDelete;
+import com.att.authz.actions.CredPrint;
+import com.att.authz.actions.FADelete;
+import com.att.authz.actions.FAPrint;
+import com.att.authz.actions.Key;
+import com.att.authz.actions.URDelete;
+import com.att.authz.actions.URFutureApprove;
+import com.att.authz.actions.URFuturePrint;
+import com.att.authz.actions.URPrint;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Cred;
+import com.att.authz.helpers.Cred.Instance;
+import com.att.authz.helpers.Future;
+import com.att.authz.helpers.Notification;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization.Identity;
+import com.att.dao.aaf.cass.CredDAO;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+public class Expiring extends Batch {
+	
+	private final Action<UserRole,Void> urDelete,urPrint;
+	private final Action<UserRole,List<Identity>> urFutureApprove;
+	private final Action<CredDAO.Data,Void> crDelete,crPrint;
+	private final Action<Future,Void> faDelete;
+//	private final Email email;
+	private final Key<UserRole> memoKey;
+	
+	public Expiring(AuthzTrans trans) throws APIException, IOException {
+		super(trans.env());
+	    trans.info().log("Starting Connection Process");
+	    TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
+	    try {
+			urPrint = new URPrint("Expired:");
+			crPrint = new CredPrint("Expired:");
+
+			URFutureApprove ufr = new URFutureApprove(trans,cluster); 
+			memoKey = ufr;
+			
+			if(isDryRun()) {
+				urDelete = new URPrint("Would Delete:");
+				// While Testing
+//				urFutureApprove = ufr;
+				urFutureApprove = new URFuturePrint("Would setup Future/Approvals");
+				crDelete = new CredPrint("Would Delete:");
+				faDelete = new FAPrint("Would Delete:");
+//				email = new EmailPrint();
+
+				TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+				try {
+					session = cluster.connect();
+				} finally {
+					tt.done();
+				}
+	
+			} else {
+				TimeTaken tt = trans.start("Connect to Cluster with DAOs", Env.REMOTE);
+				try {
+					ActionDAO<UserRole,Void> adao;
+					urDelete = adao = new URDelete(trans, cluster);
+					urFutureApprove = new URFutureApprove(trans,adao);
+					faDelete = new FADelete(trans, adao);
+
+					crDelete = new CredDelete(trans, adao);
+//					email = new Email();
+					TimeTaken tt2 = trans.start("Connect to Cluster", Env.REMOTE);
+					try {
+						session = adao.getSession(trans);
+					} finally {
+						tt2.done();
+					}
+				} finally {
+					tt.done();
+				}
+			}
+			
+			UserRole.load(trans, session, UserRole.v2_0_11);
+			Cred.load(trans, session);
+			Notification.load(trans, session, Notification.v2_0_14);
+			Future.load(trans,session,Future.v2_0_15);
+	    } finally {
+	    	tt0.done();
+	    }
+	}
+
+	@Override
+	protected void run(AuthzTrans trans) {
+		// Setup Date boundaries
+		Date now = new Date();
+        GregorianCalendar gc = new GregorianCalendar();
+        gc.setTime(now);
+        gc.add(GregorianCalendar.MONTH, 1);
+        Date future = gc.getTime();
+        gc.setTime(now);
+        gc.add(GregorianCalendar.MONTH, -1);
+        Date tooLate = gc.getTime();
+        int count = 0, deleted=0;
+        
+//        List<Notification> ln = new ArrayList<Notification>();
+        TimeTaken tt;
+                
+        // Run for Expired Futures
+        trans.info().log("Checking for Expired Futures");
+        tt = trans.start("Delete old Futures", Env.REMOTE);
+        try {
+        	List<Future> delf = new ArrayList<Future>();
+        	for(Future f : Future.data) {
+        		AuthzTrans localTrans = env.newTransNoAvg();
+        		if(f.expires.before(now)) {
+        			faDelete.exec(localTrans, f);
+        			delf.add(f);
+        		}
+        	}
+        	Future.delete(delf);
+        } finally {
+        	tt.done();
+        }
+
+        // Run for Roles
+        trans.info().log("Checking for Expired Roles");
+        try {
+        	for(UserRole ur : UserRole.data) {
+        		AuthzTrans localTrans = env.newTransNoAvg();
+        		if(ur.expires.before(tooLate)) {
+        			if("owner".equals(ur.rname)) { // don't delete Owners, even if Expired
+        				urPrint.exec(localTrans,ur);
+        			} else {
+            			urDelete.exec(localTrans,ur);
+            			++deleted;
+            			trans.logAuditTrail(trans.info());
+        			}
+        			++count;
+        		} else if(ur.expires.before(future)) {
+        			List<Future> fbm = Future.byMemo.get(memoKey.key(ur));
+        			if(fbm==null || fbm.isEmpty()) {
+	        			Result<List<Identity>> rapprovers = urFutureApprove.exec(localTrans, ur);
+	        			if(rapprovers.isOK()) {
+	        				for(Identity ou : rapprovers.value) {
+//	        					Notification n = Notification.addApproval(localTrans,ou);
+//	        					if(n.org==null) {
+//	        						n.org = getOrgFromID(localTrans, ur.user);
+//	        					}
+//		        				ln.add(n);
+		        				urPrint.exec(localTrans,ur);
+		        				if(isDryRun()) {
+		        					trans.logAuditTrail(trans.info());
+		        				}
+	        				}
+	        			}
+        			}
+	        		++count;
+	        	}
+        	}
+		} finally {
+        	env.info().log("Found",count,"roles expiring before",future);
+        	env.info().log("deleting",deleted,"roles expiring before",tooLate);
+        }
+        
+//        // Email Approval Notification
+//		email.subject("AAF Role Expiration Warning (ENV: %s)", batchEnv);
+//		email.indent("");
+//        for(Notification n: ln) {
+//        	if(n.org==null) {
+//        		trans.error().log("No Organization for Notification");
+//        	} else if(n.update(trans, session, isDryRun())) {
+//        		email.clear();
+//        		email.addTo(n.user);
+//				email.line(n.text(new StringBuilder()).toString());
+//				email.exec(trans,n.org);
+//        	}        	
+//        }
+        // Run for Creds
+        trans.info().log("Checking for Expired Credentials");
+        System.out.flush();
+        count = 0;
+        try {
+        	CredDAO.Data crd = new CredDAO.Data();
+        	Date last = null;
+        	for( Cred creds : Cred.data.values()) {
+        		AuthzTrans localTrans = env.newTransNoAvg();
+				crd.id = creds.id;
+        		for(int type : creds.types()) {
+					crd.type = type;
+        			for( Instance inst : creds.instances) {
+        				if(inst.expires.before(tooLate)) {
+        					crd.expires = inst.expires;
+        					crDelete.exec(localTrans, crd);
+        				} else if(last==null || inst.expires.after(last)) {
+    						last = inst.expires;
+    					}
+        			}
+        			if(last!=null) {
+        				if(last.before(future)) {
+        					crd.expires = last;
+        					crPrint.exec(localTrans, crd);
+	        				++count;
+        				}
+        			}
+        		}
+        	}
+        } finally {
+        	env.info().log("Found",count,"current creds expiring before",future);
+        }
+        
+	}
+	
+	@Override
+	protected void _close(AuthzTrans trans) {
+        aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+        for(Action<?,?> action : new Action<?,?>[] {urDelete,crDelete}) {
+        	if(action instanceof ActionDAO) {
+        		((ActionDAO<?,?>)action).close(trans);
+        	}
+        }
+        session.close();
+	}
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/NSDump.java b/authz-batch/src/main/java/com/att/authz/reports/NSDump.java
new file mode 100644
index 0000000..a15fc24
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/NSDump.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Date;
+import java.util.List;
+
+import com.att.authz.Batch;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Cred;
+import com.att.authz.helpers.NS;
+import com.att.authz.helpers.Perm;
+import com.att.authz.helpers.Role;
+import com.att.authz.helpers.UserRole;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+public class NSDump extends Batch{
+	private PrintStream out = System.out;
+	private final String ns, admin, owner;
+	
+	public NSDump(AuthzTrans trans) throws APIException, IOException {
+		super(trans.env());
+		if(args().length>0) {
+			ns = args()[0];
+		} else {
+			throw new APIException("NSDump requires \"NS\" parameter");
+		}
+		admin = ns + "|admin";
+		owner = ns + "|owner";
+
+		TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+		try {
+			session = cluster.connect();
+		} finally {
+			tt.done();
+		}
+
+		NS.loadOne(trans, session,NS.v2_0_11,ns);
+		Role.loadOneNS(trans, session, ns);
+		if(Role.data.keySet().size()>5) {
+			UserRole.load(trans, session,UserRole.v2_0_11);
+		} else {
+			for(Role r : Role.data.keySet()) {
+				UserRole.loadOneRole(trans, session, UserRole.v2_0_11, r.fullName());
+			}
+		}
+		Perm.loadOneNS(trans,session,ns);
+		Cred.loadOneNS(trans, session, ns);
+	}
+
+	@Override
+	protected void run(AuthzTrans trans) {
+		Date now = new Date();
+		for(NS ns : NS.data.values()) {
+			out.format("# Data for Namespace [%s] - %s\n",ns.name,ns.description);
+			out.format("ns create %s",ns);
+			boolean first = true;
+			List<UserRole> owners = UserRole.byRole.get(owner);
+			if(owners!=null)for(UserRole ur : owners) {
+				if(first) {
+					out.append(' ');
+					first = false;
+				} else {
+					out.append(',');
+				}
+				out.append(ur.user);
+			}
+			first = true;
+			List<UserRole> admins = UserRole.byRole.get(admin); 
+			if(admins!=null)for(UserRole ur : admins) {
+				if(first) {
+					out.append(' ');
+					first = false;
+				} else {
+					out.append(',');
+				}
+				out.append(ur.user);
+			}
+			out.println();
+			
+			// Load Creds
+			Date last;
+			for(Cred c : Cred.data.values()) {
+				for(int i : c.types()) {
+					last = c.last(i);
+					if(last!=null && now.before(last)) {
+						switch(i) {
+							case 1:
+								out.format("    user cred add %s %s\n", c.id,"new2you!");
+								break;
+							case 200:
+								out.format("    # CERT needs registering for %s\n", c.id);
+								break;
+							default:
+								out.format("    # Unknown Type for %s\n", c.id);
+						}
+					}
+				}
+			}
+			
+			// Load Roles
+			for(Role r : Role.data.keySet()) {
+				if(!"admin".equals(r.name) && !"owner".equals(r.name)) {
+					out.format("  role create %s\n",r.fullName());
+					List<UserRole> lur = UserRole.byRole.get(r.fullName());
+					if(lur!=null)for(UserRole ur : lur) {
+						if(ur.expires.after(now)) {
+							out.format("    request role user add %s %s\n", ur.role,ur.user);
+						}
+					}
+				}
+			}
+
+			// Load Perms
+			for(Perm r : Perm.data.keySet()) {
+				out.format("  perm create %s.%s %s %s\n",r.ns,r.type,r.instance,r.action);
+				for(String role : r.roles) {
+					out.format("    request perm grant %s.%s %s %s %s\n", r.ns,r.type,r.instance,r.action,Role.fullName(role));
+				}
+			}
+
+		}
+	}
+
+	@Override
+	protected void _close(AuthzTrans trans) {
+        session.close();
+        aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+	}
+
+}
diff --git a/authz-batch/src/main/scripts/SyncV1V2 b/authz-batch/src/main/scripts/SyncV1V2
new file mode 100644
index 0000000..c3a9115
--- /dev/null
+++ b/authz-batch/src/main/scripts/SyncV1V2
@@ -0,0 +1,17 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+
+cd $ROOT_DIR
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+  CP=$CP:$FILE
+done
+
+CMD="SyncV1V2"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD  >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
diff --git a/authz-batch/src/main/scripts/SyncV1V2daily b/authz-batch/src/main/scripts/SyncV1V2daily
new file mode 100644
index 0000000..5c89d04
--- /dev/null
+++ b/authz-batch/src/main/scripts/SyncV1V2daily
@@ -0,0 +1,17 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+
+cd $ROOT_DIR
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+  CP=$CP:$FILE
+done
+
+CMD="SyncV1V2 v1 v2" 
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD  >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
diff --git a/authz-batch/src/main/scripts/SyncV2V1 b/authz-batch/src/main/scripts/SyncV2V1
new file mode 100644
index 0000000..e766218
--- /dev/null
+++ b/authz-batch/src/main/scripts/SyncV2V1
@@ -0,0 +1,17 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+
+cd $ROOT_DIR
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+  CP=$CP:$FILE
+done
+
+CMD="SyncV2V1"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD  >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
\ No newline at end of file
diff --git a/authz-batch/src/main/scripts/SyncV2V1daily b/authz-batch/src/main/scripts/SyncV2V1daily
new file mode 100644
index 0000000..8a67692
--- /dev/null
+++ b/authz-batch/src/main/scripts/SyncV2V1daily
@@ -0,0 +1,17 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+
+cd $ROOT_DIR
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+  CP=$CP:$FILE
+done
+
+CMD="SyncV2V1 v2 v1"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD  >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
\ No newline at end of file
diff --git a/authz-batch/src/main/scripts/V1daily b/authz-batch/src/main/scripts/V1daily
new file mode 100644
index 0000000..9f6c4ca
--- /dev/null
+++ b/authz-batch/src/main/scripts/V1daily
@@ -0,0 +1,46 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+ENV_CONTEXT=_ENV_CONTEXT_
+
+cd $ROOT_DIR
+
+if [ ! -e "$ROOT_DIR/data/stage" ]; then
+	mkdir -p $ROOT_DIR/data/stage
+fi
+
+if [ ! -e "$ROOT_DIR/data/$ENV_CONTEXT/stage" ]; then
+	mkdir -p $ROOT_DIR/data/$ENV_CONTEXT
+	ln -s $ROOT_DIR/data/stage $ROOT_DIR/data/$ENV_CONTEXT/stage
+fi
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+  CP=$CP:$FILE
+done
+
+CMD="V1DataFile all"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD  >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+
+cd $ROOT_DIR/data/stage
+LATEST=`ls -tr v1*.dat | tail -1`
+if [ "$LATEST" != "" ]; then
+  > ../v1.lock
+  cp -p $LATEST ../v1.dat
+  rm ../v1.lock
+fi
+
+LATEST=`ls -tr v1*.skip | tail -1`
+if [ "$LATEST" != "" ]; then
+  cp -p $LATEST ../v1.skip
+fi
+
+for FILE in `ls v1* | grep -v .gz`; do
+	gzip $FILE
+done
+
+
diff --git a/authz-batch/src/main/scripts/V2daily b/authz-batch/src/main/scripts/V2daily
new file mode 100644
index 0000000..c547a94
--- /dev/null
+++ b/authz-batch/src/main/scripts/V2daily
@@ -0,0 +1,46 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+ENV_CONTEXT=_ENV_CONTEXT_
+
+cd $ROOT_DIR
+
+if [ ! -e "$ROOT_DIR/data/stage" ]; then
+	mkdir -p $ROOT_DIR/data/stage
+fi
+
+if [ ! -e "$ROOT_DIR/data/$ENV_CONTEXT/stage" ]; then
+	mkdir -p $ROOT_DIR/data/$ENV_CONTEXT
+	ln -s $ROOT_DIR/data/stage $ROOT_DIR/data/$ENV_CONTEXT/stage
+fi
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+  CP=$CP:$FILE
+done
+
+CMD="V2DataFile all"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD  >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+
+cd $ROOT_DIR/data/stage
+LATEST=`ls -tr v2*.dat | tail -1`
+if [ "$LATEST" != "" ]; then
+  > ../v2.lock
+  cp -p $LATEST ../v2.dat
+  rm ../v2.lock
+fi
+
+LATEST=`ls -tr v2*.skip | tail -1`
+if [ "$LATEST" != "" ]; then
+  cp -p $LATEST ../v2.skip
+fi
+
+for FILE in `ls v2* | grep -v .gz`; do
+	gzip $FILE
+done
+
+
diff --git a/authz-batch/src/main/scripts/aafbch b/authz-batch/src/main/scripts/aafbch
new file mode 100644
index 0000000..fdeb22e
--- /dev/null
+++ b/authz-batch/src/main/scripts/aafbch
@@ -0,0 +1,21 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+cd $ROOT_DIR
+
+if [ "$1" = "InnerConsistency" ]; then
+	CLS=com.att.authz.temp.InnerConsistency
+	shift
+else
+	CLS=com.att.authz.Batch
+fi 
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+  CP=$CP:$FILE
+done
+
+date
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP $CLS $* 
+date
diff --git a/authz-batch/src/main/scripts/run_batch b/authz-batch/src/main/scripts/run_batch
new file mode 100644
index 0000000..c09ea0a
--- /dev/null
+++ b/authz-batch/src/main/scripts/run_batch
@@ -0,0 +1,16 @@
+#!/bin/env bash
+
+if [[ $# < 1 ]]; then
+    echo "USAGE: run_batch ExpiryNotification|ApprNotify|JobChange|RoleExpiration|ValidateUsers"
+    exit 1;
+fi
+
+JAVA_HOME=_JAVA_HOME_
+AAF_CP="_ROOT_DIR_/etc"
+for JAR in `find _ROOT_DIR_/lib -name *.jar` ; do
+  AAF_CP="$AAF_CP:$JAR"
+done
+
+$JAVA_HOME/bin/java -cp $AAF_CP com.att.authz.Batch $*
+
+