Merge branch 'set-CAINFO-everywhere'
diff --git a/app/config/pga_config.php.template b/app/config/pga_config.php.template
index 654a1ed..920d938 100644
--- a/app/config/pga_config.php.template
+++ b/app/config/pga_config.php.template
@@ -74,7 +74,7 @@
                 // http://www.keycloak.org/docs/2.5/server_admin/topics/identity-broker/suggested.html
                 'oauth-authorize-url-extra-params' => 'kc_idp_hint=oidc',
                 // Optional
-                'logo': '/assets/path_to_image.png'
+                'logo' => '/assets/path_to_image.png'
             ],
         ],
 
@@ -180,6 +180,21 @@
         'wall-time-limit' => '30',
 
         /**
+         * Max node count
+         */
+        'max-node-count' => '4',
+
+        /**
+         * Max total core count
+         */
+        'max-total-cpu-count' => '96',
+
+        /**
+         * Max wall time limit
+         */
+        'max-wall-time-limit' => '120',
+
+        /**
          * Enable app-catalog cache
          */
         'enable-app-catalog-cache' => true,
diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php
index f9ea073..083bff0 100644
--- a/app/controllers/AccountController.php
+++ b/app/controllers/AccountController.php
@@ -79,6 +79,7 @@
         $auth_password_option = CommonUtilities::getAuthPasswordOption();
         // Support for many external identity providers (authorization code auth flow)
         $auth_code_options = CommonUtilities::getAuthCodeOptions();
+        $has_auth_code_and_password_options = $auth_password_option != null && count($auth_code_options) > 0;
 
         // If no username/password option and only one external identity
         // provider, just redirect immediately
@@ -88,6 +89,7 @@
             return View::make('account/login', array(
                 "auth_password_option" => $auth_password_option,
                 "auth_code_options" => $auth_code_options,
+                "has_auth_code_and_password_options" => $has_auth_code_and_password_options,
             ));
         }
     }
@@ -98,6 +100,7 @@
         $auth_password_option = CommonUtilities::getAuthPasswordOption();
         // Support for many external identity providers (authorization code auth flow)
         $auth_code_options = CommonUtilities::getAuthCodeOptions();
+        $has_auth_code_and_password_options = $auth_password_option != null && count($auth_code_options) > 0;
 
         // If no username/password option and only one external identity
         // provider, just redirect immediately
@@ -107,6 +110,7 @@
             return View::make('account/login-desktop', array(
                 "auth_password_option" => $auth_password_option,
                 "auth_code_options" => $auth_code_options,
+                "has_auth_code_and_password_options" => $has_auth_code_and_password_options,
             ));
         }
     }
diff --git a/app/controllers/AdminController.php b/app/controllers/AdminController.php
index 28eb9a5..03b67a7 100644
--- a/app/controllers/AdminController.php
+++ b/app/controllers/AdminController.php
@@ -173,6 +173,29 @@
 
 	public function updateGateway(){
 
+        $rules = array(
+            "password" => "min:6|max:48|regex:/^.*(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@!$#*]).*$/",
+            "confirm_password" => "same:password",
+            "email" => "email",
+        );
+        $messages = array(
+            'password.regex' => 'Password needs to contain at least (a) One lower case letter (b) One Upper case letter and (c) One number (d) One of the following special characters - !@#$&*',
+        );
+        $checkValidation = array();
+        $checkValidation["password"] = Input::get("gatewayAdminPassword");
+        $checkValidation["confirm_password"] = Input::get("gatewayAdminPasswordConfirm");
+        $checkValidation["email"] = Input::get("gatewayAdminEmail");
+
+        $validator = Validator::make( $checkValidation, $rules, $messages);
+        if ($validator->fails()) {
+            if(Request::ajax()){
+                return json_encode(array("errors" => true, "validationMessages" => $validator->messages()));
+            } else {
+                Session::put("message", "An error has occurred while updating the Gateway: " + $validator->messages());
+                return Redirect::back();
+            }
+        }
+
 	    $gateway = TenantProfileService::getGateway( Session::get('authz-token'), Input::get("internal_gateway_id"));
 		$returnVal = AdminUtilities::update_gateway( Input::get("internal_gateway_id"), Input::except("oauthClientId","oauthClientSecret"));
 		if( Request::ajax()){
@@ -184,10 +207,10 @@
                     Session::put("successMessages", "Tenant has been created successfully!");
                 else
                     Session::put("successMessages", "Gateway has been updated successfully!");
-                return json_encode(AdminUtilities::get_gateway(Input::get("internal_gateway_id")));
+                return json_encode(array("errors" => false, "gateway" => AdminUtilities::get_gateway(Input::get("internal_gateway_id"))));
             }
 			else {
-                return $returnVal; // anything other than positive update result
+                return json_encode(array("errors" => true)); // anything other than positive update result
             }
 		}
 		else{
diff --git a/app/controllers/ExperimentController.php b/app/controllers/ExperimentController.php
index 131fa1d..36131f9 100755
--- a/app/controllers/ExperimentController.php
+++ b/app/controllers/ExperimentController.php
@@ -55,7 +55,6 @@
                 "wallTimeLimit" => $wallTimeLimit
             );
 
-
             $experimentInputs = array(
                 "disabled" => ' disabled',
                 "experimentName" => $_POST['experiment-name'],
@@ -94,7 +93,17 @@
 
         } else if (isset($_POST['save']) || isset($_POST['launch'])) {
             try {
-                $expId = ExperimentUtilities::create_experiment();
+                $computeResourceId = Input::get("compute-resource");
+                //Validate entered queue details
+                $queueValues = array("queueName" => Input::get("queue-name"),
+                    "nodeCount" => Input::get("node-count"),
+                    "cpuCount" => Input::get("cpu-count"),
+                    "wallTimeLimit" => Input::get("walltime-count")
+                );
+                if($this->validateQueueData($computeResourceId, $queueValues))
+                    $expId = ExperimentUtilities::create_experiment();
+                else
+                    return Redirect::to("experiment/create")->with("error-message", "Validate the number of nodes, CPUs and the wall time limit");
             } catch (Exception $ex) {
                 Log::error("Failed to create experiment!");
                 Log::error($ex);
@@ -320,6 +329,7 @@
 
         $userComputeResourcePreferences = URPUtilities::get_all_user_compute_resource_prefs();
         $userHasComputeResourcePreference = array_key_exists($expVal['scheduling']->resourceHostId, $userComputeResourcePreferences);
+        $batchQueues = ExperimentUtilities::getQueueDatafromResourceId($computeResourceId);
 
         $experimentInputs = array(
             "disabled" => ' ',
@@ -338,7 +348,8 @@
             'project' => $experiment->projectId,
             'expVal' => $expVal,
             'cloning' => true,
-            'advancedOptions' => Config::get('pga_config.airavata')["advanced-experiment-options"]
+            'advancedOptions' => Config::get('pga_config.airavata')["advanced-experiment-options"],
+            'batchQueues' => $batchQueues
         );
 
         if(Config::get('pga_config.airavata')["data-sharing-enabled"]){
@@ -396,7 +407,19 @@
     {
         $experiment = ExperimentUtilities::get_experiment(Input::get('expId')); // update local experiment variable
         try {
-            $updatedExperiment = ExperimentUtilities::apply_changes_to_experiment($experiment, Input::all());
+            $computeResourceId = Input::get("compute-resource");
+            //Validate entered queue details
+            $queueValues = array("queueName" => Input::get("queue-name"),
+                "nodeCount" => Input::get("node-count"),
+                "cpuCount" => Input::get("cpu-count"),
+                "wallTimeLimit" => Input::get("walltime-count")
+            );
+            if($this->validateQueueData($computeResourceId, $queueValues)) {
+                $updatedExperiment = ExperimentUtilities::apply_changes_to_experiment($experiment, Input::all());
+            } else {
+                $errMessage = "Validate the number of nodes, CPUs and the wall time limit";
+                return Redirect::to("experiment/edit?expId=" . urlencode(Input::get('expId')))->with("error-message", $errMessage);
+            }
         } catch (Exception $ex) {
             $errMessage = "Failed to update experiment: " . $ex->getMessage();
             Log::error($errMessage);
@@ -590,6 +613,21 @@
         }
         return $allowedFileSize;
     }
+
+    private function validateQueueData($computeResourceId, $queue)
+    {
+        $queues = ExperimentUtilities::getQueueDatafromResourceId($computeResourceId);
+        $queueName = $queue['queueName'];
+
+        foreach($queues as $aQueue){
+            if($aQueue->queueName == $queueName) {
+                if($queue['nodeCount'] <= $aQueue->maxNodes && $queue['cpuCount'] <= $aQueue->maxProcessors && $queue['wallTimeLimit'] <= $aQueue->maxRunTime)
+                    return true;
+            }
+        }
+
+        return false;
+    }
 }
 
 ?>
diff --git a/app/controllers/GatewayRequestUpdateController.php b/app/controllers/GatewayRequestUpdateController.php
index 2ff33a5..f75019e 100644
--- a/app/controllers/GatewayRequestUpdateController.php
+++ b/app/controllers/GatewayRequestUpdateController.php
@@ -27,26 +27,18 @@
 
         $inputs = Input::all();
         $rules = array(
-            "password" => "required|min:6|max:48|regex:/^.*(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@!$#*]).*$/",
-            "confirm_password" => "required|same:password",
             "email" => "required|email",
         );
 
-        $messages = array(
-            'password.regex' => 'Password needs to contain at least (a) One lower case letter (b) One Upper case letter and (c) One number (d) One of the following special characters - !@#$&*',
-        );
+        $messages = array();
 
         $checkValidation = array();
-        $checkValidation["password"] = $inputs["admin-password"];
-        $checkValidation["confirm_password"] = $inputs["admin-password-confirm"];
-        $checkValidation["email"] = $inputs["admin-email"];
+        $checkValidation["email"] = $inputs["email-address"];
 
         $validator = Validator::make( $checkValidation, $rules, $messages);
         if ($validator->fails()) {
             Session::put("validationMessages", $validator->messages() );
-            return Redirect::back()
-                ->withInput(Input::except('password', 'password_confirm'))
-                ->withErrors($validator);
+            return Redirect::back()->withErrors($validator);
         }
         else {
             $returnVal = AdminUtilities::user_update_gateway(Input::get("internal-gateway-id"), Input::all());
diff --git a/app/libraries/AdminUtilities.php b/app/libraries/AdminUtilities.php
index 7f17408..b66ab4c 100644
--- a/app/libraries/AdminUtilities.php
+++ b/app/libraries/AdminUtilities.php
@@ -127,16 +127,6 @@
         $gateway->gatewayApprovalStatus = GatewayApprovalStatus::APPROVED;
         $gateway->emailAddress = $gatewayData["email-address"];
         $gateway->gatewayURL = $gatewayData["gateway-url"];
-        $gateway->identityServerUserName = $gatewayData["admin-username"];
-        $token = AdminUtilities::create_pwd_token([
-            "username" => $gatewayData["admin-username"],
-            "password" => $gatewayData["admin-password"],
-            "description" => "Admin user password for Gateway " . $gatewayId
-        ]);
-        $gateway->identityServerPasswordToken  = $token;
-        $gateway->gatewayAdminFirstName = $gatewayData["admin-firstname"];
-        $gateway->gatewayAdminLastName = $gatewayData["admin-lastname"];
-        $gateway->gatewayAdminEmail = $gatewayData["admin-email"];
         $gateway->reviewProposalDescription = $gatewayData["project-details"];
         $gateway->gatewayPublicAbstract = $gatewayData["public-project-description"];
         if( TenantProfileService::updateGateway( Session::get('authz-token'), $gateway) ){
@@ -163,10 +153,15 @@
             $gatewayData["declinedReason"] = " ";
             if ($gateway->identityServerPasswordToken == null)
             {
-                Session::put("errorMessages", "Error: Please ask the Gateway Provider to submit a password.");
+                Session::flash("errorMessages", "Error: Please provide an admin password.");
                 return -1;
             }
-            foreach ($gatewayData as $data) {
+            foreach ($gatewayData as $key => $data) {
+                // Don't check these fields, see related check above
+                // where we make sure that password is provided
+                if ($key == "gatewayAdminPassword" || $key == "gatewayAdminPasswordConfirm") {
+                    continue;
+                }
                 if ($data == null) {
                     return -1;
                 }
@@ -181,6 +176,14 @@
             $gateway->gatewayAdminLastName = $gatewayData["gatewayAdminLastName"];
             $gateway->gatewayAdminEmail = $gatewayData["gatewayAdminEmail"];
             $gateway->identityServerUserName = $gatewayData["identityServerUserName"];
+            if (!empty($gatewayData["gatewayAdminPassword"])) {
+                $token = AdminUtilities::create_pwd_token([
+                    "username" => $gatewayData["identityServerUserName"],
+                    "password" => $gatewayData["gatewayAdminPassword"],
+                    "description" => "Admin user password for Gateway " . $gateway->gatewayName
+                ]);
+                $gateway->identityServerPasswordToken = $token;
+            }
             $gateway->reviewProposalDescription = $gatewayData["reviewProposalDescription"];
             $gateway->gatewayPublicAbstract = $gatewayData["gatewayPublicAbstract"];
             $gateway->gatewayApprovalStatus = GatewayApprovalStatus::APPROVED;
@@ -195,6 +198,14 @@
             $gateway->gatewayAdminLastName = $gatewayData["gatewayAdminLastName"];
             $gateway->gatewayAdminEmail = $gatewayData["gatewayAdminEmail"];
             $gateway->identityServerUserName = $gatewayData["identityServerUserName"];
+            if (!empty($gatewayData["gatewayAdminPassword"])) {
+                $token = AdminUtilities::create_pwd_token([
+                    "username" => $gatewayData["identityServerUserName"],
+                    "password" => $gatewayData["gatewayAdminPassword"],
+                    "description" => "Admin user password for Gateway " . $gateway->gatewayName
+                ]);
+                $gateway->identityServerPasswordToken = $token;
+            }
             $gateway->reviewProposalDescription = $gatewayData["reviewProposalDescription"];
             $gateway->gatewayPublicAbstract = $gatewayData["gatewayPublicAbstract"];
             $gateway->gatewayApprovalStatus = GatewayApprovalStatus::APPROVED;
diff --git a/app/libraries/CommonUtilities.php b/app/libraries/CommonUtilities.php
index 525ec40..877339b 100644
--- a/app/libraries/CommonUtilities.php
+++ b/app/libraries/CommonUtilities.php
@@ -468,10 +468,14 @@
     public static function getAuthPasswordOption() {
 
         $auth_options = Config::get('pga_config.wsis')['auth-options'];
-        $auth_password_option_array = array_filter($auth_options, function($auth_option) {
-            return $auth_option["oauth-grant-type"] == "password";
-        });
-        return count($auth_password_option_array) > 0 ? $auth_password_option_array[0] : null;
+        $auth_password_option = null;
+        foreach ($auth_options as $key => $auth_option) {
+            if ($auth_option["oauth-grant-type"] == "password") {
+                $auth_password_option = $auth_option;
+                break;
+            }
+        }
+        return $auth_password_option;
     }
 
     public static function getAuthCodeOptions() {
diff --git a/app/libraries/ExperimentUtilities.php b/app/libraries/ExperimentUtilities.php
index 9424893..4ddc460 100755
--- a/app/libraries/ExperimentUtilities.php
+++ b/app/libraries/ExperimentUtilities.php
@@ -1422,7 +1422,25 @@
     public static function getQueueDatafromResourceId($crId)
     {
         $resourceObject = Airavata::getComputeResource(Session::get('authz-token'), $crId);
-        return $resourceObject->batchQueues;
+        $queues =  $resourceObject->batchQueues;
+
+        //Defining maximum allowed value for queue resources
+        $maxNodeCount = Config::get('pga_config.airavata.max-node-count', null);
+        $maxCPUCount = Config::get('pga_config.airavata.max-total-cpu-count', null);
+        $maxWallTimeLimit = Config::get('pga_config.airavata.max-wall-time-limit', null);
+
+        foreach($queues as $aQueue){
+            if($maxNodeCount && $aQueue->maxNodes > $maxNodeCount){
+                $aQueue->maxNodes = $maxNodeCount;
+            }
+            if($maxCPUCount && $aQueue->maxProcessors > $maxCPUCount){
+                $aQueue->maxProcessors = $maxCPUCount;
+            }
+            if($maxWallTimeLimit && $aQueue->maxRunTime > $maxWallTimeLimit){
+                $aQueue->maxRunTime = $maxWallTimeLimit;
+            }
+        }
+        return $queues;
     }
 
     /**
diff --git a/app/libraries/IamAdminServicesUtilities.php b/app/libraries/IamAdminServicesUtilities.php
index fbb208e..3ba50df 100644
--- a/app/libraries/IamAdminServicesUtilities.php
+++ b/app/libraries/IamAdminServicesUtilities.php
@@ -33,7 +33,7 @@
         $user_profiles = IamAdminServices::getUsersWithRole($authz_token, $role_name);
         $users = [];
         foreach ($user_profiles as $user_profile) {
-            $users[] = $user_profile->userId;
+            array_push($users, (object)["firstName"=>$user_profile->firstName,"lastName"=>$user_profile->lastName,"email"=>implode(",",$user_profile->emails),"userName"=>$user_profile->userId]);
         }
         return $users;
     }
diff --git a/app/libraries/Keycloak/Keycloak.php b/app/libraries/Keycloak/Keycloak.php
index fc839c3..7c4d90c 100644
--- a/app/libraries/Keycloak/Keycloak.php
+++ b/app/libraries/Keycloak/Keycloak.php
@@ -259,7 +259,7 @@
         $users = $this->users->getUsers($this->realm);
         $usernames = [];
         foreach ($users as $user) {
-            $usernames[] = $user->username;
+            array_push($usernames, (object)["firstName"=>$user->firstName,"lastName"=>$user->lastName,"email"=>$user->email,"userName"=>$user->username]);
         }
         return $usernames;
     }
@@ -275,7 +275,7 @@
         $users = $this->users->searchUsers($this->realm, $phrase);
         $usernames = [];
         foreach ($users as $user) {
-            $usernames[] = $user->username;
+            array_push($usernames, (object)["firstName"=>$user->firstName,"lastName"=>$user->lastName,"email"=>$user->email,"userName"=>$user->username]);
         }
         return $usernames;
     }
@@ -457,3 +457,4 @@
         return $json;
     }
 }
+
diff --git a/app/views/account/create.blade.php b/app/views/account/create.blade.php
index c490761..c86e223 100644
--- a/app/views/account/create.blade.php
+++ b/app/views/account/create.blade.php
@@ -6,8 +6,25 @@
 
 @section('content')
 
+@if (!empty($auth_code_options))
+    <div class="col-md-offset-1 col-md-4 center-column">
+        <div class="page-header">
+            <h3>Log in with your existing organizational login</h3>
+        </div>
+        @foreach ($auth_code_options as $auth_code_option)
+            @include('partials/login-external', array("auth_code_option" => $auth_code_option))
+        @endforeach
+    </div>
+    <div class="col-md-2 center-column">
+        <h3 id="login-option-separator" class="horizontal-rule">OR</h3>
+    </div>
+@endif
+
+@if (!empty($auth_code_options))
+<div class="col-md-4 center-column">
+@else
 <div class="col-md-offset-4 col-md-4">
-    @if (!empty($auth_password_option))
+@endif
     <div class="page-header">
         <h3>Create New {{{ $auth_password_option["name"] }}} Account
             <small>
@@ -73,15 +90,6 @@
         <input name="Submit" type="submit" class="btn btn-primary btn-block" value="Create">
     </form>
 
-        @if (!empty($auth_code_options))
-            <h3 id="login-option-separator" class="horizontal-rule">OR</h4>
-        @endif
-    @endif {{-- @if (!empty($auth_password_option)) --}}
-
-    @if (!empty($auth_code_options))
-        @include('partials/login-external', array("auth_code_options" => $auth_code_options))
-    @endif
-
     <style media="screen" type="text/css">
         .form-group.required .control-label:after {
             content: " *";
diff --git a/app/views/account/login-desktop.blade.php b/app/views/account/login-desktop.blade.php
index 2108206..646f821 100755
--- a/app/views/account/login-desktop.blade.php
+++ b/app/views/account/login-desktop.blade.php
@@ -6,16 +6,34 @@
 
 @section('content')
 
-<div class="col-md-offset-4 col-md-4">
-    @if (!empty($auth_password_option))
-        @include('partials/login-form', array("auth_name" => $auth_password_option["name"], "desktop" => true))
-        @if (!empty($auth_code_options))
-            <h3 id="login-option-separator" class="horizontal-rule">OR</h4>
-        @endif
+@if(count($auth_code_options) > 0)
+    @if($has_auth_code_and_password_options)
+    <div class="col-md-offset-1 col-md-4 center-column">
+    @else
+    <div class="col-md-offset-4 col-md-4 center-column">
     @endif
-    @if (!empty($auth_code_options))
-        @include('partials/login-external', array("auth_code_options" => $auth_code_options))
+
+    @foreach ($auth_code_options as $auth_code_option)
+        @include('partials/login-external', array("auth_code_option" => $auth_code_option))
+    @endforeach
+    </div>
+@endif
+
+@if($has_auth_code_and_password_options)
+    <div class="col-md-2 center-column">
+        <h3 id="login-option-separator" class="horizontal-rule">OR</h3>
+    </div>
+@endif
+
+@if(!empty($auth_password_option))
+    @if($has_auth_code_and_password_options)
+    <div class="col-md-4 center-column">
+    @else
+    <div class="col-md-offset-4 col-md-4 center-column">
     @endif
-</div>
+
+    @include('partials/login-form', array("auth_name" => $auth_password_option["name"], "desktop" => true))
+    </div>
+@endif
 
 @stop
\ No newline at end of file
diff --git a/app/views/account/login.blade.php b/app/views/account/login.blade.php
index 1e8a52a..dcd5f54 100755
--- a/app/views/account/login.blade.php
+++ b/app/views/account/login.blade.php
@@ -6,17 +6,37 @@
 
 @section('content')
 
-<div class="col-md-offset-4 col-md-4">
+@if(count($auth_code_options) > 0)
+    @if($has_auth_code_and_password_options)
+    <div class="col-md-offset-1 col-md-4 center-column">
+    @else
+    <div class="col-md-offset-4 col-md-4 center-column">
+    @endif
 
-    @if (!empty($auth_password_option))
-        @include('partials/login-form', array("auth_name" => $auth_password_option["name"]))
-        @if (!empty($auth_code_options))
-            <h3 id="login-option-separator" class="horizontal-rule">OR</h4>
-        @endif
+        <div class="page-header">
+            <h3>Log in with your existing organizational login</h3>
+        </div>
+        @foreach ($auth_code_options as $auth_code_option)
+            @include('partials/login-external', array("auth_code_option" => $auth_code_option))
+        @endforeach
+    </div>
+@endif
+
+@if($has_auth_code_and_password_options)
+    <div class="col-md-2 center-column">
+        <h3 id="login-option-separator" class="horizontal-rule">OR</h3>
+    </div>
+@endif
+
+@if(!empty($auth_password_option))
+    @if($has_auth_code_and_password_options)
+    <div class="col-md-4 center-column">
+    @else
+    <div class="col-md-offset-4 col-md-4 center-column">
     @endif
-    @if (!empty($auth_code_options))
-        @include('partials/login-external', array("auth_code_options" => $auth_code_options))
-    @endif
-</div>
+
+    @include('partials/login-form', array("auth_name" => $auth_password_option["name"]))
+    </div>
+@endif
 
 @stop
\ No newline at end of file
diff --git a/app/views/account/update.blade.php b/app/views/account/update.blade.php
index e2e905c..e5b2f37 100644
--- a/app/views/account/update.blade.php
+++ b/app/views/account/update.blade.php
@@ -65,36 +65,6 @@
                         </div>
 
                         <div class="form-group required">
-                            <label class="control-label">Gateway Admin Username</label>
-                            <input type="text" name="admin-username" value="{{ $gatewayData["adminUsername"] }}" class="form-control" required="required" />
-                        </div>
-
-                        <div class="form-group required">
-                            <label class="control-label">Gateway Admin Password</label>
-                            <input type="password" id="password" name="admin-password" class="form-control" required="required" title="" type="password" data-container="body" data-toggle="popover" data-placement="left" data-content="Password needs to contain at least (a) One lower case letter (b) One Upper case letter and (c) One number (d) One of the following special characters - !@#$*"/>
-                        </div>
-
-                        <div class="form-group required">
-                            <label class="control-label">Admin Password Confirmation</label>
-                            <input type="password" name="admin-password-confirm" class="form-control" required="required"/>
-                        </div>
-
-                        <div class="form-group required">
-                            <label class="control-label">Admin First Name</label>
-                            <input type="text" name="admin-firstname" class="form-control" required="required" value="{{ $gatewayData["adminFirstName"] }}"/>
-                        </div>
-
-                        <div class="form-group required">
-                            <label class="control-label">Admin Last Name</label>
-                            <input type="text" name="admin-lastname" class="form-control" required="required" value="{{ $gatewayData["adminLastName"] }}"/>
-                        </div>
-
-                        <div class="form-group required">
-                            <label class="control-label">Admin Email ID</label>
-                            <input type="text" name="admin-email" class="form-control" required="required" value="{{ $gatewayData["adminEmail"] }}"/>
-                        </div>
-
-                        <div class="form-group required">
                             <label class="control-label">Project Details</label>
                             <textarea type="text" name="project-details" maxlength="250" id="project-details" class="form-control" required="required"  data-container="body" data-toggle="popover" data-placement="left" data-content="This information will help us to understand and identify your gateway requirements, such as local or remote resources, user management, field of science and communities supported, applications and interfaces, license handling, allocation management, data management, etc... It will help us in serving you and providing you with the best option for you and your research community.">{{ $gatewayData["projectDetails"] }}</textarea>
                         </div>
@@ -118,10 +88,6 @@
 @parent
 <script>
 
-    $("#password").popover({
-    'trigger':'focus'
-    });
-
     $("#gateway-url").popover({
     'trigger':'focus'
     });
diff --git a/app/views/admin/manage-gateway.blade.php b/app/views/admin/manage-gateway.blade.php
index 5e72642..e581273 100644
--- a/app/views/admin/manage-gateway.blade.php
+++ b/app/views/admin/manage-gateway.blade.php
@@ -275,6 +275,14 @@
                         <input type="text" name="identityServerUserName" id="identityServerUserName" class="form-control identityServerUserName"/>
                     </div>
                     <div class="form-group">
+                        <label class="control-label">Gateway Admin Password</label>
+                        <input type="password" id="password" name="gatewayAdminPassword" class="form-control identityServerPasswordToken" title="" type="password" data-container="#approve-gateway" data-toggle="popover" data-placement="left" data-content="Password needs to contain at least (a) One lower case letter (b) One Upper case letter and (c) One number (d) One of the following special characters - !@#$*"/>
+                    </div>
+                    <div class="form-group">
+                        <label class="control-label">Admin Password Confirmation</label>
+                        <input type="password" name="gatewayAdminPasswordConfirm" class="form-control"/>
+                    </div>
+                    <div class="form-group">
                         <label>Gateway Admin First Name</label>
                         <input type="text" name="gatewayAdminFirstName" id="gatewayAdminFirstName" class="form-control gatewayAdminFirstName"/>
                     </div>
@@ -613,6 +621,9 @@
         $(".reviewProposalDescription").val( gatewayObject.reviewProposalDescription);
         $(".gatewayAdminFirstName").val( gatewayObject.gatewayAdminFirstName);
         $(".gatewayAdminLastName").val( gatewayObject.gatewayAdminLastName);
+        if (gatewayObject.identityServerPasswordToken) {
+            $(".identityServerPasswordToken").attr("placeholder", "Current token: " + gatewayObject.identityServerPasswordToken);
+        }
         $(".emailAddress").val( gatewayObject.emailAddress);
         $(".identityServerUserName").val( gatewayObject.identityServerUserName);
         $(".oauthClientId").val( gatewayObject.oauthClientId);
@@ -668,6 +679,8 @@
                     $(thisButton).addClass("hide");
                 }
             });
+            // Disallow creating tenant until password is set
+            $("button[value=createTenant]").prop("disabled", !gatewayObject.identityServerPasswordToken);
             $(".approvedGateway").removeClass("hide"); {
                 $('#emailAddress').attr('readonly', false);
                 $('#gatewayURL').attr('readonly', false);
@@ -772,16 +785,29 @@
         $.ajax({
             url: "{{URL::to('/')}}/admin/update-gateway-request",
             method: "GET",
-            data: updateGatewayData
+            data: updateGatewayData,
+            dataType: 'json'
         }).done( function( data){
             $(".loading-gif").remove();
-            if( data == -1 ){
-                //errors only with -1
+            if( data.errors ){
+                var messages = data.validationMessages;
+                var errorMessages = [];
+                for (var field in data.validationMessages) {
+                    Array.prototype.push.apply(errorMessages, data.validationMessages[field]);
+                }
+                var errorMessagesList = $("<ul></ul>");
+                errorMessages.forEach((errorMessage) => {
+                    $("<li></li>").text(errorMessage).appendTo(errorMessagesList);
+                });
                 if( updateVal == "createTenant"){
-                $(".submit-actions").before("<div class='alert alert-danger fail-alert'>All fields are required to create the gateway! Please make sure you've first updated all the Gateway details accurately and try again. Ask the Gateway Provider to set a Password token if they haven't set it yet.");
+                    $(".submit-actions")
+                        .before("<div class='alert alert-danger fail-alert'>All fields are required to create the gateway! Please make sure you've first updated all the Gateway details accurately and try again.</div>")
+                        .append(errorMessagesList);
                 }
                 else{
-                    $(".submit-actions").before("<div class='alert alert-danger fail-alert'>Error updating Gateway. Please try again.");
+                    $("<div class='alert alert-danger fail-alert'>Error updating Gateway.</div>")
+                        .insertBefore(".submit-actions")
+                        .append(errorMessagesList);
                 }
             }
             else{
@@ -799,7 +825,7 @@
 
                 //refresh data next time if same popup is opened.
                 var gatewayIdWithoutSpaces = dataObj['gateway_id'].replace(/\s+/g, '-');
-                $("#view-" +  gatewayIdWithoutSpaces).data("gatewayobject", data);
+                $("#view-" +  gatewayIdWithoutSpaces).data("gatewayobject", data.gateway);
                 $("#view-" + gatewayIdWithoutSpaces ).parent().parent().find(".form-gatewayName").html( dataObj['gatewayName']);
                 $("#view-" + gatewayIdWithoutSpaces ).parent().parent().find(".form-gatewayURL").html( dataObj['gatewayURL']);
             }
@@ -860,8 +886,8 @@
     });
 
 
-    $(".qualityOfService").popover({
-        'trigger':'focus'
+    $("[data-toggle=popover]").popover({
+        'trigger': 'focus'
     });
 
     function editableInputs( elem, yes){
diff --git a/app/views/admin/manage-users.blade.php b/app/views/admin/manage-users.blade.php
index c8ea524..1b038cb 100644
--- a/app/views/admin/manage-users.blade.php
+++ b/app/views/admin/manage-users.blade.php
@@ -54,7 +54,11 @@
 
                 <table class="table table-striped table-condensed">
                     <tr>
+                        <th>First Name</th>
+                        <th>Last Name</th>
                         <th>Username</th>
+                        <th>Email</th>
+
                         <th>
                             Role :
                             <select onchange="location = this.options[this.selectedIndex].value;">
@@ -77,10 +81,13 @@
                     </tr>
                     @foreach( (array)$users as $user)
                     <tr class="user-row">
-                        <td>{{ $user }}</td>
+                        <td>{{ $user->firstName }}</td>
+                        <td>{{ $user->lastName }}</td>
+                        <td>{{ $user->userName }}</td>
+                        <td>{{ $user->email }}</td>
                         <td>
                             <button class="button btn btn-default check-roles" type="button"
-                                    data-username="{{$user}}">Check All Roles
+                                    data-username="{{$user->userName}}">Check All Roles
                             </button>
                             <div class="user-roles"></div>
                         </td>
@@ -280,4 +287,4 @@
         });
     }
 </script>
-@stop
\ No newline at end of file
+@stop
diff --git a/app/views/experiment/edit.blade.php b/app/views/experiment/edit.blade.php
index 9e6b156..714db8a 100755
--- a/app/views/experiment/edit.blade.php
+++ b/app/views/experiment/edit.blade.php
@@ -14,7 +14,6 @@
 //$appResources = array('Echo' => $echoResources, 'WRF' => $wrfResources);
 ?>
 
-
 <div class="container">
 
     @if (Session::has("error-message"))
diff --git a/app/views/partials/experiment-inputs.blade.php b/app/views/partials/experiment-inputs.blade.php
index 1318961..eb94ae2 100644
--- a/app/views/partials/experiment-inputs.blade.php
+++ b/app/views/partials/experiment-inputs.blade.php
@@ -83,7 +83,7 @@
             <div class="queue-view">
                 @if(isset($expInputs['expVal']) )
                 @include( 'partials/experiment-queue-block', array('queues'=>
-                $expInputs['expVal']['computeResource']->batchQueues, 'expVal' => $expInputs['expVal'],
+                $expInputs['batchQueues'], 'expVal' => $expInputs['expVal'],
                 'useUserCRPref' => $expInputs['useUserCRPref'],
                 'userHasComputeResourcePreference' => $expInputs['userHasComputeResourcePreference'],
                  'cpusPerNode' => $cpusPerNode))
diff --git a/app/views/partials/experiment-queue-block.blade.php b/app/views/partials/experiment-queue-block.blade.php
index b78d391..61948d4 100644
--- a/app/views/partials/experiment-queue-block.blade.php
+++ b/app/views/partials/experiment-queue-block.blade.php
@@ -10,6 +10,35 @@
 <input type="hidden" id="queue-array" value="{{ htmlentities( json_encode( $queues ) ) }}"/>
 <input type="hidden" id="app-deployment-defaults-array" value="{{ htmlentities( json_encode( $appDeploymentDefaults ) ) }}"/>
 <input type="hidden" id="queue-defaults-array" value="{{ htmlentities( json_encode( $queueDefaults ) ) }}"/>
+
+<!-- Setting the node count we got from previous page to a hidden field for jquery -->
+@if(isset($expVal['scheduling']->nodeCount))
+<input type="hidden" id="passed-nodeCount" value="{{ $expVal['scheduling']->nodeCount }}"/>
+@else
+<input type="hidden" id="passed-nodeCount" value="0"/>
+@endif
+
+<!-- Setting the cpu count we got from previous page to a hidden field for jquery -->
+@if(isset($expVal['scheduling']->totalCPUCount))
+<input type="hidden" id="passed-cpuCount" value="{{ $expVal['scheduling']->totalCPUCount }}"/>
+@else
+<input type="hidden" id="passed-cpuCount" value="0"/>
+@endif
+
+<!-- Setting the wall time limit we got from previous page to a hidden field for jquery -->
+@if(isset($expVal['scheduling']->wallTimeLimit))
+<input type="hidden" id="passed-wallTime" value="{{ $expVal['scheduling']->wallTimeLimit }}"/>
+@else
+<input type="hidden" id="passed-wallTime" value="0"/>
+@endif
+
+<!-- Setting the physical memory we got from previous page to a hidden field for jquery -->
+@if(isset($expVal['scheduling']->totalPhysicalMemory))
+<input type="hidden" id="passed-physicalmem" value="{{ $expVal['scheduling']->totalPhysicalMemory }}"/>
+@else
+<input type="hidden" id="passed-physicalmem" value="0"/>
+@endif
+
 <div class="form-group required">
     @if( count( $queues) > 0 )
     <label class="control-label" for="node-count">Select a Queue</label>
@@ -94,6 +123,7 @@
 </div>
 
 <script>
+var experimentQueueBlockInit = function() {
     //To work with experiment edit (Not Ajax)
     $( document ).ready(function() {
         var selectedQueue = $("#select-queue").val();
@@ -148,8 +178,8 @@
             readBlob(startByte, endByte, fileId);
         });
     });
-
-    //To work work with experiment create (Ajax)
+    
+    // To work work with experiment create (Ajax)
     var selectedQueue = $("#select-queue").val();
     getQueueData(selectedQueue);
     $("#select-queue").change(function () {
@@ -166,8 +196,13 @@
         var queues = $.parseJSON($("#queue-array").val());
         var queueDefaults = $.parseJSON($("#queue-defaults-array").val());
         var appDefaults = $.parseJSON($("#app-deployment-defaults-array").val());
-
+        //getting the html values we set to hidden fields above!
+        var passedNodeCount = parseInt($("#passed-nodeCount").val());
+        var passedCpuCount = parseInt($('#passed-cpuCount').val());
+        var passedWallTime = parseInt($('#passed-wallTime').val());
+        var passedPhysicalMemory = parseInt($('#passed-physicalmem').val());
         var veryLargeValue = 9999999;
+
         console.log(queues);
         $(".queue-view").addClass("hide");
         for (var i = 0; i < queues.length; i++) {
@@ -192,6 +227,10 @@
                 }else{
                     $("#node-count").val(queueDefaults['nodeCount']);
                 }
+                // load previously set values on page load.
+                if(passedNodeCount!=0){
+                    $("#node-count").val(passedNodeCount);
+                }
 
                 //core-count
                 if (queues[i]['maxProcessors'] != 0 && queues[i]['maxProcessors'] != null) {
@@ -214,6 +253,11 @@
                     $("#cpu-count").val(queueDefaults['cpuCount']);
                 }
 
+                // load previously set values on page load.
+                if(passedCpuCount!=0){
+                    $("#cpu-count").val(passedCpuCount);
+                }
+
 
                 //walltime-count
                 if (queues[i]['maxRunTime'] != null && queues[i]['maxRunTime'] != 0) {
@@ -234,6 +278,11 @@
                     $("#wall-time").val(queueDefaults['wallTimeLimit']);
                 }
 
+                // load previously set values on page load.
+                if(passedWallTime!=0){
+                    $("#wall-time").val(passedWallTime);
+                }
+
                 //memory-count
                 if (queues[i]['maxMemory'] != 0 && queues[i]['maxMemory'] != null) {
                     if($('#enable-auto-scheduling').prop('checked')){
@@ -253,6 +302,12 @@
                     var cpusPerNode = queueDefaults['cpusPerNode'];
                 }
 
+                // load previously set values on page load.
+                if(passedPhysicalMemory!=0){
+                    $("#memory-count").val(passedPhysicalMemory);
+                }
+
+
                 var nodeCount=$("#node-count");
                 var cpuCount=$("#cpu-count");
 
@@ -280,4 +335,12 @@
         }
         $(".queue-view").removeClass("hide");
     }
+}
+
+// On initial load jQuery isn't loaded until later so wait until DOMContentLoaded
+if (typeof $ === 'undefined') {
+    document.addEventListener("DOMContentLoaded", experimentQueueBlockInit);
+} else {
+    experimentQueueBlockInit();
+}
 </script>
\ No newline at end of file
diff --git a/app/views/partials/login-external.blade.php b/app/views/partials/login-external.blade.php
index 393048a..82ecb1a 100644
--- a/app/views/partials/login-external.blade.php
+++ b/app/views/partials/login-external.blade.php
@@ -1,9 +1,7 @@
 
-@foreach ($auth_code_options as $auth_code_option)
-    <a href="{{ $auth_code_option["auth_url"] }}" class="btn btn-primary btn-block">
-        @if (isset($auth_code_option["logo"]))
-        <img src="{{ $auth_code_option["logo"] }}">
-        @endif
-        Sign in with {{{ $auth_code_option["name"] }}}
-    </a>
-@endforeach
+<a href="{{ $auth_code_option["auth_url"] }}" class="btn btn-primary btn-block btn-external-login">
+    @if (isset($auth_code_option["logo"]))
+    <img src="{{ $auth_code_option["logo"] }}">
+    @endif
+    Sign in with {{{ $auth_code_option["name"] }}}
+</a>
diff --git a/public/css/bootstrap.min.css b/public/css/bootstrap.min.css
index cae0f80..2f479ad 100644
--- a/public/css/bootstrap.min.css
+++ b/public/css/bootstrap.min.css
@@ -193,3 +193,30 @@
 	left: 0.5em;
 	margin-right: -50%;
 }
+
+/* vertically center a Bootstrap column. Must be applied to every column in the row. */
+.center-column {
+	display: inline-block;
+	vertical-align: middle;
+	float: none;
+	width: 100%;
+}
+
+.btn-external-login + .btn-external-login {
+	margin-top: 40px;
+}
+
+@media (min-width: 992px) {
+	.center-column.col-md-12 { width:100% }
+	.center-column.col-md-11 { width:91.66666667% }
+	.center-column.col-md-10 { width:83.33333333% }
+	.center-column.col-md-9 { width:75% }
+	.center-column.col-md-8 { width:66.66666667% }
+	.center-column.col-md-7 { width:58.33333333% }
+	.center-column.col-md-6 { width:50% }
+	.center-column.col-md-5 { width:41.66666667% }
+	.center-column.col-md-4 { width:33.33333333% }
+	.center-column.col-md-3 { width:25% }
+	.center-column.col-md-2 { width:16.66666667% }
+	.center-column.col-md-1 { width:8.33333333% }
+}