package gov.va.med.authentication.kernel.sspi.authentication.manageable;

import java.util.Enumeration;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.util.Properties;
import java.util.ResourceBundle;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.SQLException;
import javax.sql.DataSource;

import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;

import javax.management.MBeanException;
import javax.management.modelmbean.RequiredModelMBean;
import weblogic.management.security.authentication.AuthenticatorImpl;
import weblogic.management.utils.AlreadyExistsException;
import weblogic.management.utils.InvalidCursorException;
import weblogic.management.utils.NotFoundException;
import weblogic.security.spi.AuditorService;
import weblogic.security.spi.SecurityServices;
import weblogic.logging.NonCatalogLogger;



/**
 * The manageable authenticator's management mbean implementation.
 * It is used for managing users and groups.
 * It delegates the work to its corresponding database classe.
 *
 * It also posts audit events for its management operations (eg. createUser).
 *
 * Note that an authenticator is not allowed to have a user and a
 * group with the same name - that is, users and groups share one name space.
 *
 *
 * @author VHIT Security and Other Common Services (S&OCS)
 * @version 1.1.0.002
 */
public class KaajeeManageableAuthenticatorImpl extends AuthenticatorImpl
{
  // Manages the user and group definitions for this provider:
  private KaajeeUserGroupDatabase database;
  private PoolingDataSource dataSource = null;
  private static PoolableConnectionFactory poolableConnectionFactory = null;

  // Manages active queries (see listUsers, listGroups, listMemberGroups):
  private KaajeeListManager listManager = new KaajeeListManager();

  private static NonCatalogLogger sLogger = new NonCatalogLogger( "SSPI_Authentication_Providers_logs" );                                                               // (so we can remove the principals we added if the login is aborted)


  // The name of the realm containing this provider:
  private String realm;

  // The name of this provider:
  private String provider;
  private String schemaname="";;
  

  // The auditor for auditing user/group management operations.
  // This is only available if this provider was configured in
  // the default realm when the server was booted.
  private AuditorService auditor;

  /**
   * Standard mbean impl constructor.
   * When this constructor is called, it's too early to get the
   * mbean's corresponding client side proxy.
   * See the "init" method below for the work around.
   *
   * @throws MBeanException
   */
  public KaajeeManageableAuthenticatorImpl(RequiredModelMBean base) throws MBeanException
  {
    super(base);
  }

  /**
   * Initialize by finding the database object corresponding
   * to this provider's realm.
   *
   * To do this, get the client side mbean proxy.  This will
   * be used by the database class to find the realm and return
   * the proper database object.
   *
   * Note that this wasn't done in the constructor since
   * during the constructor, you can't access the client side
   * mbean proxy.  Instead, every method on this mbean needs
   * to call "init" so that the first method that's called
   * initializes the database object.
   *
   * @throws MBeanException
   */
  private synchronized void init() throws MBeanException
  {
	  Properties userprop = new Properties();
	  String JdbcConnectURI = null;
		if (database == null) {
		  try {
				KaajeeManageableAuthenticatorMBean myMBean = (KaajeeManageableAuthenticatorMBean)getProxy();
				database = KaajeeUserGroupDatabase.getDatabase(myMBean);
				realm    = myMBean.getRealm().getName();
				provider = myMBean.getName();
				SecurityServices services = database.getSecurityServices();
				auditor = (services != null) ? services.getAuditorService() : null;
			}catch(Exception e) {
					throw new MBeanException(e, "Manageable AuthenticatorImpl.init failed");
			}
		}
		if(dataSource == null){
		 try{
					ResourceBundle prop = ResourceBundle.getBundle("KaajeeDatabase");
					String driver = prop.getString("DriverName");
					String dbUserId = prop.getString("dbUserID");
					String dbpassword = prop.getString("Password");
					schemaname = prop.getString("schema");		// not used?
					JdbcConnectURI = prop.getString("db_URL");
					userprop.put("user", dbUserId);
					userprop.put("password", dbpassword);
					Class.forName(driver);
										
					//Properties prop = new Properties();
					//FileInputStream in = new FileInputStream(System.getProperties().getProperty("user.dir")+"/KaajeeDatabase.properties");
					//prop.load(in);
					//String driver = prop.getProperty("DriverName");
					//String dbUserId = prop.getProperty("dbUserID");
					//String dbpassword = prop.getProperty("Password");
					//schemaname = prop.getProperty("schema");
					//JdbcConnectURI = prop.getProperty("db_URL");

					
					
				}catch (ClassNotFoundException e) {
					sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase: " +e );
			}catch ( Exception e ) {
			 		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase: " +e );
					throw new RuntimeException(	"Exception while reading user data KaajeeUserGroupDatabase" + e.getMessage());
			}

		// First, we'll need a ObjectPool that serves as the
		  // actual pool of connections. We'll use a GenericObjectPool instance, although any ObjectPool implementation will suffice.
		  ObjectPool connectionPool = new GenericObjectPool(null);
		  // Next, we'll create a ConnectionFactory that the pool will use to create Connections.
		  // We'll use the DriverManagerConnectionFactory, using the connect string passed in the command line arguments.
		  ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(JdbcConnectURI,userprop);
		  // Now we'll create the PoolableConnectionFactory, which wraps
		  // the "real" Connections created by the ConnectionFactory with the classes that implement the pooling functionality.
		  poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true);
		  // Finally, we create the PoolingDriver itself, passing in the object pool we created.
		  dataSource = new PoolingDataSource(connectionPool);
		}
  }

  /**
   * See if a list has a current element (vs. has run out of elements).
   *
   * listUsers, listGroups and listMemberGroups return cursors that
   * are subsequently passed into these list handling methods.
   *
   * @param cursor a String containing a cursor that identifies a
   * previously returned list.
   *
   * @returns a boolean indicating if the list has a current element
   * (v.s. has already been traversed to the end).  The list initially
   * starts out at the first element (if there is one).
   *
   * @throws InvalidCursorException if the cursor does not represent
   * a currently active list.
   *
   * @throws MBeanException
   */
  public boolean haveCurrent(String cursor)
    throws MBeanException, InvalidCursorException
  {
    init();
    String details = (auditor != null) ?
      "haveCurrent(Cursor = " + cursor + ")" : null;
    try {
      boolean rtn = listManager.getList(cursor).haveCurrent();
      auditOperationSucceeded(details + " = " + rtn);
      return rtn;
    }
    //catch (InvalidCursorException   e) { auditOperationFailed(details, e); throw e; }
    catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Advance a list to the next element (or to the end of the list
   * if there are not more elements).
   *
   * listUsers, listGroups and listMemberGroups return cursors that
   * are subsequently passed into these list handling methods.
   *
   * @param cursor a String containing a cursor that identifies a
   * previously returned list.
   *
   * @throws InvalidCursorException if the cursor does not represent
   * a currently active list.
   *
   * @throws IllegalStateException if the list has already
   * been advanced to the end.
   *
   * @throws MBeanException
   */
  public void advance(String cursor)
    throws MBeanException, InvalidCursorException
  {
    init();
    String details = (auditor != null) ?
      "advance(Cursor = " + cursor + ")" : null;
    try {
      listManager.getList(cursor).advance();
      auditOperationSucceeded(details);
    }
    catch (InvalidCursorException   e) { auditOperationFailed(details, e); throw e; }
    catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Close the list.  This releases any memory or resources
   * held on behalf of the list.
   *
   * listUsers, listGroups and listMemberGroups return cursors that
   * are subsequently passed into these list handling methods.
   *
   * @param cursor a String containing a cursor that identifies a
   * previously returned list.
   *
   * @throws InvalidCursorException if the cursor does not represent
   * a currently active list.
   *
   * @throws MBeanException
   */
  public void close(String cursor)
    throws MBeanException, InvalidCursorException
  {
    init();
    String details = (auditor != null) ?
      "close(Cursor = " + cursor + ")" : null;
    try {
      listManager.getList(cursor).close();
      auditOperationSucceeded(details);
    }
    catch (InvalidCursorException   e) { auditOperationFailed(details, e); throw e; }
    catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Get the name of the current element on a list.
   *
   * listUsers, listGroups and listMemberGroups return cursors that
   * are subsequently passed into these list handling methods.
   *
   * @param cursor a String containing a cursor that identifies a
   * previously returned list.
   *
   * @return the name of the current element in the list.
   *
   * @throws InvalidCursorException if the cursor does not represent
   * a currently active list.
   *
   * @throws IllegalStateException if the list has already
   * been advanced to the end.
   *
   * @throws MBeanException
   */
  public String getCurrentName(String cursor)
    throws MBeanException, InvalidCursorException
  {
    init();
    String details = (auditor != null) ?
      "getCurrentName(Cursor = " + cursor + ")" : null;
    try {
      String rtn = listManager.getList(cursor).getCurrentName();
      auditOperationSucceeded(details + " = " + rtn);
      return rtn;
    }
    catch (InvalidCursorException   e) { auditOperationFailed(details, e); throw e; }
    catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Set a user's description.  The description is ignored since this
   * provider does not support descriptions.
   *
   * @param user a String containing the user's name.
   *
   * @param description a String containing the user's description.
   *
   * @throws NotFoundException if the user does not exist.
   *
   * @throws IllegalArgumentException if the user name is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public void setUserDescription(String user, String description)
    throws MBeanException, NotFoundException
  {
    init();
    String details = (auditor != null) ?
      "setUserDescription(user = " + user + ", description = " + description + ")" : null;
    try {
      database.getExistingUser(user); // for error checking
      // just ignore it - this sample doesn't support descriptions
      auditOperationSucceeded(details);
    }
    catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
    catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Set a group's description.  The description is ignored since this
   * provider does not support descriptions.
   *
   * @param group a String containing the group's name.
   *
   * @param description a String containing the group's description.
   *
   * @throws NotFoundException if the group does not exist.
   *
   * @throws IllegalArgumentException if the group name is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public void setGroupDescription(String group, String description)
  throws MBeanException, NotFoundException
  {
  	init();
  	String details = (auditor != null) ?
  			"setGroupDescription(group = " + group + ", description = " + description + ")" : null;
  	String rtn ="";
  	Connection conn = null;
  	PreparedStatement userStmt = null;
  	ResultSet rs = null;
  	try {
  		conn = getConnection();
  		userStmt = conn.prepareStatement("select count(*) from "+schemaname+".Principals where name = ? and isUser='false'");
  		userStmt.setString(1,group);
  		rs = userStmt.executeQuery();
  		if(rs.next()){
  			if(rs.getInt(1) > 0)
  				rtn = "";
  		}
  		
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rs != null)	rs.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (userStmt != null)	userStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {	
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	//database.getExistingGroup(group); // for error checking
  	// just ignore it - this sample doesn't support descriptions
  	try {
  		auditOperationSucceeded(details);
  	}
  	//catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Get a user's description.
   *
   * @param user a String containing the user's name.
   *
   * @return a String containing the user's description.  null is
   * always returned since this provider does not support descriptions.
   *
   * @throws NotFoundException if the user does not exist.
   *
   * @throws IllegalArgumentException if the user name is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public String getUserDescription(String user) 
    throws MBeanException, NotFoundException
  {
    init();
    String details = (auditor != null) ?
      "getUserDescription(user = " + user + ")" : null;
    try {
      database.getExistingUser(user); // for error checking
      // just return null - this sample doesn't support descriptions
      String rtn = null;
      auditOperationSucceeded(details + " = " + rtn);
      return rtn;
    }
    catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
    catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Get a group's description.
   *
   * @param group a String containing the group's name.
   *
   * @return a String containing the group's description.  null is
   * always returned since this provider does not support descriptions.
   *
   * @throws NotFoundException if the group does not exist.
   *
   * @throws IllegalArgumentException if the group name is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public String getGroupDescription(String group) 
  throws MBeanException, NotFoundException
  {
  	init();
  	String details = (auditor != null) ?
  			"getGroupDescription(group = " + group + ")" : null;
  	String rtn = "";
  	Connection conn = null;
  	PreparedStatement userStmt = null;
  	ResultSet rs = null;
  	try{
  		conn = getConnection();
  		userStmt = conn.prepareStatement("select count(*) from "+schemaname+".Principals where name = ? and isUser='false'");
  		userStmt.setString(1,group);
  		rs = userStmt.executeQuery();
  		if(rs.next()){
  			if(rs.getInt(1) > 0)
  				rtn = " ";
  		} else 
  			rtn = null;
  		rs.close();
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rs != null)	rs.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (userStmt != null)	userStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {	
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	// String rtn = null;
  	try {
  		auditOperationSucceeded(details + " = " + rtn);
  		return rtn;
  	}
  	//  catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Determines if a group exists.
   *
   * @param group a String containing the group's name.
   *
   * @return a boolean indicating if the group exists.
   *
   * @throws IllegalArgumentException if the group name is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public boolean groupExists(String group)
  throws MBeanException
  {
  	init();
  	String details = (auditor != null) ?
  			"groupExists(group = " + group + ")" : null;
  	boolean rtn = false;
  	Connection conn = null;
  	PreparedStatement userStmt = null;
  	ResultSet rs = null;
  	try {
  		conn = getConnection();
  		userStmt = conn.prepareStatement("select count(*) from "+schemaname+".Principals where name = ? and isUser='false'");
  		userStmt.setString(1,group);
  		rs = userStmt.executeQuery();
  		if(rs.next()){
  			if(rs.getInt(1) > 0)
  				rtn = true;
  		}
  		rs.close();
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rs != null)	rs.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (userStmt != null)	userStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {	
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	try {
  		auditOperationSucceeded(details + " = " + rtn);
  		return rtn;
  	} catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Determines whether or not a member (user or group) is a member of another group.
   *
   * @param group a String containing the name of the group that might contain the member
   *
   * @param member a String containing the name of the member (that is, a
   * user or group)
   *
   * @param recursive a boolean indicating that the member should immediately
   * (false) or indirectly a member (true) a member of the group.
   * If group2 contains group1 and group1 contiains user1, then
   * user1 is immediately a member of group1 and indirectly a member
   * of group1 and group2.
   *
   * @return a boolean indicating if the member is a member of the group.
   *
   * @throws NotFoundException if the member or the group does not exist.
   *
   * @throws IllegalArgumentException if the member or group name
   * is invalid (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public boolean isMember(String group, String member, boolean recursive)
  throws MBeanException, NotFoundException
  {
  	init();
  	String details = (auditor != null) ?
  			"isMember(group = " + group + ", member = " + member + ", recursive = " + recursive + ")" : null;
  	boolean rtn = false;
  	Connection conn = null;
  	PreparedStatement userStmt = null;
  	ResultSet rs = null;
  	try {
  		conn = getConnection();
  		userStmt = conn.prepareStatement("select count(*) from "+schemaname+".GroupMembers where mygroup = ? and principal = ?");
  		userStmt.setString(1,group);
  		userStmt.setString(2,member);
  		rs = userStmt.executeQuery();
  		if (rs.next()){
  			if(rs.getInt(1) > 0)
  				rtn = true;
  		}
  		rs.close();	
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rs != null)	rs.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (userStmt != null)	userStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {	
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	
  	
  	try {
  		auditOperationSucceeded(details + " = " + rtn);
  		return rtn;
  	}
  	// catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Creates a group.  Initially, the group is not a member of any other groups.
   *
   * @param group a String containing the new group's name.
   *
   * @param description a String containing the new group's
   * description.  This parameter is ignored since this provider
   * does not support descriptions.
   *
   * @throws AlreadyExistsException if a group or user with that
   * name already exists.
   *
   * @throws IllegalArgumentException if the group name is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public void createGroup(String group, String description) throws MBeanException, AlreadyExistsException
  {
  	//System.out.println("created       Group " );
  	init();
  	String details = (auditor != null) ?
  			"createGroup(group = " + group + ", description = " + description + ")" : null;
  	Connection conn = null;
  	PreparedStatement groupStmt = null;
  	try {
  		conn = getConnection();
  		groupStmt = conn.prepareStatement("insert into "+schemaname+".principals (name, isUser, password) values (?,?,?)");
  		groupStmt.setString(1, group);
  		groupStmt.setString(2, "false");
  		groupStmt.setString(3, null);
  		groupStmt.executeUpdate();
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (groupStmt != null)	groupStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {	
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	try {
  		auditOperationSucceeded(details);
  	}
  	//catch (AlreadyExistsException   e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Adds a member to a group.
   *
   * Does nothing if the member is already a member of the group
   * either directly or indirectly.
   *
   * Also does nothing if the member is a group, and it directly
   * or indirectly contains the group.  That is, do not allow
   * cyclic membership (group1 is a member of group2 and group2 is
   * a member of group1).
   *
   * @param group a String containing the group's name.
   *
   * @param member a String containing the member's (user or group) name.
   *
   * @throws NotFoundException if the group or member does not exist.
   *
   * @throws IllegalArgumentException if the group or member name
   * is invalid (eg. begins with whitespace).
   *
   * @throws MBeanException
   */ 
  public void addMemberToGroup(String group, String member) throws MBeanException, NotFoundException
  {
  	//System.out.println("Entered addMemberToGroup    ");
  	init();
  	String details = (auditor != null) ?
  			"addMemberToGroup(group = " + group + ", member = " + member + ")" : null;
  	Connection conn = null;
  	PreparedStatement addMemGroupStmt = null;
  	PreparedStatement selGroupStmt = null;
  	PreparedStatement addGroupStmt = null;
  	ResultSet rs = null;
  	
  	try {
  		conn = getConnection();
  		selGroupStmt = conn.prepareStatement("select count(*) from "+schemaname+".Principals where name = ?");
  		selGroupStmt.setString(1,group);
  		rs = selGroupStmt.executeQuery();
  		if(rs.next()){
  			if(rs.getInt(1) == 0){
  				addGroupStmt = conn.prepareStatement("insert into "+schemaname+".Principals (name, isUser, password) values (?,?,?)");
  				addGroupStmt.setString(1, group);
  				addGroupStmt.setString(2, "false");
  				addGroupStmt.setString(3, null);
  				addGroupStmt.executeUpdate();
  			}
  		}
  		addMemGroupStmt = conn.prepareStatement("insert into "+schemaname+".GroupMembers (principal,mygroup) values (?,?)");
  		addMemGroupStmt.setString(1, member);
  		addMemGroupStmt.setString(2, group);
  		addMemGroupStmt.executeUpdate();
  		
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rs != null)	rs.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try{
  			if (addMemGroupStmt != null)	addMemGroupStmt.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (addGroupStmt != null)	addGroupStmt.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (selGroupStmt != null)	selGroupStmt.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	try { 
  		auditOperationSucceeded(details);
  	}
  	//catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Removes a member from a group.  Does nothing if the member is
   * not an immediate member of the group.
   *
   * @param group a String containing the group's name.
   *
   * @param member a String containing the member's (user or group) name.
   *
   * @throws NotFoundException if the group or member does not exist.
   *
   * @throws IllegalArgumentException if the group or member name
   * is invalid (eg. begins with whitespace).
   *
   * @throws MBeanException
   */ 
  public void removeMemberFromGroup(String group, String member) throws MBeanException, NotFoundException
  {
  	//   System.out.println("removeMemberFromGroup(String group, String member)  ");
  	init();
  	String details = (auditor != null) ?
  			"removeMemberFromGroup(group = " + group + ", member = " + member + ")" : null;
  	Connection conn = null;
  	PreparedStatement rmMemGroupStmt = null;
  	try {
  		conn = getConnection();
  		rmMemGroupStmt = conn.prepareStatement("delete from "+schemaname+".GroupMembers where principal =? and mygroup=?");
  		rmMemGroupStmt.setString(1, member);
  		rmMemGroupStmt.setString(2, group);
  		rmMemGroupStmt.executeUpdate();
  		
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rmMemGroupStmt != null)	rmMemGroupStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {	
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	try {
  		auditOperationSucceeded(details);
  	}
  	//catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }
  /**
   * Removes a group.
   *
   * Since in this database, a member contains a list of the
   * groups that contain immediately contain it, update all the
   * members to remove their membership in this group.
   *
   * @param group a String containing the group's name.
   *
   * @throws NotFoundException if the group does not exist.
   *
   * @throws IllegalArgumentException if the group name is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */ 
  public void removeGroup(String group)   throws MBeanException, NotFoundException
  {
  	// System.out.println("removeGroup");
  	init();
  	String details = (auditor != null) ?
  			"removeGroup(group = " + group + ")" : null;
  	Connection conn = null;
  	PreparedStatement rmGroupStmt = null;
  	PreparedStatement rmGroupStmt1 = null;
  	try {
  		conn = getConnection();
  		rmGroupStmt = conn.prepareStatement("delete from "+schemaname+".Principals where name =? and isUser='false'");
  		rmGroupStmt.setString(1, group);
  		rmGroupStmt.executeUpdate();
  		rmGroupStmt1 = conn.prepareStatement("delete from "+schemaname+".groupmembers where mygroup = ? ");
  		rmGroupStmt1.setString(1, group);
  		rmGroupStmt1.executeUpdate();
  		
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rmGroupStmt1 != null)	rmGroupStmt1.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (rmGroupStmt != null)	rmGroupStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	
  	try {
  		auditOperationSucceeded(details);
  	}
  	//	catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }
  
  /**
	 * List this provider's groups.
	 *
	 * @param groupNameWildcard a String indicating which group names
	 * should be returned.  There are three forms:
	 *   "*"      : return all group names
	 *   "Foo*"   : return all groups whose names starts with "Foo"
	 *   "FooBar" : only return a group named "FooBar"
	 * The match is case sensitive.
	 *
	 * @param max an int indicating the maximum number of group names
	 * that will be returned.  The value must be greater than zero.
	 * If there are more than max matches, only max matches will be
	 * returned.  It is arbitrary which matches will be returned.
	 *
	 * @return a String containing a cursor that represents the returned
	 * list.  Pass this cursor to the haveCurrent, advance, getCurrentName
	 * and close methods to get the list results.
	 *
	 * @throws IllegalArgumentException if the wildcard is invalid
	 * (eg. begins with whitespace).
	 *
	 * @throws MBeanException
	 */
  public String listGroups(String groupNameWildcard, int maximumToReturn)	  throws MBeanException
  {
  	//System.out.println("listGroups");
  	init();
  	String details = (auditor != null) ?
  			"listGroups(groupNameWildcard = " + groupNameWildcard + ", maximumToReturn = " + maximumToReturn + ")" : null;
  	
  	List list = new ArrayList();
  	Connection conn = null;
  	PreparedStatement groupStmt = null;
  	ResultSet rs = null;
  	try {
  		conn = getConnection();
  		groupStmt = conn.prepareStatement("select name from "+schemaname+".Principals where isUser='false'");
  		rs = groupStmt.executeQuery();
  		while (rs.next()){
  			list.add(rs.getString("name"));
  		}
  		
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rs != null)	rs.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (groupStmt != null)	groupStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	try {
  		String rtn = listManager.registerList(  new KaajeeUserOrGroupList(database, false, groupNameWildcard, maximumToReturn));
  		auditOperationSucceeded(details + " = " + rtn);
  		return rtn;
  	}
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }
	
  /**
   * List the groups that a member (that is, user or group) is immediately
   * a member of.  Since a member is usually not a member of many groups,
   * there is no max to return argument.
   *
   * @param member a String containing the name of a user or group.
   *
   * @return a String containing a cursor that represents the returned
   * list.  Pass this cursor to the haveCurrent, advance, getCurrentName
   * and close methods to get the list results.
   *
   * @throws NotFoundException if the member does not exist.
   *
   * @throws IllegalArgumentException if the member name is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public String listMemberGroups(String member)   throws MBeanException, NotFoundException
  {
  	//System.out.println("KaajeeManageableAuthenticatorImpl   listMemberGroups  member value  ");
  	init();
  	String details = (auditor != null) ?
  			"listMemberGroups(member = " + member + ")" : null;
  	List list = new ArrayList();
  	Connection conn = null;
  	PreparedStatement groupStmt = null;
  	ResultSet rs = null;
  	try {
  		//System.out.println("KaajeeManageableAuthenticatorImpl   listMemberGroups  (mygroup)   " + member);
  		conn = getConnection();
  		groupStmt = conn.prepareStatement("select principal from "+schemaname+".groupmembers where mygroup = ?");
  		groupStmt.setString(1,member);
  		
  		rs = groupStmt.executeQuery();
  		while (rs.next()){
  			list.add(rs.getString("principal"));
  			// System.out.println("KaajeeManageableAuthenticatorImpl   listMemberGroups  rs.getString(mygroup)   " + rs.getString("principal"));
  			
  		}
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rs != null)	rs.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (groupStmt != null)	groupStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	try {
  		String rtn = listManager.registerList( new KaajeeMemberGroupsList(database.getExistingPrincipal(member).getImmediateParentGroups()));
  		auditOperationSucceeded(details + " = " + rtn);
  		return rtn;
  	}
  	//catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * List this provider's users.
   *
   * @param groupNameWildcard a String indicating which user names
   * should be returned.  There are three forms:
   *   "*"      : return all user names
   *   "Foo*"   : return all users whose names starts with "Foo"
   *   "FooBar" : only return a user named "FooBar"
   * The match is case sensitive.
   *
   * @param max an int indicating the maximum number of user names
   * that will be returned.  The value must be greater than zero.
   * If there are more than max matches, only max matches will be
   * returned.  It is arbitrary which matches will be returned.
   *
   * @return a String containing a cursor that represents the returned
   * list.  Pass this cursor to the haveCurrent, advance, getCurrentName
   * and close methods to get the list results.
   *
   * @throws IllegalArgumentException if the wildcard is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public String listUsers(String userNameWildcard, int maximumToReturn)   throws MBeanException
  {
  	//System.out.println("KaajeeManageableAuthenticatorImpl listUsers");
  	init();
  	String details = (auditor != null) ?
  			"listUsers(userNameWildcard = " + userNameWildcard + ", maximumToReturn = " + maximumToReturn + ")" : null;
  	List list = new ArrayList();
  	Connection conn = null;
  	PreparedStatement userStmt = null;
  	ResultSet rs = null;
  	try {
  		conn = getConnection();
  		userStmt = conn.prepareStatement("select name from "+schemaname+".Principals where isUser='true'");
  		rs = userStmt.executeQuery();
  		while (rs.next()){
  			list.add(rs.getString("name"));
  		}
  		
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rs != null)	rs.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (userStmt != null)	userStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	String rtn = listManager.registerList(new KaajeeUserOrGroupList(database, true, userNameWildcard, maximumToReturn));
  	//System.out.println(" listUsers  rtn  "+ rtn);
  	try {
  		auditOperationSucceeded(details + " = " + rtn);
  		return rtn;
  	}
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Determines if a user exists.
   *
   * @param user a String containing the user's name.
   *
   * @return a boolean indicating if the user exists.
   *
   * @throws IllegalArgumentException if the user name is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public boolean userExists(String user)    throws MBeanException
  {
  	//System.out.println("userExists");
  	init();
  	String details = (auditor != null) ?
  			"userExists(user = " + user + ")" : null;
  	boolean rtn = false;
  	Connection conn = null;
  	PreparedStatement userStmt = null;
  	ResultSet rs = null;
  	try {
  		conn = getConnection();
  		userStmt = conn.prepareStatement("select count(*) from "+schemaname+".Principals where name = ? and isUser='true'");
  		userStmt.setString(1,user);
  		rs = userStmt.executeQuery();
  		if (rs.next()){
  			if(rs.getInt(1) > 0)
  				rtn = true;
  		}
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rs != null)	rs.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (userStmt != null)	userStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	try {
  		auditOperationSucceeded(details + " = " + rtn);
  		return rtn;
  	}
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Creates a user.  Initially, the user is not a member of any groups.
   *
   * @param user a String containing the new user's name.
   *
   * @param password a String containing the new user's password.
   *
   * @param description a String containing the new user's
   * description.  This parameter is ignored since this provider
   * does not support descriptions.
   *
   * @throws AlreadyExistsException if a group or user with that
   * name already exists.
   *
   * @throws IllegalArgumentException if the user name or password
   * is invalid (eg. begins with whitespace).
   *
   * @throws MBeanException
   */
  public void createUser(String user, String password, String description)  throws MBeanException, AlreadyExistsException
  {
  	//System.out.println("created    User   ");
  	
  	Connection conn = null;
  	PreparedStatement userstmt = null;
  	init();
  	String details = (auditor != null) ?
  			"createUser(user = " + user + ", password = " + password + ", description = " + description + ")" : null;
  	try {
  		try {
  			password = BootUserPasswordEncryption.getInstance().encrypt(password);
  		} catch(Exception e){ }
  		conn = getConnection();
  		userstmt = conn.prepareStatement("insert into "+schemaname+".Principals (name, isUser, password) values (?,?,?)");
  		userstmt.setString(1, user);
  		userstmt.setString(2, "true");
  		userstmt.setString(3, password);
  		userstmt.executeUpdate();
  		
  		
  	} catch (Exception e) {
  		e.printStackTrace();
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (userstmt != null)	userstmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {	
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	
  	try {
  		auditOperationSucceeded(details);
  	}
  	//catch (AlreadyExistsException   e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Change a user's password.
   *
   * This is supposed to be called by the user, therefore the old
   * and new passwords are required.
   *
   * @param user a String containing the user's name.
   *
   * @param oldPassword a String containing the user's current password.
   *
   * @param newPassword a String containing the user's new password.
   *
   * @throws NotFoundException if the user does not exist.
   *
   * @throws IllegalArgumentException if the user name or new password
   * is invalid (eg. begins with whitespace).  Also thrown if the
   * old password is incorrect.
   *
   * @throws MBeanException
   */
  public void changeUserPassword(String user, String oldPassword, String newPassword)    throws MBeanException, NotFoundException
  {
  	init();
  	String details = (auditor != null) ?
  			"changeUserPassword(user = " + user + ", oldPassword = " + oldPassword + ", newPassword = " + newPassword + ")" : null;
  	PreparedStatement updStmt = null;
  	Connection conn = null;
  	try {
  		try {
  			newPassword = BootUserPasswordEncryption.getInstance().encrypt(newPassword);
  		} catch (Exception e){}
  		conn = getConnection();
  		updStmt = conn.prepareStatement("update "+schemaname+".principals set password=? where name=? and isuser='true' and password=?");
  		updStmt.setString(1, newPassword);
  		updStmt.setString(2, user);
  		updStmt.setString(3, oldPassword);
  		updStmt.executeUpdate();
  		
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		
  		try {
  			if (updStmt != null)	updStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {	
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	try {
  		auditOperationSucceeded(details);
  	}
  	//catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Reset a user's password.
   *
   * This is supposed to be called by an administrator (who shouldn't
   * know the old password), therefore only the new password is required.
   *
   * @param user a String containing the user's name.
   *
   * @param newPassword a String containing the user's new password.
   *
   * @throws NotFoundException if the user does not exist.
   *
   * @throws IllegalArgumentException if the user name or new password
   * is invalid (eg. begins with whitespace).
   *
   * @throws MBeanException
   */ 
  public void resetUserPassword(String user, String newPassword) throws MBeanException, NotFoundException
  {
  	init();
  	String details = (auditor != null) ?
  			"resetUserPassword(user = " + user + ", newPassword = " + newPassword + ")" : null;
  	PreparedStatement updStmt = null;
  	Connection conn = null;
  	try {
  		newPassword = BootUserPasswordEncryption.getInstance().encrypt(newPassword);
  	} catch (Exception e){
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  	}
  	try {
  		/*try{
  		 newPassword = PasswordEncryption.getInstance().encrypt(newPassword);
  		 }catch(Exception e){
  		 System.out.println(e.getMessage());
  		 }*/
  		conn = getConnection();
  		updStmt = conn.prepareStatement("update "+schemaname+".principals set password=? where name=? and isuser='true'");
  		updStmt.setString(1, newPassword);
  		updStmt.setString(2, user);
  		updStmt.executeUpdate();
  		
  	} catch (Exception e) {
  		sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		
  		try {
  			if (updStmt != null)	updStmt.close();	
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {	
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	try {
  		auditOperationSucceeded(details);
  	}
  	//catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Removes a user.
   *
   * Since in this database, a member contains a list of the
   * groups that contain immediately contain it, there is no
   * no need to update any groups when a user is removed.
   *
   * @param user a String containing the user's name.
   *
   * @throws NotFoundException if the user does not exist.
   *
   * @throws IllegalArgumentException if the user name is invalid
   * (eg. begins with whitespace).
   *
   * @throws MBeanException
   */ 
  public void removeUser(String user)  throws MBeanException, NotFoundException
  {
  	//System.out.println("removeUser     ");
  	init();
  	String details = (auditor != null) ?
  			"removeUser(user = " + user + ")" : null;
  	
  	Connection conn = null;
  	ResultSet rs = null;
  	PreparedStatement rmUserStmt = null;
  	PreparedStatement groupmemStmt = null;
  	PreparedStatement selectUserStmt = null;
  	try {
  		conn = getConnection();
  		rmUserStmt = conn.prepareStatement("delete from "+schemaname+".Principals where name = ? and isUser='true'");
  		rmUserStmt.setString(1, user);
  		rmUserStmt.executeUpdate();
  		
  		selectUserStmt = conn.prepareStatement("select count(*) from "+schemaname+".GroupMembers where principal=? ");
  		selectUserStmt.setString(1, user);
  		rs = selectUserStmt.executeQuery();
  		if(rs.next()){
  			if(rs.getInt(1) > 0){
  				groupmemStmt = conn.prepareStatement("delete from "+schemaname+".GroupMembers where principal =?");
  				groupmemStmt.setString(1, user);
  				groupmemStmt.executeUpdate();
  			}
  		}
  		
  		//
  		
  	} catch (Exception e) {
  		e.printStackTrace();
  		throw new RuntimeException("Exception occured while reading user data");
  	}
  	finally {
  		try {
  			if (rs != null)	rs.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (groupmemStmt != null)	groupmemStmt.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (selectUserStmt != null)	selectUserStmt.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (rmUserStmt != null)	rmUserStmt.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  		try {
  			if (conn != null)	conn.close();
  		} catch (SQLException e) {
  			sLogger.debug( "Exception while reading user data KaajeeUserGroupDatabase   "+ e);
  			throw new RuntimeException("Exception occured while reading user data");
  		}
  	}
  	try {
  		auditOperationSucceeded(details);
  	}
  	//catch (NotFoundException        e) { auditOperationFailed(details, e); throw e; }
  	catch (IllegalArgumentException e) { auditOperationFailed(details, e); throw e; }
  }

  /**
   * Post an audit event indicating that a management operation succeeded.
   *
   * Does nothing if there is no auditor avaiable (that is, the provider was
   * not a configured in the default realm when the server was booted).
   *
   * @param details a String containing the name of the operation,
   * the input parameters (if any) and return value (if any).
   */
  private void auditOperationSucceeded(String details)  {
    if (auditor != null) {
      auditor.providerAuditWriteEvent(
        new KaajeeManageableAuthenticatorManagementEvent(realm, provider, details, null)
      );
    }
  }

  /**
   * Post an audit event indicating that a management operation failed.
   *
   * Does nothing if there is no auditor avaiable (that is, the provider was
   * not a configured in the default realm when the server was booted).
   *
   * @param details a String containing the name of the operation and
   * its input parameters (if any).
   *
   * @param failureException an Exception containing the reason the
   * management operation failed.
   */
  private void auditOperationFailed(String details, Exception failureException)
  {
    if (auditor != null) {
      auditor.providerAuditWriteEvent(
        new KaajeeManageableAuthenticatorManagementEvent(realm, provider, details, failureException)
      );
    }
  }
  private Connection getConnection() throws Exception{
		Connection connection = null;
		try{
				connection = dataSource.getConnection();
		
		} catch ( Exception e ) {
			  sLogger.debug( "Exception while trying to get the database connection   "+ e);
			  //System.out.println("Error checking for user or group existance: " +e );
			  throw new RuntimeException(	"Exception while reading user data KaajeeUserGroupDatabase" + e.getMessage());
		   }
		//catch (ClassNotFoundException e) {
		//			e.printStackTrace();
		//		}
		return connection;
	//	return DriverManager.getConnection("jdbc:oracle:thin:@ISFUX01:1521:dev01","SSO","sso");
	}
 
}
