Index: /issm/trunk-jpl/src/m/classes/clusters/acenet.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/acenet.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/acenet.m	(revision 27262)
@@ -143,5 +143,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/aci.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/aci.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/aci.m	(revision 27262)
@@ -92,5 +92,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/aurora.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/aurora.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/aurora.m	(revision 27262)
@@ -110,5 +110,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/aws_issm_solution_server.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/aws_issm_solution_server.m	(revision 27262)
+++ /issm/trunk-jpl/src/m/classes/clusters/aws_issm_solution_server.m	(revision 27262)
@@ -0,0 +1,236 @@
+%AWS_ISSM_SOLUTION_SERVER cluster class definition
+%
+%   Usage:
+%      cluster=aws_issm_solution_server();
+%      cluster=aws_issm_solution_server('np',3);
+%      cluster=aws_issm_solution_server('np',3,'login','username');
+%
+%   TODO:
+%   - Modify src/m/os/issmscp* with idfile parameter
+
+classdef aws_issm_solution_server
+	properties (SetAccess=public)
+		% {{{
+		name           = '54.67.123.214';
+		login          = '';
+		idfile         = '';
+		modules        = {};
+		numnodes       = 1;
+		cpuspernode    = 8;
+		queue          = '';
+		time           = 12*60*60;
+		srcpath        = '/usr/local/repos/issm/trunk-jpl-head';
+		extpkgpath     = '/usr/local/issm-ext';
+		codepath       = '/usr/local/repos/issm/trunk-jpl-head/bin';
+		executionpath  = '';
+		interactive    = 0;
+		numstreams     = 1;
+		hyperthreading = 0;
+		email          = '';
+	end
+	%}}}
+	methods
+		function cluster=aws_issm_solution_server(varargin) % {{{
+
+			%initialize cluster using default settings if provided
+			if (exist('aws_issm_solution_server_settings')==2), aws_issm_solution_server_settings; end
+
+			%use provided options to change fields
+			cluster=AssignObjectFields(pairoptions(varargin{:}),cluster);
+		end
+		%}}}
+		function disp(cluster) % {{{
+			% display the object
+			disp(sprintf('class ''%s'' object ''%s'' = ',class(cluster),inputname(1)));
+			disp(sprintf('    name: %s',cluster.name));
+			disp(sprintf('    login: %s',cluster.login));
+			disp(sprintf('    idfile: %s',cluster.idfile));
+			disp(sprintf('    modules: %s',strjoin(cluster.modules,', ')));
+			disp(sprintf('    numnodes: %i',cluster.numnodes));
+			disp(sprintf('    cpuspernode: %i',cluster.cpuspernode));
+			disp(sprintf('    np: %i',cluster.nprocs()));
+			disp(sprintf('    time: %i',cluster.time));
+			disp(sprintf('    processor: %i',cluster.processor));
+			disp(sprintf('    srcpath: %s',cluster.srcpath));
+			disp(sprintf('    extpkgpath: %s',cluster.extpkgpath));
+			disp(sprintf('    codepath: %s',cluster.codepath));
+			disp(sprintf('    executionpath: %s',cluster.executionpath));
+			disp(sprintf('    grouplist: %s',cluster.grouplist));
+			disp(sprintf('    interactive: %i',cluster.interactive));
+			disp(sprintf('    numstreams: %s',cluster.numstreams));
+			disp(sprintf('    hyperthreading: %s',cluster.hyperthreading));
+			disp(sprintf('    email: %s',cluster.email));
+		end
+		%}}}
+		function numprocs=nprocs(cluster) % {{{
+			%compute number of processors
+			numprocs=cluster.numnodes*cluster.cpuspernode;
+		end
+		%}}}
+		function md = checkconsistency(cluster,md,solution,analyses) % {{{
+
+			if ((cluster.numnodes>1 ) | (cluster.numnodes<1)),
+				md = checkmessage(md,'only 1 node is currently available');
+			end
+
+			if ((cluster.cpuspernode>8 ) | (cluster.cpuspernode<1)),
+				md = checkmessage(md,'cpuspernode should be between 1 and 8');
+			end
+
+			%Miscellaneous
+			if isempty(cluster.login), md = checkmessage(md,'login empty'); end
+			if isempty(cluster.srcpath), md = checkmessage(md,'srcpath empty'); end
+			if isempty(cluster.extpkgpath), md = checkmessage(md,'extpkgpath empty'); end
+			if isempty(cluster.codepath), md = checkmessage(md,'codepath empty'); end
+			if isempty(cluster.executionpath), md = checkmessage(md,'executionpath empty'); end
+
+		end
+		%}}}
+		function BuildQueueScript(cluster,dirname,modelname,solution,io_gather,isvalgrind,isgprof,isdakota,isoceancoupling) % {{{
+
+			if(isgprof),    disp('gprof not supported by cluster, ignoring...'); end
+
+			executable='issm.exe';
+			if isdakota,
+				version=IssmConfig('_DAKOTA_VERSION_'); version=str2num(version(1:3));
+				if (version>=6),
+					executable='issm_dakota.exe';
+				end
+			end
+			if isoceancoupling,
+				executable='issm_ocean.exe';
+			end
+
+			%write queuing script 
+			fid=fopen([modelname '.queue'],'w');
+			fprintf(fid,'#!/bin/bash\n');
+			fprintf(fid,'export PATH="${PATH}:."\n');
+			fprintf(fid,'export MPI_LAUNCH_TIMEOUT=520\n');
+			fprintf(fid,'export MPI_GROUP_MAX=64\n');
+			fprintf(fid,'export ISSM_DIR="%s"\n',cluster.srcpath);
+			if cluster.extpkgpath
+				fprintf(fid,'export ISSM_EXT_DIR="%s"\n',cluster.extpkgpath);
+			end
+			fprintf(fid,'source $ISSM_DIR/etc/environment.sh\n\n');
+			if cluster.interactive
+				if IssmConfig('_HAVE_MPI_'),
+					fprintf(fid,'mpiexec -np %i %s/%s %s %s %s\n',cluster.nprocs(),cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname);
+				else
+					fprintf(fid,'%s/%s %s %s %s\n',cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname);
+				end
+			else
+				if IssmConfig('_HAVE_MPI_'),
+					fprintf(fid,'mpiexec -np %i %s/%s %s %s %s 2> %s.errlog > %s.outlog &\n',cluster.nprocs(),cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname,modelname,modelname);
+				else
+					fprintf(fid,'%s/%s %s %s %s 2> %s.errlog > %s.outlog &\n',cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname,modelname,modelname);
+				end
+			end
+			if ~io_gather, %concatenate the output files:
+				fprintf(fid,'cat %s.outbin.* > %s.outbin',modelname,modelname);
+			end
+			fclose(fid);
+
+			%in interactive mode, create a run file, and errlog and outlog file
+			if cluster.interactive,
+				fid=fopen([modelname '.errlog'],'w'); fclose(fid);
+				fid=fopen([modelname '.outlog'],'w'); fclose(fid);
+			end
+		end %}}}
+		function UploadQueueJob(cluster,modelname,dirname,filelist) % {{{
+
+			%compress the files into one zip.
+			compressstring=['tar -zcf ' dirname '.tar.gz'];
+			for i=1:numel(filelist),
+				compressstring = [compressstring ' ' filelist{i}];
+			end
+			if cluster.interactive,
+				compressstring = [compressstring ' ' modelname '.run '  modelname '.errlog ' modelname '.outlog '];
+			end
+			system(compressstring);
+
+			disp('uploading input file and queuing script');
+			if cluster.interactive==10,
+				directory=[pwd() '/run/'];
+			elseif cluster.interactive,
+				directory=[cluster.executionpath '/Interactive' num2str(cluster.interactive)];
+			else 
+				directory=cluster.executionpath;
+			end
+
+			%NOTE: Replacement for issmscpout(cluster.name,directory,cluster.login,cluster.port,{[dirname '.tar.gz']});
+			uploadstring=['scp -i ' cluster.idfile ' ' dirname '.tar.gz ' cluster.login '@' cluster.name ':' directory];
+			[status,result]=system(uploadstring);
+			if status, 
+				error(['cluster.UploadQueueJob error message: ' status]);
+			end
+		end
+		%}}}
+		function LaunchQueueJob(cluster,modelname,dirname,filelist,restart,batch) % {{{
+
+			%launch command, to be executed via ssh
+			if cluster.interactive,
+				if ~isempty(restart)
+					launchcommand=['cd ' cluster.executionpath '/Interactive' num2str(cluster.interactive)];
+				else
+					if cluster.interactive==10,
+						launchcommand=['cd ' pwd() '/run && tar -zxf ' dirname '.tar.gz'];
+					else
+						launchcommand=['cd ' cluster.executionpath '/Interactive' num2str(cluster.interactive) ' && tar -zxf ' dirname '.tar.gz'];
+					end
+				end
+			else
+				if ~isempty(restart)
+					launchcommand=['cd ' cluster.executionpath ' && cd ' dirname ' && ./' modelname '.queue'];
+				else
+					launchcommand=['cd ' cluster.executionpath ' && rm -rf ./' dirname ' && mkdir ' dirname ...
+						' && cd ' dirname ' && mv ../' dirname '.tar.gz . && tar -zxf ' dirname '.tar.gz && chmod +x ./' modelname '.queue && ./' modelname '.queue'];
+				end
+			end
+
+			disp('launching solution sequence on remote cluster');
+			%NOTE: Replacement for issmssh(cluster.name,cluster.login,cluster.port,launchcommand);
+			launchstring=['ssh -l ' cluster.login ' -i ' cluster.idfile ' ' cluster.name ' "' launchcommand '"'];
+			[status,result]=system(launchstring);
+			if status,
+				error(['cluster.LaunchQueueJob error message: ' status]);
+			end
+		end
+		%}}}
+		function Download(cluster,dirname,filelist) % {{{
+
+			%copy files from cluster to current directory
+			if cluster.interactive==10,
+				directory=[pwd() '/run/'];
+			elseif ~cluster.interactive,
+				directory=[cluster.executionpath '/' dirname '/'];
+			else
+				directory=[cluster.executionpath '/Interactive' num2str(cluster.interactive) '/'];
+			end
+
+			%NOTE: Replacement for issmscpin(cluster.name,cluster.login,cluster.port,directory,filelist);
+			if numel(filelist)==1,
+				filestring=filelist{1};
+			else
+				filestring='\{';
+				for i=1:numel(filelist)-1,
+					filestring=[filestring filelist{i} ','];
+				end
+				filestring=[filestring filelist{end} '\}'];
+			end
+
+			downloadstring=['scp -i ' cluster.idfile ' ' cluster.login '@' cluster.name ':' directory '/' filestring ' ./'];
+			[status,result]=system(downloadstring);
+			if status, 
+				error(['cluster.Download error message: ' status]);
+			end
+
+			%check scp worked
+			for i=1:numel(filelist),
+				if ~exist(['./' filelist{i}]),
+					warning(['cluster.Download error message: could not scp ' filelist{i}]);
+				end
+			end
+
+		end %}}}
+	end
+end
Index: /issm/trunk-jpl/src/m/classes/clusters/camhpc.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/camhpc.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/camhpc.m	(revision 27262)
@@ -124,5 +124,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/castor.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/castor.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/castor.m	(revision 27262)
@@ -82,5 +82,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/cloud.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/cloud.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/cloud.m	(revision 27262)
@@ -70,5 +70,5 @@
 				error('cloud BuildQueueScript: login should be supplied!');
 			end
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmstscpout(cluster.name,cluster.executionpath,cluster.login,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/cloud.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/cloud.py	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/cloud.py	(revision 27262)
@@ -75,5 +75,5 @@
             raise Exception('cloud BuildQueueScript: login should be supplied!')
 
-        print('uploading input file and queueing script')
+        print('uploading input file and queuing script')
         issmstscpout(self.name, self.executionpath, self.login, '{}.tar.gz'.format(dirname))
     # }}}
Index: /issm/trunk-jpl/src/m/classes/clusters/computecanada.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/computecanada.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/computecanada.m	(revision 27262)
@@ -108,5 +108,5 @@
 			 system(compressstring);
 
-			 disp('uploading input file and queueing script');
+			 disp('uploading input file and queuing script');
 			 issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/cosmos.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/cosmos.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/cosmos.m	(revision 27262)
@@ -82,5 +82,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/cyclone.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/cyclone.py	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/cyclone.py	(revision 27262)
@@ -93,5 +93,5 @@
         subprocess.call(compressstring, shell=True)
 
-        print('uploading input file and queueing script')
+        print('uploading input file and queuing script')
         issmscpout(self.name, self.executionpath, self.login, self.port, [dirname + '.tar.gz'])
     # }}}
Index: /issm/trunk-jpl/src/m/classes/clusters/discover.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/discover.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/discover.m	(revision 27262)
@@ -173,5 +173,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			if cluster.interactive,
 				directory=[cluster.executionpath '/Interactive' num2str(cluster.interactive)];
Index: /issm/trunk-jpl/src/m/classes/clusters/discover.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/discover.py	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/discover.py	(revision 27262)
@@ -181,5 +181,5 @@
         subprocess.call(compressstring, shell=True)
 
-        print('uploading input file and queueing script')
+        print('uploading input file and queuing script')
         if self.interactive:
             directory = '{}/Interactive{}'.format(self.executionpath, self.interactive)
Index: /issm/trunk-jpl/src/m/classes/clusters/discovery.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/discovery.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/discovery.m	(revision 27262)
@@ -145,5 +145,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,0,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/fram.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/fram.py	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/fram.py	(revision 27262)
@@ -144,5 +144,5 @@
         subprocess.call(compressstring, shell=True)
 
-        print('uploading input file and queueing script')
+        print('uploading input file and queuing script')
         issmscpout(self.name, self.executionpath, self.login, self.port, [dirname + '.tar.gz'])
 
Index: /issm/trunk-jpl/src/m/classes/clusters/frontera.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/frontera.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/frontera.m	(revision 27262)
@@ -177,5 +177,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/gemini.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/gemini.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/gemini.m	(revision 27262)
@@ -83,5 +83,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/generic.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/generic.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/generic.m	(revision 27262)
@@ -307,5 +307,5 @@
 				system(compressstring);
 
-				if cluster.verbose, disp('uploading input file and queueing script'); end
+				if cluster.verbose, disp('uploading input file and queuing script'); end
 				issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 			end
Index: /issm/trunk-jpl/src/m/classes/clusters/generic.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/generic.py	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/generic.py	(revision 27262)
@@ -98,5 +98,5 @@
             executable = 'issm_ocean.exe'
 
-        # Write queueing script
+        # Write queuing script
         if not ispc():
             fid = open(modelname + '.queue', 'w')
@@ -200,5 +200,5 @@
         call(compressstring, shell=True)
 
-        print('uploading input file and queueing script')
+        print('uploading input file and queuing script')
         issmscpout(self.name, self.executionpath, self.login, self.port, [dirname + '.tar.gz'])
 
Index: /issm/trunk-jpl/src/m/classes/clusters/generic_static.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/generic_static.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/generic_static.m	(revision 27262)
@@ -77,5 +77,5 @@
 			codepath=strrep(cluster.codepath,' ','\ ');
 
-			% Write queueing script
+			% Write queuing script
 			fid=fopen([modelname '.queue'],'w');
 			fprintf(fid,'#!%s\n',cluster.shell);
Index: /issm/trunk-jpl/src/m/classes/clusters/generic_static.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/generic_static.py	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/generic_static.py	(revision 27262)
@@ -85,5 +85,5 @@
         codepath = self.codepath.replace(' ', '\ ')
 
-        # Write queueing script
+        # Write queuing script
         fid = open(modelname + '.queue', 'w')
         fid.write('#!{}'.format(self.shell) + '\n')
@@ -120,5 +120,5 @@
         codepath = self.codepath.replace(' ', '\ ')
 
-        # Write queueing script
+        # Write queuing script
         fid = open(modelname + '.queue', 'w')
         fid.write('#!{}'.format(self.shell) + '\n')
Index: /issm/trunk-jpl/src/m/classes/clusters/greenplanet.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/greenplanet.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/greenplanet.m	(revision 27262)
@@ -152,5 +152,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/hpc.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/hpc.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/hpc.m	(revision 27262)
@@ -140,5 +140,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/hpc_simba.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/hpc_simba.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/hpc_simba.m	(revision 27262)
@@ -152,5 +152,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/localpfe.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/localpfe.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/localpfe.m	(revision 27262)
@@ -228,5 +228,5 @@
 				system(compressstring);
 
-				if cluster.verbose, disp('uploading input file and queueing script'); end
+				if cluster.verbose, disp('uploading input file and queuing script'); end
 				issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 			end
Index: /issm/trunk-jpl/src/m/classes/clusters/lonestar.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/lonestar.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/lonestar.m	(revision 27262)
@@ -176,5 +176,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/maui.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/maui.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/maui.m	(revision 27262)
@@ -127,5 +127,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/pace.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/pace.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/pace.m	(revision 27262)
@@ -89,5 +89,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/pfe.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/pfe.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/pfe.m	(revision 27262)
@@ -176,5 +176,5 @@
 			fprintf(fid,'export ISSM_DIR="%s"\n',cluster.srcpath); %FIXME
 			if cluster.extpkgpath
-				fprintf(fid,'export ISSM_EXT_PKG="%s"\n',cluster.extpkgpath); 
+				fprintf(fid,'export ISSM_EXT_DIR="%s"\n',cluster.extpkgpath); 
 			end
 			fprintf(fid,'source $ISSM_DIR/etc/environment.sh\n');       %FIXME
Index: /issm/trunk-jpl/src/m/classes/clusters/pfe.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/pfe.py	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/pfe.py	(revision 27262)
@@ -180,5 +180,5 @@
         fid.write('export ISSM_DIR="{}"\n'.format(self.srcpath)) # FIXME
         if self.extpkgpath:
-            fid.write('export ISSM_EXT_PKG="{}"\n'.format(self.extpkgpath)) 
+            fid.write('export ISSM_EXT_DIR="{}"\n'.format(self.extpkgpath)) 
         fid.write('source $ISSM_DIR/etc/environment.sh\n') # FIXME
         fid.write('cd {}/{}/\n\n'.format(self.executionpath, dirname))
Index: /issm/trunk-jpl/src/m/classes/clusters/raijin.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/raijin.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/raijin.m	(revision 27262)
@@ -102,5 +102,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/saga.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/saga.py	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/saga.py	(revision 27262)
@@ -153,5 +153,5 @@
         subprocess.call(compressstring, shell=True)
 
-        print('uploading input file and queueing script')
+        print('uploading input file and queuing script')
         issmscpout(self.name, self.executionpath, self.login, self.port, [dirname + '.tar.gz'])
     # }}}
Index: /issm/trunk-jpl/src/m/classes/clusters/sherlock.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/sherlock.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/sherlock.m	(revision 27262)
@@ -135,5 +135,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
Index: /issm/trunk-jpl/src/m/classes/clusters/smce_eis.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/smce_eis.py	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/smce_eis.py	(revision 27262)
@@ -177,5 +177,5 @@
         subprocess.call(compressstring, shell=True)
 
-        print('uploading input file and queueing script')
+        print('uploading input file and queuing script')
         if self.interactive:
             directory = '{}/Interactive{}'.format(self.executionpath, self.interactive)
Index: /issm/trunk-jpl/src/m/classes/clusters/tetralith.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/tetralith.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/tetralith.m	(revision 27262)
@@ -192,5 +192,5 @@
 			end
 			system(compressstring);
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			directory=cluster.executionpath;
 % 			issmbbftpout(cluster.name,directory,cluster.login,cluster.port,cluster.numstreams,{[dirname '.tar.gz']});
Index: /issm/trunk-jpl/src/m/classes/clusters/yellowstone.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/yellowstone.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/classes/clusters/yellowstone.m	(revision 27262)
@@ -128,5 +128,5 @@
 			system(compressstring);
 
-			disp('uploading input file and queueing script');
+			disp('uploading input file and queuing script');
 			directory=cluster.executionpath;
 
Index: /issm/trunk-jpl/src/m/solve/waitonlock.m
===================================================================
--- /issm/trunk-jpl/src/m/solve/waitonlock.m	(revision 27261)
+++ /issm/trunk-jpl/src/m/solve/waitonlock.m	(revision 27262)
@@ -43,16 +43,19 @@
 %prepare command if the job is not running on the local machine
 if ~strcmpi(oshostname(),cluster.name),
-	login = cluster.login;
-	port  = 0;
-	if isprop(cluster,'port') 
-		port = cluster.port;
-	end
-	if port,
-		command = ['ssh -l ' login ' -p ' num2str(port) ' localhost "[ -f ' lockfilename ' ] && [ -f ' logfilename ' ]" 2>/dev/null'];
-	elseif isa(cluster,'cloud')
+	if isa(cluster,'cloud'),
 		command = [' [ -f ' lockfilename ' ] && [ -f ' logfilename ' ] 2>/dev/null'];
 		command = [starcluster() ' sshmaster ' cluster.name ' --user ' cluster.login ' ''' command ''''];
 	else
-		command = ['ssh -l ' login ' ' cluster.name ' "[ -f ' lockfilename ' ] && [ -f ' logfilename ' ]" 2>/dev/null'];
+		command = ['ssh -l ' cluster.login];
+		if isprop(cluster,'idfile') && ~strcmp(cluster.idfile,''),
+			command = [command ' -i ' cluster.idfile];
+		end
+		port=0;
+		if isprop(cluster,'port') && cluster.port,
+			command = [command ' -p ' num2str(port) ' localhost'];
+		else,
+			command = [command ' ' cluster.name];
+		end
+		command = [command ' "[ -f ' lockfilename ' ] && [ -f ' logfilename ' ]" 2>/dev/null'];
 	end
 end
Index: /issm/trunk-jpl/src/m/solve/waitonlock.py
===================================================================
--- /issm/trunk-jpl/src/m/solve/waitonlock.py	(revision 27261)
+++ /issm/trunk-jpl/src/m/solve/waitonlock.py	(revision 27262)
@@ -61,8 +61,6 @@
                 command += ' -i {}'.format(cluster.idfile)
             port = 0
-            if isprop(cluster, 'port'):
-                port = cluster.port
-            if port: # Check if port is non-zero
-                command += ' -p {} localhost'.format(port)
+            if isprop(cluster, 'port') && cluster.port:
+                command += ' -p {} localhost'.format(port);
             else:
                 command += ' {}'.format(cluster.name)
@@ -82,8 +80,4 @@
             outs, errs = subproc.communicate()  # NOTE: Need to consume output before checking return code
 
-            # TODO: Debug the following check under Linux (exits after first iteration with errs = "b")
-            # UPDATE: Works in testing under Debian Linux system. Leaving comment for now so that it is easier to backtrace this issue if someone else encounters it.
-            # FIXED: comunicates returns stuff in bytes in Python 3 unless you set "universal_newlines=True"
-            #
             if errs != '':
                raise Exception('waitonlock: check for existence of files failed: {}'.format(errs))
Index: /issm/trunk-jpl/test/NightlyRun/runme.m
===================================================================
--- /issm/trunk-jpl/test/NightlyRun/runme.m	(revision 27261)
+++ /issm/trunk-jpl/test/NightlyRun/runme.m	(revision 27262)
@@ -235,5 +235,5 @@
 					archive_cell=archread(['../Archives/' archive_name '.arch'],[archive_name '_field' num2str(k)]);
 					archive=archive_cell{1};
-					error_diff=full(max(abs(archive(:)-field(:)))/(max(abs(archive(:)))+eps));					%disp test result
+					error_diff=full(max(abs(archive(:)-field(:)))/(max(abs(archive(:)))+eps)); %disp test result
 					if (error_diff>tolerance | isnan(error_diff));
 						disp(sprintf(['ERROR   difference: %-7.2g > %7.2g test id: %i test name: %s field: %s'],...
Index: /issm/trunk-jpl/test/NightlyRun/test101awsissmsolutionserver.m
===================================================================
--- /issm/trunk-jpl/test/NightlyRun/test101awsissmsolutionserver.m	(revision 27262)
+++ /issm/trunk-jpl/test/NightlyRun/test101awsissmsolutionserver.m	(revision 27262)
@@ -0,0 +1,94 @@
+%Test Name: SquareShelfConstrainedStressSSA2d
+md=triangle(model(),'../Exp/Square.exp',50000.);
+md=setmask(md,'all','');
+md=parameterize(md,'../Par/SquareShelfConstrained.par');
+md=setflowequation(md,'SSA','all');
+md.cluster=generic('name',oshostname(),'np',2);
+
+if true
+	cluster=aws_issm_solution_server;
+	cluster.login='';
+	cluster.idfile='';
+	cluster.executionpath='~/issm-exec';
+	md.cluster=cluster;
+end
+
+%output
+md.stressbalance.requested_outputs={'default','DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6'};
+md.outputdefinition.definitions={...
+	massfluxatgate('name','MassFlux1','profilename',['../Exp/MassFlux1.exp'],'definitionstring','Outputdefinition1'),...
+	massfluxatgate('name','MassFlux2','profilename',['../Exp/MassFlux2.exp'],'definitionstring','Outputdefinition2'),...
+	massfluxatgate('name','MassFlux3','profilename',['../Exp/MassFlux3.exp'],'definitionstring','Outputdefinition3'),...
+	massfluxatgate('name','MassFlux4','profilename',['../Exp/MassFlux4.exp'],'definitionstring','Outputdefinition4'),...
+	massfluxatgate('name','MassFlux5','profilename',['../Exp/MassFlux5.exp'],'definitionstring','Outputdefinition5'),...
+	massfluxatgate('name','MassFlux6','profilename',['../Exp/MassFlux6.exp'],'definitionstring','Outputdefinition6')...
+	};
+
+md=solve(md,'Stressbalance');
+
+%Fields and tolerances to track changes
+field_names     ={'Vx','Vy','Vel','Pressure',...
+	'DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6'};
+field_tolerances={3e-13,1e-13,1e-13,1e-13,...
+	2e-13,1e-13,2e-13,...
+	1e-13, 1e-13, 1e-13, 1e-13, 1e-13, 1e-13 };
+field_values={...
+	(md.results.StressbalanceSolution.Vx),...
+	(md.results.StressbalanceSolution.Vy),...
+	(md.results.StressbalanceSolution.Vel),...
+	(md.results.StressbalanceSolution.Pressure),...
+	(md.results.StressbalanceSolution.DeviatoricStressxx),...
+	(md.results.StressbalanceSolution.DeviatoricStressyy),...
+	(md.results.StressbalanceSolution.DeviatoricStressxy),...
+	(md.results.StressbalanceSolution.MassFlux1),...
+	(md.results.StressbalanceSolution.MassFlux2),...
+	(md.results.StressbalanceSolution.MassFlux3),...
+	(md.results.StressbalanceSolution.MassFlux4),...
+	(md.results.StressbalanceSolution.MassFlux5),...
+	(md.results.StressbalanceSolution.MassFlux6)...
+	};
+
+id=101;
+id_string='test101';
+archive_name=['Archive101'];
+for k=1:length(field_names),
+
+	try,
+		%Get field and tolerance
+		field=field_values{k};
+		fieldname=field_names{k};
+		tolerance=field_tolerances{k};
+
+		%compare to archive
+		%our output is in the correct order (n,1) or (1,1), so we do not need to transpose again
+		archive_cell=archread(['../Archives/' archive_name '.arch'],[archive_name '_field' num2str(k)]);
+		archive=archive_cell{1};
+		error_diff=full(max(abs(archive(:)-field(:)))/(max(abs(archive(:)))+eps)); %disp test result
+		if (error_diff>tolerance | isnan(error_diff));
+			disp(sprintf(['ERROR   difference: %-7.2g > %7.2g test id: %i test name: %s field: %s'],...
+				error_diff,tolerance,id,id_string,fieldname));
+			if(getfieldvalue(options,'stoponerror',0)), disp('STOP'); return; end
+		else
+			disp(sprintf(['SUCCESS difference: %-7.2g < %7.2g test id: %i test name: %s field: %s'],...
+				error_diff,tolerance,id,id_string,fieldname));
+		end
+
+	catch me2
+
+		%something went wrong, print failure message:
+		message=getReport(me2);
+		fprintf('%s',message);
+		if strcmpi(output,'nightly')
+			fid=fopen([issmdir() '/nightlylog/matlaberror.log'], 'at');
+			fprintf(fid,'%s',message);
+			fprintf(fid,'\n------------------------------------------------------------------\n');
+			fclose(fid);
+			disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,fieldname));
+		else
+			disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,fieldname));
+			fprintf('%s',message);
+			if(getfieldvalue(options,'stoponerror',0)), disp('STOP'); return; end
+		end
+		continue;
+	end
+end
