diff --git a/www/editgroup.php3 b/www/editgroup.php3
index b55b3f5fec8d7323216e40d939dcf910f56d3e1a..a2c8484511ea27ad54cf067fec6f0aca325b0187 100644
--- a/www/editgroup.php3
+++ b/www/editgroup.php3
@@ -8,9 +8,9 @@ include("defs.php3");
 include("showstuff.php3");
 
 #
-# No testbed header since we spit out a redirect.
+# Standard Testbed Header
 #
-ignore_user_abort(1);
+PAGEHEADER("Edit Group Membership");
 
 #
 # Only known and logged in users.
@@ -46,7 +46,7 @@ if (! ($group = Group::LookupByPidGid($pid, $gid))) {
 #
 # Verify permission. 
 #
-if (! TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_EDITGROUP)) {
+if (! $group->AccessCheck($this_user, $TB_PROJECT_EDITGROUP)) {
     USERERROR("You do not have permission to edit group $gid in ".
 	      "project $pid!", 1);
 }
@@ -55,7 +55,7 @@ if (! TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_EDITGROUP)) {
 # See if user is allowed to add non-members to group.
 # 
 $grabusers = 0;
-if (TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_GROUPGRABUSERS)) {
+if ($group->AccessCheck($this_user, $TB_PROJECT_GROUPGRABUSERS)) {
     $grabusers = 1;
 }
 
@@ -63,7 +63,7 @@ if (TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_GROUPGRABUSERS)) {
 # See if user is allowed to bestow group_root upon members of group.
 # 
 $bestowgrouproot = 0;
-if (TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_BESTOWGROUPROOT)) {
+if ($group->AccessCheck($this_user, $TB_PROJECT_BESTOWGROUPROOT)) {
     $bestowgrouproot = 1;
 }
 
@@ -72,11 +72,7 @@ if (TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_BESTOWGROUPROOT)) {
 # removed! Do not include members that have not been approved to main
 # group either! This will force them to go through the approval page first.
 #
-$curmembers_result =
-    DBQueryFatal("select distinct m.uid, m.trust from group_membership as m ".
-		 "left join groups as g on g.pid=m.pid and g.gid=m.gid ".
-		 "where m.pid='$pid' and m.gid='$gid' and ".
-		 "      m.uid!=g.leader and m.trust!='none'");
+$curmembers = $group->MemberList();
 
 #
 # Grab the user list from the project. These are the people who can be
@@ -84,13 +80,7 @@ $curmembers_result =
 # include members that have not been approved to main group either! This
 # will force them to go through the approval page first.
 # 
-$nonmembers_result =
-    DBQueryFatal("select m.uid from group_membership as m ".
-		 "left join group_membership as a on ".
-		 "     a.uid=m.uid and a.pid=m.pid and a.gid='$gid' ".
-		 "where m.pid='$pid' and m.gid=m.pid and a.uid is NULL ".
-		 "      and m.trust!='none'");
-
+$nonmembers = $group->NonMemberList();
 
 #
 # First pass does checks. Second pass does the real thing. 
@@ -102,11 +92,11 @@ $nonmembers_result =
 # from the group membership. Otherwise, look to see if the trust level
 # has been changed.
 # 
-if (mysql_num_rows($curmembers_result)) {
-    while ($row = mysql_fetch_array($curmembers_result)) {
-	$user     = $row[0];
-	$oldtrust = $row[1];
-	$foo      = "change_$user";
+if (count($curmembers)) {
+    foreach ($curmembers as $target_user) {
+	$target_uid = $target_user->uid();
+	$oldtrust   = $target_user->GetTempData();
+	$foo        = "change_$target_uid";    
 
 	#
 	# Is member to be deleted?
@@ -116,25 +106,21 @@ if (mysql_num_rows($curmembers_result)) {
 	    continue;
 	}
 
-	if (! ($target_user = User::Lookup($user))) {
-	    TBERROR("Could not find user object for $user", 1);
-	}
-
         #
         # There should be a corresponding trust variable in the POST vars.
         # Note that we construct the variable name and indirect to it.
         #
-        $foo      = "$user\$\$trust";
+        $foo      = "$target_uid\$\$trust";
 	$newtrust = $$foo;
 	
 	if (!$newtrust || strcmp($newtrust, "") == 0) {
-	    TBERROR("Error finding trust for $user in editgroup.php3", 1);
+	    TBERROR("Error finding trust for $target_uid in editgroup", 1);
 	}
 
-	if (strcmp($newtrust, "user") &&
-	    strcmp($newtrust, "local_root") &&
-	    strcmp($newtrust, "group_root")) {
-	    TBERROR("Invalid trust $newtrust for $user in editgroup.php3.", 1);
+	if (strcmp($newtrust, TBDB_TRUSTSTRING_USER) &&
+	    strcmp($newtrust, TBDB_TRUSTSTRING_LOCALROOT) &&
+	    strcmp($newtrust, TBDB_TRUSTSTRING_GROUPROOT)) {
+	    TBERROR("Invalid trust $newtrust for $target_uid in editgroup", 1);
 	}
 
 	#
@@ -143,7 +129,7 @@ if (mysql_num_rows($curmembers_result)) {
 	# permitted.
 	#
 	if (strcmp($newtrust, $oldtrust) &&
-	    !strcmp($newtrust, "group_root") && 
+	    !strcmp($newtrust, TBDB_TRUSTSTRING_GROUPROOT) && 
 	    !$bestowgrouproot) {
 	    USERERROR("You do not have permission to bestow group root".
 		      "trust to users in $pid/$gid!", 1 );
@@ -151,6 +137,7 @@ if (mysql_num_rows($curmembers_result)) {
 
 	$group->CheckTrustConsistency($target_user, $newtrust, 1);
     }
+    reset($curmembers);
 }
 
 #
@@ -160,44 +147,38 @@ if (mysql_num_rows($curmembers_result)) {
 # Only do this if user has permission to grab users. 
 #
 
-if ($grabusers && !$defaultgroup && mysql_num_rows($nonmembers_result)) {
-    while ($row = mysql_fetch_array($nonmembers_result)) {
-	$user = $row[0];
-	$foo  = "add_$user";
+if ($grabusers && !$defaultgroup && count($nonmembers)) {
+    foreach ($nonmembers as $target_user) {
+	$target_uid = $target_user->uid();
+	$foo        = "add_$target_uid";    
 	
 	if (isset($$foo)) {
 	    #
 	    # There should be a corresponding trust variable in the POST vars.
 	    # Note that we construct the variable name and indirect to it.
 	    #
-	    $bar      = "$user\$\$trust";
+	    $bar      = "$target_uid\$\$trust";
 	    $newtrust = $$bar;
 	    
 	    if (!$newtrust || strcmp($newtrust, "") == 0) {
-		TBERROR("Error finding trust for $user in editgroup.php3",
-			1);
+		TBERROR("Error finding trust for $target_uid", 1);
 	    }
 	    
-	    if (strcmp($newtrust, "user") &&
-		strcmp($newtrust, "local_root") &&
-		strcmp($newtrust, "group_root")) {
-		TBERROR("Invalid trust $newtrust for $user in editgroup.php3.",
-			1);
+	    if (strcmp($newtrust, TBDB_TRUSTSTRING_USER) &&
+		strcmp($newtrust, TBDB_TRUSTSTRING_LOCALROOT) &&
+		strcmp($newtrust, TBDB_TRUSTSTRING_GROUPROOT)) {
+		TBERROR("Invalid trust $newtrust for $target_uid", 1);
 	    }
 
-	    if (!strcmp($newtrust, "group_root")
+	    if (!strcmp($newtrust, TBDB_TRUSTSTRING_GROUPROOT)
 		&& !$bestowgrouproot) {
 		USERERROR("You do not have permission to bestow group root".
 			  "trust to users in $pid/$gid!", 1 );
 	    }
-
-	    if (! ($target_user = User::Lookup($user))) {
-		TBERROR("Could not find user object for $user", 1);
-	    }
-
 	    $group->CheckTrustConsistency($target_user, $newtrust, 1);
 	}
     }
+    reset($nonmembers);
 }
 
 #
@@ -205,7 +186,9 @@ if ($grabusers && !$defaultgroup && mysql_num_rows($nonmembers_result)) {
 #
 # Grab the unix GID for running scripts.
 #
-TBGroupUnixInfo($pid, $pid, $unix_gid, $unix_name);
+$unix_gid = $group->unix_gid();
+
+STARTBUSY("Applying group membership changes");
 
 #
 # Go through the list of current members. For each one, check to see if
@@ -213,28 +196,28 @@ TBGroupUnixInfo($pid, $pid, $unix_gid, $unix_name);
 # from the group membership. Otherwise, look to see if the trust level
 # has been changed.
 #
-if (mysql_num_rows($curmembers_result)) {
-    mysql_data_seek($curmembers_result, 0);
-    
-    while ($row = mysql_fetch_array($curmembers_result)) {
-	$user = $row[0];
-	$oldtrust = $row[1];
-	$foo  = "change_$user";
+if (count($curmembers)) {
+    foreach ($curmembers as $target_user) {
+	$target_uid = $target_user->uid();
+	$oldtrust   = $target_user->GetTempData();
+	$foo        = "change_$target_uid";    
 
 	if (!$defaultgroup && !isset($$foo)) {
-	    SUEXEC($uid, $unix_gid, "webmodgroups -r $pid:$gid $user", 1);
+	    SUEXEC($uid, $unix_gid, "webmodgroups -r $pid:$gid $target_uid",
+		   SUEXEC_ACTION_DIE);
 	    continue;
 	}
         #
         # There should be a corresponding trust variable in the POST vars.
         # Note that we construct the variable name and indirect to it.
         #
-        $foo      = "$user\$\$trust";
+        $foo      = "$target_uid\$\$trust";
 	$newtrust = $$foo;
 	
 	if (strcmp($oldtrust,$newtrust)) {
 	    SUEXEC($uid, $unix_gid,
-		   "webmodgroups -m $pid:$gid:$newtrust $user", 1);
+		   "webmodgroups -m $pid:$gid:$newtrust $target_uid",
+		   SUEXEC_ACTION_DIE);
 	}
     }
 }
@@ -245,32 +228,36 @@ if (mysql_num_rows($curmembers_result)) {
 # to the group membership, with the trust level specified.
 # 
 
-if ($grabusers && !$defaultgroup && mysql_num_rows($nonmembers_result)) {
-    mysql_data_seek($nonmembers_result, 0);
-    
-    while ($row = mysql_fetch_array($nonmembers_result)) {
-	$user = $row[0];
-	$foo  = "add_$user";
+if ($grabusers && !$defaultgroup && count($nonmembers)) {
+    foreach ($nonmembers as $target_user) {
+	$target_uid = $target_user->uid();
+	$foo        = "add_$target_uid";    
 	
 	if (isset($$foo)) {
 	    #
 	    # There should be a corresponding trust variable in the POST vars.
 	    # Note that we construct the variable name and indirect to it.
 	    #
-	    $bar      = "$user\$\$trust";
+	    $bar      = "$target_uid\$\$trust";
 	    $newtrust = $$bar;
 
 	    SUEXEC($uid, $unix_gid,
-		   "webmodgroups -a $pid:$gid:$newtrust $user", 1);
+		   "webmodgroups -a $pid:$gid:$newtrust $target_uid",
+		   SUEXEC_ACTION_DIE);
 	}
     }
 }
 
+STOPBUSY();
+
 #
 # Spit out a redirect so that the history does not include a post
 # in it. The back button skips over the post and to the form.
 # 
-header("Location: showgroup.php3?pid=$pid&gid=$gid");
+PAGEREPLACE("showgroup.php3?pid=$pid&gid=$gid");
 
-# No Testbed footer.
+#
+# Standard Testbed Footer
+# 
+PAGEFOOTER();
 ?>
diff --git a/www/editgroup_form.php3 b/www/editgroup_form.php3
index c72875ca540363498371ea848ebb84fca8db3c24..e5c5c190b25cfbcd74bf7c0232482397cc980709 100644
--- a/www/editgroup_form.php3
+++ b/www/editgroup_form.php3
@@ -46,7 +46,7 @@ if (! ($group = Group::LookupByPidGid($pid, $gid))) {
 #
 # Verify permission.
 #
-if (! TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_EDITGROUP)) {
+if (! $group->AccessCheck($this_user, $TB_PROJECT_EDITGROUP)) {
     USERERROR("You do not have permission to edit group $gid in ".
 	      "project $pid!", 1);
 }
@@ -55,7 +55,7 @@ if (! TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_EDITGROUP)) {
 # See if user is allowed to add non-members to group.
 # 
 $grabusers = 0;
-if (TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_GROUPGRABUSERS)) {
+if ($group->AccessCheck($this_user, $TB_PROJECT_GROUPGRABUSERS)) {
     $grabusers = 1;
 }
 
@@ -63,7 +63,7 @@ if (TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_GROUPGRABUSERS)) {
 # See if user is allowed to bestow group_root upon members of group.
 # 
 $bestowgrouproot = 0;
-if (TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_BESTOWGROUPROOT)) {
+if ($group->AccessCheck($this_user, $TB_PROJECT_BESTOWGROUPROOT)) {
     $bestowgrouproot = 1;
 }
 
@@ -74,24 +74,15 @@ if (TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_BESTOWGROUPROOT)) {
 # to main group either! This will force them to go through the approval
 # page first.
 #
-$curmembers_result =
-    DBQueryFatal("select m.uid,m.trust from group_membership as m ".
-		 "left join groups as g on g.pid=m.pid and g.gid=m.gid ".
-		 "where m.pid='$pid' and m.gid='$gid' and ".
-		 "      m.uid!=g.leader and m.trust!='none'");
+$curmembers = $group->MemberList();
 
 #
 # Grab the user list from the project. These are the people who can be
 # added. Do not include people in the above list, obviously! Do not
 # include members that have not been approved to main group either! This
 # will force them to go through the approval page first.
-# 
-$nonmembers_result =
-    DBQueryFatal("select m.uid from group_membership as m ".
-		 "left join group_membership as a on ".
-		 "     a.uid=m.uid and a.pid=m.pid and a.gid='$gid' ".
-		 "where m.pid='$pid' and m.gid=m.pid and a.uid is NULL ".
-		 "      and m.trust!='none'");
+#
+$nonmembers = $group->NonMemberList();
 
 #
 # We do not allow the actual group info to be edited. Just the membership.
@@ -104,14 +95,14 @@ echo "<br><center>
        <a href='docwrapper.php3?docname=groups.html'>Groups Tutorial</a>.
       </center>\n";
 
-if (mysql_num_rows($curmembers_result) ||
-    ($grabusers && mysql_num_rows($nonmembers_result))) {
+if (count($curmembers) ||
+    ($grabusers && count($nonmembers))) {
     echo "<br>
           <form action='editgroup.php3?pid=$pid&gid=$gid' method=post>
           <table align=center border=1>\n";
 }
 
-if (mysql_num_rows($curmembers_result)) {
+if (count($curmembers)) {
     if ($defaultgroup) {
 	echo "<tr><td align=center colspan=2 nowrap=1>
               <br>
@@ -131,33 +122,30 @@ if (mysql_num_rows($curmembers_result)) {
               </td></tr>\n";
     }
 
-    while ($row = mysql_fetch_array($curmembers_result)) {
-	$user  = $row[0];
-	$trust = $row[1];
-
-	if (! ($target_user = User::Lookup($user))) {
-	    TBERROR("Could not look up user object for $user", 1);
-	}
-	$showurl = CreateURL("showuser", $target_user);
+    foreach ($curmembers as $target_user) {
+	$target_uid = $target_user->uid();
+	$trust      = $target_user->GetTempData();
+	$showurl    = CreateURL("showuser", $target_user);
 
 	if ($defaultgroup) {
 	    echo "<tr>
                      <td>
-                       <input type=hidden name='change_$user' value=permit>
-                          <A href='$showurl'>$user &nbsp</A>
+                       <input type=hidden name='change_$target_uid'
+                               value=permit>
+                          <A href='$showurl'>$target_uid &nbsp</A>
                      </td>\n";
 	}
 	else {
 	    echo "<tr>
                      <td>   
                        <input checked type=checkbox value=permit
-                              name='change_$user'>
-                          <A href='$showurl'>$user &nbsp</A>
+                              name='change_$target_uid'>
+                          <A href='$showurl'>$target_uid &nbsp</A>
                      </td>\n";
 	}
 
 	echo "   <td align=center>
-                    <select name='$user\$\$trust'>\n";
+                    <select name='$target_uid\$\$trust'>\n";
 
 	#
 	# We want to have the current trust value selected in the menu.
@@ -188,9 +176,10 @@ if (mysql_num_rows($curmembers_result)) {
                    </td>\n";
     }
     echo "</tr>\n";
+    reset($curmembers);
 }
 
-if ($grabusers && mysql_num_rows($nonmembers_result)) {
+if ($grabusers && count($nonmembers)) {
     echo "<tr><td align=center colspan=2 nowrap=1>
           <br>
           <font size=+1><b>Add Group Members</b></font>[<b>1</b>].
@@ -198,24 +187,20 @@ if ($grabusers && mysql_num_rows($nonmembers_result)) {
              Select the ones you would like to add.<br>
              Be sure to select the appropriate trust level.
           </td></tr>\n";
-    
-    while ($row = mysql_fetch_array($nonmembers_result)) {
-	$user  = $row[0];
-	$trust = $row[1];
-	
-	if (! ($target_user = User::Lookup($user))) {
-	    TBERROR("Could not look up user object for $user", 1);
-	}
-	$showurl = CreateURL("showuser", $target_user);
+
+    foreach ($nonmembers as $target_user) {
+	$target_uid = $target_user->uid();
+	$trust      = $target_user->GetTempData();
+	$showurl    = CreateURL("showuser", $target_user);
 
 	echo "<tr>
                  <td>
-                   <input type=checkbox value=permit name='add_$user'>
-                      <A href='$showurl'>$user &nbsp</A>
+                   <input type=checkbox value=permit name='add_$target_uid'>
+                      <A href='$showurl'>$target_uid &nbsp</A>
                  </td>\n";
 
 	echo "   <td align=center>
-                   <select name='$user\$\$trust'>\n";
+                   <select name='$target_uid\$\$trust'>\n";
 
 	if ($group->CheckTrustConsistency($target_user,
 					  TBDB_TRUSTSTRING_USER, 0)) {
@@ -239,10 +224,11 @@ if ($grabusers && mysql_num_rows($nonmembers_result)) {
 	    </td>\n";
     }
     echo "</tr>\n";
+    reset($nonmembers);
 }
 
-if (mysql_num_rows($curmembers_result) ||
-    ($grabusers && mysql_num_rows($nonmembers_result))) {
+if (count($curmembers) ||
+    ($grabusers && count($nonmembers))) {
     echo "<tr>
              <td align=center colspan=2>
                  <b><input type=submit value=Submit></b>
diff --git a/www/experiment_defs.php b/www/experiment_defs.php
index 894d8a33f56b1d3ad7a82e99dc311f32c68c6dd4..dfb9ba3a82945b64eed07dfcb0be7db080180d98 100644
--- a/www/experiment_defs.php
+++ b/www/experiment_defs.php
@@ -53,7 +53,7 @@ class Experiment
 
 	    $foo = Experiment::LookupByPidEid($pid, $eid);
 
-	    if ($foo->IsValid())
+	    if ($foo && $foo->IsValid())
 		return $foo;
 	}
 	return null;
diff --git a/www/group_defs.php b/www/group_defs.php
index 48c6b9be38ecb5f0dcf06f82812e4b7df7ace799..a79c03b3490139987f15c207289bd964360389e1 100644
--- a/www/group_defs.php
+++ b/www/group_defs.php
@@ -430,6 +430,77 @@ class Group
 	return 1;
     }
 
+    #
+    # Return list of approved members in this group. 
+    #
+    function MemberList($exclude_leader = 1) {
+	$gid_idx    = $this->gid_idx();
+	$pid_idx    = $this->pid_idx();
+	$trust_none = TBDB_TRUSTSTRING_NONE;
+	$leader     = $this->GetLeader();
+	$result     = array();
+
+	$query_result =
+	    DBQueryFatal("select m.uid_idx,m.trust ".
+			 "   from group_membership as m ".
+			 "left join groups as g on ".
+			 "     g.pid=m.pid and g.gid=m.gid ".
+			 "where m.pid_idx='$pid_idx' and ".
+			 "      m.gid_idx='$gid_idx' and ".
+			 "      m.trust!='$trust_none'");
+
+	while ($row = mysql_fetch_array($query_result)) {
+	    $uid_idx = $row["uid_idx"];
+	    $trust   = $row["trust"];
+
+	    if ($exclude_leader && $leader->uid_idx() == $uid_idx)
+		continue;
+
+	    if (! ($user =& User::Lookup($uid_idx))) {
+		TBERROR("Group::MemberList: ".
+			"Could not load user $uid_idx!", 1);
+	    }
+	    # So caller can get this.
+	    $user->SetTempData($trust);
+	    
+	    $result[] =& $user;
+	}
+	return $result;
+    }
+
+    #
+    # Grab the user list from the project. These are the people who can be
+    # added. Do not include people in the above list, obviously! Do not
+    # include members that have not been approved to main group either! This
+    # will force them to go through the approval page first.
+    #
+    function NonMemberList() {
+	$gid_idx    = $this->gid_idx();
+	$pid_idx    = $this->pid_idx();
+	$trust_none = TBDB_TRUSTSTRING_NONE;
+	$result     = array();
+	
+	$query_result =
+	    DBQueryFatal("select m.uid_idx from group_membership as m ".
+			 "left join group_membership as a on ".
+			 "     a.uid_idx=m.uid_idx and ".
+			 "     a.pid_idx=m.pid_idx and a.gid_idx='$gid_idx' ".
+			 "where m.pid_idx='$pid_idx' and ".
+			 "      m.gid_idx=m.pid_idx and a.uid_idx is NULL ".
+			 "      and m.trust!='$trust_none'");
+
+	while ($row = mysql_fetch_array($query_result)) {
+	    $uid_idx = $row["uid_idx"];
+
+	    if (! ($user =& User::Lookup($uid_idx))) {
+		TBERROR("Group::NonMemberList: ".
+			"Could not load user $uid_idx!", 1);
+	    }
+	    $result[] =& $user;
+	}
+	return $result;
+    }
+
     #
     # Change the leader for a group.
     #
diff --git a/www/newimageid.php3 b/www/newimageid.php3
index 99b64dff282e40d4e0844d37fa7e1bbfb058f576..33beb2ba84f4ef573f957bbe5828aa2d7793b2ba 100644
--- a/www/newimageid.php3
+++ b/www/newimageid.php3
@@ -83,11 +83,13 @@ function SPITFORM($formfields, $errors)
 			 "order by osid");
     }
     else {
+	$uid_idx = $this_user->uid_idx();
+	
 	$osid_result =
 	    DBQueryFatal("select distinct o.* from os_info as o ".
 			 "left join group_membership as m ".
 			 " on m.pid=o.pid ".
-			 "where m.uid='$uid' and ".
+			 "where m.uid_idx='$uid_idx' and ".
 			 "      (path='' or path is NULL) and ".
 			 "      version!='' and version is not NULL ".
 			 "order by o.pid,o.osid");
diff --git a/www/nodecontrol_form.php3 b/www/nodecontrol_form.php3
index dc80fd13f49abfdbc8ac81e8db3e994ce1834734..a75f02da871c467e983c06640cdc9e50a2b3095f 100644
--- a/www/nodecontrol_form.php3
+++ b/www/nodecontrol_form.php3
@@ -76,13 +76,15 @@ if ($isadmin) {
 		     "order by o.osid");
 }
 else {
+    $uid_idx = $this_user->uid_idx();
+    
     $osid_result =
 	DBQueryFatal("select distinct o.osname, o.pid, o.osid as oosid," .
 		     "p.osid as posid from os_info as o ".
 		     "left join group_membership as m on m.pid=o.pid ".
 		     "left join partitions as p on o.osid=p.osid ".
 		     "where p.node_id='$node_id' or ".
-		     "  ((m.uid='$uid' or o.shared=1) and ".
+		     "  ((m.uid_idx='$uid_idx' or o.shared=1) and ".
 		     "   (o.path!='' and o.path is not NULL)) ".
 		     "order by o.pid,o.osid");
 }
diff --git a/www/showimageid_list.php3 b/www/showimageid_list.php3
index d8e3c4987f11fabeb97e9d96bd7c577f40599a75..956bb5847840c5471ae6652d349f643e5ec3153c 100644
--- a/www/showimageid_list.php3
+++ b/www/showimageid_list.php3
@@ -67,11 +67,13 @@ else {
     # permission to use/modify the image/descriptor of course, but that is
     # checked in the pages that do that stuff. In other words, ignore the
     # shared flag in the descriptors.
-    # 
+    #
+    $uid_idx = $this_user->uid_idx();
+    
     $query_result =
 	DBQueryFatal("select distinct i.* from images as i ".
 		     "left join group_membership as g on g.pid=i.pid ".
-		     "where (g.uid='$uid' or i.global) ".
+		     "where (g.uid_idx='$uid_idx' or i.global) ".
 		     "$extraclause ".
 		     "order by $order");
 }
diff --git a/www/showlasterror.php3 b/www/showlasterror.php3
index 7bd2b11771eaea66d2232dc7b045d666e7090c3e..2412f4228ff1cd90258d14443b474eb56db4f88a 100644
--- a/www/showlasterror.php3
+++ b/www/showlasterror.php3
@@ -31,37 +31,26 @@ if (!TBvalid_eid($eid)) {
 }
  
 #
-# Check to make sure this is a valid PID/EID tuple.
+# Check to make sure this is a valid PID/EID.
 #
-$query_result =
-    DBQueryFatal("SELECT * FROM experiments WHERE ".
-		 "eid='$eid' and pid='$pid'");
-if (mysql_num_rows($query_result) == 0) {
-  USERERROR("The experiment $eid is not a valid experiment ".
-            "in project $pid.", 1);
-} else {
-  $row     = mysql_fetch_array($query_result);
-  $exptidx = $row[idx];
+if (! ($experiment = Experiment::Lookup($pid, $eid))) {
+    USERERROR("The experiment $pid/$eid is not a valid experiment!", 1);
 }
-
-$expstate = TBExptState($pid, $eid);
+$exptidx = $experiment->idx();
 
 #
-# Verify that this uid is a member of the project for the experiment
-# being displayed.
+# Must have permission to view experiment details.
 #
-if (!$isadmin) {
-    $query_result =
-	DBQueryFatal("SELECT pid FROM group_membership ".
-		     "WHERE uid='$uid' and pid='$pid'");
-    if (mysql_num_rows($query_result) == 0) {
-        USERERROR("You are not a member of Project $pid!", 1);
-    }
+if (!$isadmin &&
+    !$experiment->AccessCheck($this_user, $TB_EXPT_READINFO)) {
+    USERERROR("You do not have permission to view experiment last error!", 1);
 }
 
 $query_result =
-    DBQueryFatal("SELECT e.cause,e.confidence,e.mesg,cause_desc FROM experiment_stats as s,errors as e, causes as c ".
-	         "WHERE s.exptidx = $exptidx and e.cause = c.cause and s.last_error = e.session and rank = 0");
+    DBQueryFatal("select e.cause,e.confidence,e.mesg,cause_desc ".
+		 "   from experiment_stats as s,errors as e, causes as c ".
+	         "where s.exptidx = $exptidx and e.cause = c.cause and ".
+		 "      s.last_error = e.session and rank = 0");
 
 if (mysql_num_rows($query_result) != 0) {
   $row = mysql_fetch_array($query_result);
diff --git a/www/shownsfile.php3 b/www/shownsfile.php3
index f28df1c457dc1b131a9c1965837ed7b8a3084fd0..975b4b13884b30f7e628104bdfd63cbff1e63b49 100644
--- a/www/shownsfile.php3
+++ b/www/shownsfile.php3
@@ -43,29 +43,19 @@ if (!isset($zoom) || !ereg("^[0-9]{1,50}.?[0-9]{0,50}$", $zoom)) { $zoom = 1; }
 if (!isset($detail) || !ereg("^[0-9]{1,50}$", $detail)) { $detail = 0; }
  
 #
-# Check to make sure this is a valid PID/EID tuple.
+# Check to make sure this is a valid PID/EID.
 #
-$query_result =
-    DBQueryFatal("SELECT * FROM experiments WHERE ".
-		 "eid='$eid' and pid='$pid'");
-if (mysql_num_rows($query_result) == 0) {
-  USERERROR("The experiment $eid is not a valid experiment ".
-            "in project $pid.", 1);
+if (! ($experiment = Experiment::Lookup($pid, $eid))) {
+    USERERROR("The experiment $pid/$eid is not a valid experiment!", 1);
 }
-
-$expstate = TBExptState($pid, $eid);
+$expstate = $experiment->state();
 
 #
-# Verify that this uid is a member of the project for the experiment
-# being displayed.
+# Must have permission to view experiment details.
 #
-if (!$isadmin) {
-    $query_result =
-	DBQueryFatal("SELECT pid FROM group_membership ".
-		     "WHERE uid='$uid' and pid='$pid'");
-    if (mysql_num_rows($query_result) == 0) {
-        USERERROR("You are not a member of Project $pid!", 1);
-    }
+if (!$isadmin &&
+    !$experiment->AccessCheck($this_user, $TB_EXPT_READINFO)) {
+    USERERROR("You do not have permission to view experiment details!", 1);
 }
 
 #
diff --git a/www/showosid_list.php3 b/www/showosid_list.php3
index 6d5092d3011ad6254a7d2a2feb391c7781c1cf06..a3371a7a321b920035a7bbfd42362a2e89d584b0 100644
--- a/www/showosid_list.php3
+++ b/www/showosid_list.php3
@@ -61,10 +61,12 @@ if ($isadmin) {
 		     "order by $order");
 }
 else {
+    $uid_idx = $this_user->uid_idx();
+    
     $query_result =
 	DBQueryFatal("select distinct o.* from os_info as o ".
 		     "left join group_membership as g on g.pid=o.pid ".
-		     "where (g.uid='$uid' or o.shared=1) ".
+		     "where (g.uid_idx='$uid_idx' or o.shared=1) ".
 		     "$extraclause ".
 		     "order by $order");
 }
diff --git a/www/showproject_list.php3 b/www/showproject_list.php3
index 93dbf67c2efba97817469fe7633965df52914eb0..a7a2a33e6d13d01e6ed90a66e39f7f529eb9a58f 100644
--- a/www/showproject_list.php3
+++ b/www/showproject_list.php3
@@ -293,6 +293,8 @@ function GENPLIST ($query_result)
 # Get the project list for non admins.
 #
 if (! $isadmin) {
+    $uid_idx = $this_user->uid_idx();
+    
     $query_result =
 	DBQueryFatal("SELECT p.*, ".
 		     "IF(p.expt_last, ".
@@ -301,7 +303,7 @@ if (! $isadmin) {
 		     "FROM projects as p ".
 		     "left join group_membership as g on ".
 		     " p.pid=g.pid and g.pid=g.gid ".
-		     "where g.uid='$uid' and g.trust!='none' ".
+		     "where g.uid_idx='$uid_idx' and g.trust!='none' ".
 		     "group by p.pid order by $order");
 				   
     if (mysql_num_rows($query_result) == 0) {
diff --git a/www/showuser_list.php3 b/www/showuser_list.php3
index be9e8a64e9d67ca5319c2f19edd0f1595e4ee3a2..0de9075ff41df24c89059540bc3cfc7058246a0a 100644
--- a/www/showuser_list.php3
+++ b/www/showuser_list.php3
@@ -87,7 +87,7 @@ elseif (! strcmp($showtype, "widearea")) {
     $showtag = "widearea";
 }
 elseif (! strcmp($showtype, "homeless")) {
-    $clause  = "left join group_membership as m on u.uid=m.uid ";
+    $clause  = "left join group_membership as m on u.uid_idx=m.uid_idx ";
     $clause .= "left join widearea_accounts as w on u.uid=w.uid ";
     $where   = "where (m.uid is null and w.node_id is NULL) ";
     $showtag = "homeless";
diff --git a/www/user_defs.php b/www/user_defs.php
index c6167fb5d423571fb7de47aff42585cf177db5d1..aef3e848e6770e211c87dea2a1b50a153329f7da 100644
--- a/www/user_defs.php
+++ b/www/user_defs.php
@@ -13,6 +13,7 @@ $user_cache = array();
 class User
 {
     var	$user;
+    var $tempdata;		# For temporary data values ...
 
     #
     # For pedantic checks early in pages.
@@ -209,6 +210,14 @@ class User
     function wikionly()		{ return $this->field("wikionly"); }
     function mailman_password() { return $this->field("mailman_password"); }
 
+    # Temporary data storage ... useful.
+    function SetTempData(&$value) {
+	$this->tempdata =& $value;
+    }
+    function &GetTempData() {
+	return $this->tempdata;
+    }
+
     #
     # Class function to create new user and return object.
     #