function [out,out1] = sdtcheck(varargin);

% Verification that the SDT is properly installed and installation if needed
%
% Accepted commands
%
%  <a href="matlab:sdtcheck rlmstat">sdtcheck rlmstat</a>      : verifies the status of current license
%  <a href="matlab:sdtcheck rlmstatExp">sdtcheck rlmstatExp</a>   : displays license expiration dates
%  <a href="matlab:sdtcheck patchupgrade">sdtcheck patchUpgrade</a> : update SDT from sdtcur (latest beta version)
%  <a href="matlab:sdtcheck('patchupgrade ../download/daily/sdtdaily_dis.p')">sdtcheck 'patchupgrade ../download/daily/sdtdaily_dis.p'</a> : update from sdt.daily (latest alpha version)
%  <a href="matlab:sdtcheck PatchJavapath">sdtcheck PatchJavapath</a> : verify java path
%
%     sdtcheck path       : resets the path to the sdtcheck directory location
%     sdtcheck check      : verification of current installation 
%     sdtcheck helps      : rebuild the help search database/path/... 
%     sdtcheck uninstall  : generates a script for uninstallation 
%     sdtcheck DependsMsvc : microsoft runtime dependencies
%     sdtcheck Dependsmkl_utils : seeks depends.exe in sdt/7.5 and tests
%     sdtcheck syspathlib : checks paths for SDT libraries
%     sdtcheck patchmkl   : download mkl_patch
%     sdtcheck pyenv      : setup python environment
%     

%       Etienne Balmes
%       Copyright (c) 1990-2024 by SDTools, All Rights Reserved.

if nargin==1 && strcmp(varargin{1},'cvs')
 out='$Revision: 1.277 $  $Date: 2024/04/25 07:33:13 $'; return;
end

persistent st LastPatch
%#ok<*ASGLU,*NASGU,*TRYNC,*NOSEM,*CTCH,*MXFND,*STREMP>

if nargin==0 && nargout==1; CAM = 'check'; 
elseif nargin==0 
   aa=pwd; st0=which('sdtcheck');
   if isempty(strfind(st0,'found')); st0=st0(1:strfind(st0,'sdtcheck')-1); end
   st1=which('sp_util');
   if isempty(strfind(st1,'found')); st1=st1(1:strfind(st1,'sp_util')-1);end
   if strncmpi(st0,st1,length(st0));  CAM = 'check'; else; CAM='install'; end
elseif ischar(varargin{1}); CAM=varargin{1};
else; CAM=varargin{3};
end

[CAM,Cam]=comstR(CAM,1);

%% About --------------------------------------------------------------------
if comstR(Cam,'about'); [CAM,Cam]=comstR(CAM,6); 
  sdtkey('about');
  
%% #SiteReq : script to generate license request ----------------------------1
elseif strncmpi(CAM,'sitereq',7) % rlm request

if  exist('sdtrlm','file')==3
if ~exist(['./sdtrlm.',mexext],'file')
 f2=fullfile(fileparts(which('sdtcheck')),'7.5');
 if exist(f2,'dir');addpath(f2);end
end
if ~exist(['sdtrlm.',mexext],'file')
 fprintf('\nMove to the directory where you extracted sdtrlm.mex*\n')
 return;
end
end
f2=fullfile(prefdir,'sdt.lic');
if ~exist(f2,'file')
 f2=fullfile(fileparts(which('sdtrlm')),'sdt.lic');
 if ~isempty(regexp(f2,'toolbox[\\/]', 'once'))
  error('You must not place sdtcur in the MATLAB toolbox path but a temporary directory')
 end
end
if ~exist(f2,'file'); 
 try
 fid=fopen(f2,'w');fprintf(fid,[' ' char(35) ' SDT Request on %s', ...
     ],datestr(now,'dd-mmm-yyyy'));
 fclose(fid);
 catch;
  error('You must have write permission to the extraction directory\n %s', ...
      fileparts(f2))
 end
end
 st1={'mu','Matlab/user';
      'cu','Computer/user';
      'dc','Designated computer';'sa','';'sb','';'sc',''};
carg=2;
if nargin>1&&~any(strcmpi(varargin{2},st1(:,1))); RO.req=varargin{carg};carg=carg+1;%sdtcheck('sitereq','base-fem')
else
 li={'SDT-base (modal analysis, FEM, reduction, piezo, ...)', ...
  'FEMLink (import/export Abaqus, Nastran, Ansys, ...)', ...
  'visc (Viscoelastic vibration)', ...
  'contact (non conform contact problems)', ...
  'rotor (Cyclic-symmetry, some rotor dynamics)', ...
  'nlsim (solvers for HBM and NL transient)', ...
  'SDT-Runtime (SDT with MATLAB Compiler)', ...
  'Oscar (SNCF Pantograph/catenary)','OscarUI (GUI for OSCAR)'};
 [i1,v]=listdlg('Name','SDTools product selection', ...
  'PromptString','Select product(s) requested : ',...
  'ListString',li, ...
  'InitialValue',[1 2],'listsize',[500 300]);
 if v==0;return;end
 li=li(i1);li=lower(cellfun(@(x)sscanf(x,'%s',1),li,'uni',0));
 st2={'SDT-base','base';'FEMLink','fem'};
 for j1=1:size(st2,1);li(strcmpi(li,st2{j1,1}))=st2(j1,2);end
 RO.req=sprintf('%s-',li{:});RO.req(end)='';
end
try; sdtrlm('cvs') % Verify present of runtime libraries
catch
 if ispc
  sdtcheck('syspathadd',fullfile(fileparts(which('sdtcheck')),'sys'))   
 else; error('Problem with the sdtrlm.mex file')
 end
end

try
 %a=sdtrlm('hostid');if ~iscell(a);a=sdtrlm('hostid');end
 st2=regexprep(version,'( .*)','');st2(max(find(st2=='.',2)):end)='';
 RO.ver=st2;
 RO.targ=mexext;RO.targ(1:3)='';
 % sdtcheck('sitereq','base-fem','mu')
 if carg<=nargin; RO.type=varargin{carg};carg=carg+1;else; RO.type='mu'; end
 if ~ismember(RO.type,st1(:,1));RO.type=st1{1};end
 RO.v='v74';try; RO.v=sprintf('v%s',strrep(sdtdef('ver'),'.',''));end
 if strcmpi(RO.type,'mu')
  st3=sdtcheck('rlmhostidMu');
  st3=sprintf('SE.t%s.%s_"%s"_%s_"%s"_"%s"_"%s"',datestr(now,'mmmyy'),RO.v,RO.req, ...
    st3, ...  %hostid strings
    RO.ver,RO.targ,datestr(now,'mmmyy'));
 elseif any(strcmpi(RO.type,{'cu','dc','sa','sb'}))
  st3=sdtcheck(['rlmhostid' RO.type]);
  st3=sprintf('SE.t%s.%s_"%s"_%s_"%s"_"%s"_"%s"',datestr(now,'mmmyy'),RO.v,RO.req, ...
    st3, ...  %hostid strings
    RO.ver,RO.targ,datestr(now,'mmmyy'));
 else
  st3=sdtcheck('rlmhostid');
  st3=sprintf('SE.t%s.%s.%s_"%s"_%s_"%s"_"%s"_"%s"',datestr(now,'mmmyy'),RO.v,RO.type,RO.req, ...
    st3, ...  %hostid strings
    RO.ver,RO.targ,datestr(now,'mmmyy'));
 end
 st=sprintf('\n\n%s \n%s\n\n''%s''\n\n', ...
     'Please email the following string to request@sdtools.com',...
    ' with a comment on who you are and motivation for the request (demo, ...)', ...
    st3); % Matlab ver, mexext
 if nargout==1;out=st3;else; disp(st);end
catch
 sdtrlm('cvs')
 which('sdtrlm');
 fprintf('Failed with %s',lasterr);
end
% Generate the license request string

%% #Host #HostIP -------------------------------------------------------------
elseif comstR(Cam,'host')
 if isunix
  checkShellEnv;
  if ~isempty(strfind(Cam,'ip')); st1='-i'; else; st1=''; end
  [i0,out]=system(sprintf('hostname %s',st1)); % should always work
  if i0||isempty(out); % in case hostname command failed
   out=cleanGetEnv({'HOST','host','HOSTNAME','hostname'});
   if ~isempty(st1) % recover IP, using ping
    [i1,out]=system(sprintf('ping -c1 %s',out));
    if i1==0 % call worked, it can fail if host not recovered
     out(1:find(out=='(',1,'first'))=''; out=textscan(out,'%s',1);
     out=out{1}{1};out(end)='';
    else % resort to ifconfig, rethrow the first one
     [i1,out]=system('ifconfig');
     gg=regexp(out,'inet addr:([0-9\.]*)','tokens');
     out=out{1};
    end
   end
  else; out=strtrim(out); % trim output of hostname command
  end
  
 else %PC
  if ~isempty(strfind(Cam,'ip')) % ask for IP
   [i1,out]=system('ipconfig');
   i1=strfind(out,'IPv4');
   if ~isempty(i1)
    out(1:strfind(out,'IPv4'))='';out(1:find(out==':',1,'first'))='';
   else
    out(1:strfind(out,'IP Address'))='';out(1:find(out==':',1,'first'))='';
   end
   out=textscan(out,'%s',1);out=out{1};if iscell(out); out=out{1}; end
   if isempty(intersect(out,'123456789')); out='127.0.0.1';end
   
  else % ask for hostname
   out=cleanGetEnv({'USERDOMAIN','HOST','HOSTNAME'});
  end
 end
 
%% #Revision -----------------------------------------------------------------
elseif comstR(Cam,'revision')
 if nargin>1&&isempty(strfind(varargin{2},'$Revision'))
  % sdtcheck('revision','fun')
  f1=varargin{2};
  [wd,root,ext]=fileparts(f1);
  if isempty(wd)||isempty(ext); [wd,root,ext]=fileparts(which(f1)); end
  if isempty(root); error('no function %s found',f1); end
 else % Coming from function use stack 
  r1=dbstack('-completenames');
  [wd,root,ext]=fileparts(sdth.fileutil('cffile',r1(2).file));
 end
 wd0=pwd; out='';
 try
  cd(wd);st1=[root ext];
  % ok for unix and pc
  [i0,st2]=system(sprintf('git --no-pager log -1 --pretty="format:#Revision: %%h #  #Date: %%ci #" %s  ',[root ext]));
  if i0
   if nargin==2&&~isempty(strfind(varargin{2},'$Revision'))
    disp('Using fixed revision ''%s''',varargin{2});
    out=varargin{2};
   else
     sdtw('_nb','No revision is accessible for %s\n %s',st1,st2);
   end
  else; 
    if nargin<2||isempty(strfind(varargin{2},'$Revision'))
      sdtw('_ewt','should define fixed revision with sd(''cvsgit'',''%s'')',root);
    else
     st3=comstr(regexprep(varargin{2},'\$',char(35)),1);
     if ~isequal(st2,st3)&&sdtkey('isdev')
      fprintf('Consider updating fixed revision before commit with\n sd(''cvsgit'',''%s'')',root);
     end
    end
    out=st2;
  end
 catch; 
   if nargin==2&&~isempty(strfind(varargin{2},'$Revision'))
    out=varargin{2};
   else; out='';
   end
 end
 out=strrep(out,char(35),'$');
 cd(wd0);
 
%% #User ---------------------------------------------------------------------
elseif comstR(Cam,'user')
 if isunix
  checkShellEnv;
  [i0,out]=system('id -u -n');
  if i0||isempty(out) % in case id command failed
   out=cleanGetEnv({'USER','user','USERNAME','username','LOGNAME','logname'});
  else; out=strtrim(out);
  end
 else % PC
  out=cleanGetEnv({'USERNAME','USER','LOGNAME'});
 end
 
%% #Memory -------------------------------------------------------------------
elseif comstR(Cam,'meminfo')
 % recover free memory available robust to platforms
 %[freem,totalm]=sdtcheck('meminfo -g');
 if isunix
  [r1,st1] = unix('free -b | grep Mem');
  stats = str2double(regexp(st1, '[0-9]*', 'match'));
  out1 = stats(1);  out = (stats(3)+stats(end)); % free+buffers
 else
  [r1,r2]=memory;
  out=r2.PhysicalMemory.Available; out1=r2.PhysicalMemory.Total;
 end
 if contains(Cam,'-k'); out=out/1024; out1=out1/1024;
 elseif contains(Cam,'-m'); out=out/1024^2; out1=out1/1024^2;
 elseif contains(Cam,'-g'); out=out/1024^3; out1=out1/1024^3;
 end

%% #Top: check matlab status by pid ------------------------------------------
elseif comstR(Cam,'top')
 % sdtcheck('tops')
 % sdtcheck('topget',10933)
 % sdtcheck('topgetMATLAB',10933); % can be other process
 st=''; if nargin>1; st=varargin{2}; end
 if ~ischar(st); st=num2str(st); end
 st0=st; stget='';
 if comstR(Cam,'topget')
  [CAM,Cam,stget]=comstr('get',[-25 4],CAM,Cam);
  if isempty(stget); stget='MATLAB'; end
 end
 if isunix
  if isempty(st);
   try;st=sprintf('%i',feature('getpid'));catch; [i1,st]=system('whoami');end
  end
  if isempty(stget); stp='MATLAB'; else; stp=stget; end
  [i1,st]=system(sprintf('top -bn1 | grep %s | grep %s',stp,st));
  if ~isempty(stget)
   st=strtrim(st);
   in1=find(diff(isstrprop(st,'digit')),1,'first');
   if isempty(in1); in1=length(st0); end
   if in1<=length(st)&&isequal(st(1:in1),st0); out=1; else; out=0; end
   return
  elseif comstr(Cam,'tops');
   r1=dbstack;fprintf('Process check : %-15s line %i\n',r1(end).name,r1(end).line);
  end
  disp(st);
  
 else; % ispc
  try
   if isempty(st); st=num2str(feature('getpid')); end
   st0=st;
   [i0,st]=system(sprintf('tasklist /FI "PID eq %s"',st));
   st1=textscan(st,'%s'); st1=st1{1};
   if ~isempty(stget)
    in1=strncmpi(st1,stget,6);
    if any(in1); out=1; else; out=0; end;
    return;
   else
    r1=st1{end-1}; r1=regexprep(r1,'\D',''); r1=str2double(r1);
    fprintf('Process %s Memory %i Mb\n',st0,fix(r1/1024))
   end
  catch;  i0=1; if comstr(Cam,'topget'); out=0; return; end
  end
  if i0;    a=memory;fprintf('Memory %i Mb\n',fix(a.MemUsedMATLAB/1024^2)); end
 end
 if ~isempty(strfind(Cam,'tic'));eval('tic');end
 if ~isempty(strfind(Cam,'toc'));eval('toc');end
 
 
%% #ClearSDTClasses
elseif comstR(Cam,'clearsdtclasses')
 [st1,st2,st3]=inmem('-completenames');
 root=sdtcheck('SDTRootDir');
 i1=strncmpi(st1,root,length(root));
 [st1,st12,st13]=cellfun(@(x)fileparts(x),st1(i1),'uni',0);
 i3=cellfun(@(x)strfind(x,'.'),st3,'uni',0); i4=~cellfun(@isempty,i3);
 st3(i4)=cellfun(@(x,y)x(1:y-1),st3(i4),i3(i4),'uni',0);
 li=intersect(st12,st3);
 for j1=1:length(li)
  eval(sprintf('clear %s',li{j1}));
 end
 if ~isempty(li); sdtw('_nb','cleared SDT classes: %s ',sprintf('\n%s',li{:}))
 else; sdtw('_nb','No SDT classes were loaded')
 end
 
%% #SDTrootdir
elseif comstR(Cam,'sdtrootdir')
 out=fileparts(which('ii_fin'));
%% #MCCrootdir
elseif comstR(Cam,'mccrootdir')
 % recover location of mcc exe file in deployed mode, base sdtroot othserwise
 if isdeployed
  try
   if isunix
    [i0,st1]=system(sprintf('top -bcn1 -p%i -w512',feature('getpid')));
    if i0; error('1'); end
    st1=textscan(st1,'%s'); out=st1{1}{end}; % may not be robust to spaces...
   else
    [i0,st1]=dos(sprintf('PowerShell Get-Process -Id %i -FileVersionInfo < nul',feature('getpid')));
    if i0; error('1'); end
    st2=textscan(st1,'%s','delimiter','\t\b\n','multipledelimsasone',1);
    st2=st2{1};i1=strfind(st2{1},'FileName');
    out=strtrim(st2{end}(i1:end));
    if ~exist(out,'file') % try older stra if this one failed
     i1=strfind(st1,repmat('-',1,8)); % FileName assumed last
     out=strtrim(st1(i1(end)+9:end));
    end
   end
  catch; sdtw('_nb','failed MccRootDir recovery with %s',st1); out='';
  end
  [out,out1,ext]=fileparts(out); out1=[out1 ext];
  if isempty(out)&&length(varargin)>1; out=varargin{2}; end % allow default
  if ~isempty(strfind(Cam,'-vh'))
   gf=cingui('rwarn_HANDLE'); % clean init
   out=v_handle('uo',{gf,'tag','base_wd'},'',out);
  end
 else; out=sdtcheck('sdtrootdir'); out1='';
 end
 %% #MccInfo -2
elseif comstR(Cam,'mccinfo')
 out=''; f0=fullfile(sdtcheck('SDTRootDir'),'Contents.m');
 if isdeployed
  try
   f1=fullfile(fileparts(which('SdtRunKey')),'mccinfo.txt');
   if ~exist(f1,'file');   f1=fullfile(ctfroot,'deploy','mccinfo.txt'); end % <909
   if exist(f1,'file'); type(f1); out=f1; end
  end
  out1=evalc(sprintf('type %s;',out));
  out1=strrep(out1,' - ',char(10));
 else; out=f0; out1='';
 end
 if nargout==0; clear out;
 else;
  try
  st1=evalc(sprintf('type %s;',f0));
  st1=textscan(st1,'%s','delimiter','%\n\t','multipledelimsasone',true);
  if ~isempty(st1); st1=st1{1}; end
  if ~isempty(st1); st1=st1(1:min(length(st1),4)); end
  if length(st1)<4
   sty=datestr(datenum(st1{2}(strfind(st1{2},'Built')+6:end)),'yyyy');
   st1{end+1}=sprintf('Copyright (c) 1990 - %s by SDTools\nAll Rights Reserved.',sty);
  end
  st1=sprintf('%s\n',st1{:});
  catch; 
   st1=sdtcheck('cvs'); st1=st1(strfind(st1,'$Date')+7:end-1);
   st1=datestr(datenum(st1),'yyyy');
   st1=sprintf('Structural Dynamics Toolbox\nCopyright (c) 1990-%s by SDTools\nAll Rights Reserved.',st1);
  end
  stv=builtin('version');
  sty=regexp(stv,'.*R([0-9]{4,4}).*','tokens'); sty=sty{1}{1};
  if isempty(out1); out1=sprintf('\n\n\n\n',out1); end
  out1=sprintf(['%s\n%s\nMATLAB Version %s\n'...
   'MATLAB(r). (c) 1984 - %s The MathWorks, Inc.'],out1,st1,stv,sty);
 end

%% #MCRrootdir: location of the runtime libraries -2
elseif comstR(Cam,'mcrrootdir')
 try
  r1=which('strfind','-all');
  r1=r1{find(strncmp(r1,'built-in',8),1,'first')};
  r1=textscan(r1(9:end),'%s','whitespace',' \t\b()'); r1=r1{1}{1};
  i1=strfind(r1,'toolbox'); 
  if ~isempty(i1);r1=r1(1:(i1(1)-1));else;r1=getenv('MCRROOT');
  end
 catch
  r1=getenv('MCRROOT');
 end
 out=r1;
 
%% #CPUVendor ----------------------------------------------------------------
elseif comstR(Cam,'cpuvendor')
 if isunix
  [i0,out]=system('lscpu');
  if i0; [i0,out]=system('cat /proc/cpuinfo | grep vendor_id');
   if i0; error('Could not recover CPU info'); end
  else;
   out=textscan(out,'%s','delimiter',':'); 
   if isempty(i0);out='';else;out=out{1}{i0+1};end
  end
  
 else; out=getenv('PROCESSOR_IDENTIFIER'); % PC
 end
 if ~isempty(strfind(lower(out),'intel')); out='intel';
 else; out='amd';
 end
 
%% #DefaultBrowserCom
elseif comstR(Cam,'defaultbrowsercom')
 if isunix
  % xxx this seems sufficient in linux to have an acceptable behavior
  st1='web(''%1'')';

 else % in windows, web command may miss hastag anchors, need direct call to browser

  try % recover user default browser
   [i0,st1]=system('reg QUERY HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.html\UserChoice /v ProgId');
   st2=regexp(st1,'.*REG_SZ(.*)$','tokens'); st2=strtrim(st2{1}{1});
   [i0,st1]=system(sprintf('reg QUERY HKEY_CLASSES_ROOT\\%s\\shell\\open\\command /ve',st2));
  catch; i0=1;
  end

  if i0 % if failed, look for more simple defaults
   [i0,st1]=system('reg QUERY HKEY_CLASSES_ROOT\http\shell\open\command /ve');
   if i0
    [i0,st1]=system('reg QUERY HKEY_CLASSES_ROOT\htmlfile\shell\open\command /ve');
   end
  end
  if i0; sdtw('_nb''Could not get default browser, using MATLAB web')
   st1='web(''%1'')';
  else
   i1=strfind(st1,'REG_SZ'); st1=strtrim(st1(i1+6:end));
   if isempty(strfind(st1,'%1')); st1=[st1 '"%1"']; end
   if st1(end)~='&'; st1=[st1 ' &']; end
   st1=sprintf('system(''%s'')',st1);
  end
 end

 out=st1;

 %% #fun ---------------------------------------------------------------------
elseif comstR(Cam,'fun'); [CAM,Cam]=comstR(CAM,4);
 % check if function is available
 out=false; fun=varargin{2};
 try; out=feval(fun,'@true'); out=out(1); 
 catch;  if ~isempty(Cam); sdtw('_nb','function %s not available',fun); end
 end
  
%% #Chmod --------------------------------------------------------------------
elseif comstR(Cam,'chmod'); [CAM,Cam]=comstR(CAM,6);
 
 ua=sdtkey('disdirlist');
 ind=[strmatch('6',ua.subdir);strmatch('7',ua.subdir)];
 if isunix
  st={sprintf('!chmod a+rx "%s"',fullfile(ua.toolbox,'*','*.mex*'))};
 else
  st={};
  for j1=1:length(ind)
   a=fullfile(ua.toolbox,ua.subdir{ind(j1)});
   %sprintf('!cacls "%s" /E /G "%%username%%:R"',fullfile(a,'*.dll'));
   st(end+1,1)={ ...
      sprintf('!cacls "%s" /E /G "%%username%%:R"',fullfile(a,'*.mex*'))}; %#ok<AGROW>
  end
 end
 for j1=1:length(st);disp(st{j1});eval(st{j1});end

%% #Uninstall ----------------------------------------------------------------
elseif comstR(Cam,'uninstall'); [CAM,Cam]=comstR(CAM,6);


 ua=sdtkey('disdirlist'); wd=ua.toolbox;
 list={};
 for j1=1:length(ua.subdir)
  if exist(fullfile(ua.toolbox,ua.subdir{j1}),'dir')
    list{end+1,1}=fullfile(ua.toolbox,ua.subdir{j1}); %#ok<AGROW>
  end
 end
 for j1=1:length(ua.hsubdir)
  if exist(fullfile(ua.help,ua.hsubdir{j1}),'dir')
    list{end+1,1}=fullfile(ua.help,ua.hsubdir{j1}); %#ok<AGROW>
  end
 end

 for j1=1:length(list)
  if ~isempty(strfind(list{j1},'sdt.cur'))||~isempty(strfind(list{j1},'sdtdev'))
    list{j1}=''; %#ok<AGROW>
  end
 end
 [list,i2]=sortrows(list);list=list(end:-1:1);

 fprintf('%% To uninstall run the following commands \n\n')
 for j1=1:length(list)
  if ~isempty(list{j1})
   fprintf('st=''%s'';cd(st);delete *.*;cd ..;!rmdir %s\n',list{j1},list{j1});
  end
 end 

% -----------------------------------------------------------------------
%% #check general compatibility checks for current configuration 
elseif comstR(Cam,'check'); [CAM,Cam]=comstR(CAM,6);

cf=findobj('tag','sdt4i'); 
if ~isempty(cf); st = get(cf,'userdata'); else; st=[]; end

% verification of source and target directories

ua=sdtkey('disdirlist');
if comstR(Cam,'h')
elseif exist(CAM,'dir'); ua.toolbox=CAM;
end

un_message('Checking installation');
pw0=pwd;

% build actual list of files
st0={ua.toolbox;fullfile(ua.toolbox,'@sdth');
     fullfile(ua.toolbox,'private');
     fullfile(ua.toolbox,'sdtdemos');
     fullfile(ua.toolbox,'@v_handle');
     fullfile(ua.toolbox,'openfem');
     fullfile(ua.toolbox,'openfem','@ofact');
  fullfile(ua.help,ua.hsubdir{1}); ...
  fullfile(ua.help,ua.hsubdir{1})}; alist={};
while ~isempty(st0)
  if exist(st0{1},'dir')==7
   cd(st0{1});st0=st0(2:end);
   ilist=dir('*.*');
   i1=[ilist.isdir];
   i2=find(i1==0);
   if ~isempty(i2)
     alist(end+[1:length(i2)],1)={ilist(i2).name}; %#ok<AGROW>
      alist(end+[-length(i2)+1:0],2)={pwd}; %#ok<AGROW>
   end
   i2=find(i1); ilist=ilist(i1); 
   i1=1:length(ilist); i1(strmatch('.',{ilist.name}))=0;i1=find(i1);
   for j1=i1(:)'
     st0{end+1}=fullfile(pwd,ilist(j1).name); %#ok<AGROW>
   end
  else; st0=st0(2:end);
  end
end
cd(pw0)

% obtain the installation list

try; 
   cd(fullfile(ua.toolbox,'private'));
   st2='MATLAB:lang:cannotClearExecutingFunction';st1=warning('query',st2);
   warning('off',st2);clear('functions');warning(st1.state,st2); %#ok<CLFUNC>
   eval('list=sdt_install_list;');
catch
  if     exist('sdt52_dislist','file'); list=sdt52_dislist;
  elseif exist('sdt51_dislist','file'); list=sdt51_dislist;
  elseif exist('sdt50_dislist','file'); list=sdt50_dislist;
  else
   error(['You must have an sdt_install_list.m file' ...
         ' in your sdt/private directory']);
  end
end
cd(pw0)

%% compare directory list
a=char(list{:,2});i1=find(a=='\');if ~isempty(i1); a(i1)='/';end
a=sortrows(a);a=a([find(any(diff(double(a)),2));size(a,1)],:);
b=char(alist{:,2});i1=find(b=='\');if ~isempty(i1); b(i1)='/';end
b=sortrows(b); b=b([find(any(diff(double(b)),2));size(b,1)],:);
i1=find(ua.toolbox=='\'); st1=ua.toolbox;if ~isempty(i1); st1(i1)='/';end
dlist={};
for j1=1:size(b,1)

 st4=deblank(b(j1,:)); i1=strmatch(st4,a,'exact');
 if isempty(i1)
   st4=deblank(strrep(st4,st1,'')); i1=strmatch(st4(2:end),a,'exact');
 end
 if ~isempty(strfind(st4,'pdf_doc/sdt')); i1=strmatch('pdf',a,'exact');end
 if ~isempty(strfind(st4,'help/toolbox/sdt')); i1=strmatch('help',a,'exact');end

 if ~isempty(strfind(st4,'CVS'))
 elseif isempty(i1) && (comstR(st(2:end),'sdtdev/@sdth')|| ...
    comstR(st(2:end),'sdtdev/@v_handle'))
  i1=strmatch(st4(9:end),a,'exact');
  dlist(end,1:2)={deblank(b(j1,:)) deblank(a(i1,:))};a(i1,:)=' ';  
 elseif isempty(i1)
  r3=regexp(st4,'/([^/]*)','tokens');r3=r3{1}{1};
  if ~ismember(r3,{'demo','idacq','dmap','test','tex','sdtdev'});
   un_message(sprintf('Additional directory : %s',st4(2:end)))
  end
 else  
  dlist{end+1,1}=deblank(b(j1,:)); %#ok<AGROW>
  dlist{end,2}=deblank(a(i1,:));a(i1,:)=' ';  
 end
end

% Deal with missing directories
i1=find(any(a~=' ',2));
if ~isempty(i1)
   st4=cellstr(a(i1,:));
   for j1=1:length(st4)
    if strcmp(st4{j1},'help') && ...
      exist(fullfile(ua.toolbox,'toolbox','sdt'),'dir')==7
       dlist(end+1,1:2)={fullfile(ua.droot,'toolbox','sdt'),'help'}; %#ok<AGROW>
    elseif strcmp(st4{j1},'pdf') && ...
      exist(fullfile(ua.toolbox,'pdf_doc','sdt'),'dir')==7
       dlist(end+1,1:2)={fullfile(ua.droot,'pdf_doc','sdt'),'pdf'}; %#ok<AGROW>
    elseif strcmp(st4{j1},'@sdth') && ...
      exist(fullfile(ua.toolbox,'sdtdev','@sdth'),'dir')==7
       dlist(end+1,1:2)={fullfile(ua.toolbox,'sdtdev','@sdth'),'@sdth'};%#ok<AGROW>
    elseif strcmp(st4{1},'6.0')
     st2={''};list(strcmp(list(:,2),'6.0'),2)=st2;
    else;   un_message(sprintf('Missing directory : %s\n',st4{:}));
    end
   end
end
alist(:,2)=strrep(alist(:,2),'\','/');
list(:,2)=strrep(list(:,2),'\','/');

%% File List checking, list is desired list
otherfile={};missingfile={};
for j1=1:size(dlist,1) % loop on expected dirs
 a=unique(alist(strcmp(alist(:,2),dlist{j1,1}),1));% alist Files in dlist{j1}
 b=unique(list(strcmp(list(:,2),dlist{j1,2}),1));% blist Files in dlist{j1}
 if ~ismember(dlist{j1,2},{'p','help','p/@v_handle'})
  r2=setdiff(a,b);r2=setdiff(r2,{'sdt_install_list.m'});
  r2(cellfun(@(x)any(x=='~'|any(x==35)),r2))=[];
  otherfile=[otherfile; ...
     cellfun(@(x)fullfile(dlist{j1,2},x),r2,'uni',0)]; %#ok<AGROW>
 end
 r2=setdiff(b,a);r2(cellfun(@isempty,r2))=[];
 if ~isempty(r2) % some files are missing
   r2(cellfun(@(x)exist(fullfile('sdtdev',x),'file')==2,r2))=[];
   r2(cellfun(@(x)exist(fullfile('sdtdev','@v_handle',x),'file')==2,r2))=[];
   missingfile=[missingfile;r2]; %#ok<AGROW>
 end
end

if ~isempty(otherfile)
 un_message(sprintf('\nUnexpected files\n'))
 for j1=1:length(otherfile); un_message(otherfile{j1}); end
end

if ~isempty(otherfile)
 un_message(sprintf('\nMissing files\n'));
 for j1=1:length(missingfile); un_message(missingfile{j1}); end
end
cd(ua.toolbox);

% PATHDEF file edit

try
if exist('pathdef','file')==2
  
  fid = fopen(which('pathdef'));file=fscanf(fid,'%c');fclose(fid);
  ind = find(file==10|file==13);

  % find how the line is built
  i1=strfind(file,'matlabroot,''');
  if isempty(i1); i1=strfind(file,'toolbox/matlab');   end
  if isempty(i1);  i1=strfind(file,'toolbox\matlab');  end
  i2=strfind(file,'sparfun');i1=i1(max(find(i1<i2)));
  st2=file(ind(max(find(ind<i1)))+1:ind(min(find(ind>i1))));
  if isempty(st2)
    st2=sprintf(['Sorry I don''t know how to edit your pathdef.m file\n' ...
     'Mail the contents of your pathdef.m file to support@sdtools.com']);
    un_message(st2);error(st2); %#ok<SPERR>
  end
  i2=strfind(st2,'sparfun'); st.start=st2(1:i2-8);
  st.dsep=st2(i2+7);st.fsep=st2(i2-8);

  % check if start is really the default toolbox
  st4=dbstack;st4=fileparts(st4(1).name);
  if isempty(st4); st4=pwd; end
  if isempty(strfind(st4,'toolbox'));
   st.start=['  ''' fileparts(st4) st.fsep];
  end
  st4=strrep(st4,fileparts(st4),'');
  if ~isempty(st4)&&any(st4(1)=='\/'); st4(1)='';end

  % see what needs to be done
  st.subdir={};
  for j3=1:length(ua.subdir)
   if exist(fullfile(ua.toolbox,ua.subdir{j3}),'dir') && ...
    ~any(ua.subdir{j3}=='@')
    st5=strrep(fullfile(st4,ua.subdir{j3}),'\','/');
    st5=strrep(st5,'/',st.fsep); st.subdir{end+1}=[st5 st.dsep];
   end
  end;
  st.insert='';i3=[];
  for j1=1:length(st.subdir)
   i2=strfind(file,st.subdir{j1});
   if isempty(i2)
     st.insert=[st.insert st.start st.subdir{j1} sprintf(''',...\n')];
     i3(j1)=0; %#ok<AGROW>
   else; i3(j1)=ind(max(find(ind<i2(1)))); %#ok<AGROW>
   end
  end

  if ~any(i3)
   i4=max(strfind(file,[st.start]));
   if ~isempty(i4)
    i3(end+1)=ind(max(find(ind<i4)));
   else
    un_message( ...
     ['''%s'' not found in current pathdef, expected insertion of \n\n',...
      '%s \nwas not performed'],st.start,st.insert);
    i3(:)=Inf;
   end
  end
  
  if any(i3==0)  % needs some modification
   % save old pathdef to other file
   fname = fullfile(matlabroot,'toolbox','local','pathdef.old');
   while exist(fname,'file')==2; fname(end)=char(fname(end)+1);end
   fprintf(1,'\n Saving pathdef.m to %s to allow safe editing\n',fname)
   [fid,err] = fopen(fname,'w');
   if ~isempty(err)
       error(['sdtcheck only edits the pathdef.m file ' ...
        'if you run MATLAB\nas a user who has write permission' ...
        ' to the $MATLAB/toolbox/local directory'])
   else; fprintf(fid,'%c',file);fclose(fid);
   end

   % editing the pathdef
   i1=[strfind(file,st.start) length(file)+101];
   i1=i1(min(find(diff(i1)>100)));i1=min(find(ind>i1))-1;
   i3=min(i3(i3~=0));i3(2)=ind(min(find(ind>i3+2)));
   while isempty(strfind(file(i3(1):i3(2)),st.dsep))
    i3=ind(max(find(ind<i3(1)-2))+[0 1]);
   end
   i3=i3(2)+[0 1];
   while any(file(i3(1))==[10 13]); i3(1)=i3(1)-1;end
   while any(file(i3(2))==[10 13]); i3(2)=i3(2)+1;end

   file = [file(1:i3(1)) sprintf('\n') st.insert file(i3(2):end)];

   % saving the new pathdef
   fname2=fullfile(matlabroot,'toolbox','local','pathdef.m');
   delete(fname2);[fid,err] = fopen(fname2,'w');
   if ~isempty(err)
       error('Sorry I deleted pathdef.m and cannot write a new one.')
   end
   fprintf(fid,'%c',file);i3=fclose(fid);
   if i3; error('Sorry I had problems closing pathdef.m'); end
   fprintf(1,'%s was edited to contain\n%s', which('pathdef'),st.insert)
   if isunix
     unix(sprintf('chmod a+r %s',which('pathdef')));
   end
  elseif all(isfinite(i3))
   un_message( ...
      sprintf('\nYour pathdef.m file includes proper SDT entries\n'));
  end
end
catch 
 un_message(lasterr); %#ok<LERR>
 un_message('Editing of pathdef.m failed');
end
try
    st1=sprintf(['You may always fix your path by adding the following to' ...
    ' your startup.m file\n\npw0=pwd;cd(''%s'');\nsdtcheck(''path'');\n' ...
    'cd(pw0);clear pw0;\n\n' ...
    ],ua.toolbox);
    disp(st1); if ~isempty(cf); un_message(st1);end
end

% documentation checks
sdtcheck('helps')

%% list mex platforms and check version
eval('i1=~comstr(''ismex'')|comstr~=current_comstr;','i1=1;');
if i1&&exist('comstr','file')==3
  try; i1=comstr; catch; i1=1; end
  un_message(sprintf( ...
  'warning: Incorrect version of comstr (%.4f instead of %.4f)', ...
    i1,current_comstr));
end
RO.mext={'comstr','sp_util','of_mk','spfmex','mkl_utils'};
RO.ini=cellfun(@(x)which(x),RO.mext,'uni',0);
i1=cellfun(@isempty,RO.ini);RO.mext(i1)=[];RO.ini(i1)=[];
try;sdtcheck('path');end
if ~isequal(cellfun(@(x)which(x),RO.mext,'uni',0),RO.ini)
   un_message(sprintf('mex order changed after sdtcheck(''path'')\n%s', ...
         ' this indicates a default path ordering problem'));
end

eval('i1=~sp_util(''ismex'')|sp_util~=current_sputil;','i1=1;');
if i1&&exist('sp_util','file')==3
  try; i1=sp_util; catch;i1=1; end
  un_message(sprintf( ...
  'warning: Incorrect version of sp_util (%.4f instead of %.4f)', ...
    i1,current_sputil));
end
rehash toolboxcache  % in case the user did something manually


cd(pw0)

% -----------------------------------------------------------------------
% -----------------------------------------------------------------------
% -----------------------------------------------------------------------
%% #Sdtkey : licensing utilities
% forward for sdtkey implement --------------------------------------
elseif comstR(Cam,'resize'); sdtkey('resize');
elseif comstR(Cam,'install'); sdtkey('install');
% com.mathworks.services.Prefs.setIntegerPref('JavaMemHeapMax',512)

% replace license key
%% #RlmLic : copy sdt.lic to prefdir -2
elseif comstR(Cam,'rlmlic')
  fname=fullfile(prefdir,'sdt.lic');
  if exist(fname,'file')
     fprintf('Keeping %s\n',fname);
  else
   f2=which('sdt.lic');
   if isempty(f2);error('No sdt.lic file found');end
   copyfile(f2,fname);
  end

elseif comstR(Cam,'rlmexp')
%% #RlmExp : check expire -2
 ti=timerfind('tag','rlm');
 if isempty(ti)
       ti=timer('TimerFcn',' ', ...
        'BusyMode','queue','ExecutionMode','singleShot', ...
        'TasksToExecute',1,'tag','rlm');
 end
 set(ti,'startdelay',2,'TimerFcn','try;sdtcheck(''rlmstatexp;'');end');
 start(ti);
 
elseif comstR(Cam,'rlmstatexp')
    
 RO.verSDT=sscanf(sdtkey('version'),'%s',1);
 if Cam(end)==';';checkRlmExpire(RO.verSDT,1);
 else;checkRlmExpire(RO.verSDT,0);
 end
 ti=timerfind('tag','rlm');if ~isempty(ti);stop(ti);delete(ti);end

elseif comstR(Cam,'rlmstat')
%% #RlmStat : see license status -2
 try;st1=sdtrlm('cvs');catch;st1='Loading sdtrlm fails';end
 try;st2=sdtkey('cvs');catch;st2='Loading sdtkey fails';end
 fprintf('%s\n\n%s %s\n%s %s\n\ntype %s\n\n', ...
     repmat('-',1,50),which('sdtrlm'),st1,which('sdtkey'),st2,sdtkey('licfile'))
 fprintf('<a href="matlab:type(''%s'');">Show licfile</a>\n',sdtkey('licfile'))
 fprintf('Nominal request is \n %s\n',sdtcheck('sitereq','TEST'))
 sdtkey('hostid')
 
 try;RO.verSDT=sscanf(sdtdef('version'),'%s',1);catch;RO.verSDT='7.4';end
 %%  detailed stat
 try; sdtrlm('stat');
 catch;
     pw0=pwd;
     cd(fileparts(which('sdtrlm')));
     try;copyfile(sdtkey('licfile'),tempdir);end
     sdtrlm('stat');
     cd(pw0);
 end
 i1=sdtrlm('checkout','base',RO.verSDT);
 if i1;
    try
     sdtrlm('init');
     if mislocked('sdtrlm');munlock('sdtrlm');clear('sdtrlm');end
     if mislocked('sdtkey');munlock('sdtkey');clear('sdtkey');end
    end
    i1=sdtrlm('checkout','base',RO.verSDT);
 end
 if i1;
   fprintf('A problem occured in checking out ''base'',''%s''\n %s\n', ...
       RO.verSDT,i1);
   type(sdtkey('licfile'));
 end
 checkRlmExpire(RO.verSDT,1);
 li=sdtrlm('products',[],RO.verSDT);li(cellfun(@isempty,li(:,1)),:)=[];
 fprintf('Available\n'); disp(li);
 fprintf('\n%s\n%s\n','Everything looks good',repmat('-',1,50));
 
elseif comstR(Cam,'rlmhostid')
%% #Rlm : check license status using RLMUTIL -2
 a=sdtrlm('hostid');if ~iscell(a);a=sdtrlm('hostid');end
 st2=regexprep(version,'( .*)','');st2(max(find(st2=='.',2)):end)='';
 if strcmpi(Cam,'rlmhostidmu')||strcmpi(Cam,'rlmhostid')
  out=sprintf('"%s#%s"_"%s"_"%s"_"%s"',a{8},strrep(a{4},'user=',''), ...
      a{1},a{2},a{3});
 elseif strcmpi(Cam,'rlmhostidcu')
  if ispc
   out=sprintf('"%s#%s"_"%s"_"%s"_"%s"',a{1},strrep(a{4},'user=',''), ...
      a{2},a{3},a{8});
  else
   out=sprintf('"%s#%s"_"%s"_"%s"_"%s"',a{3},strrep(a{4},'user=',''), ...
      a{1},a{2},a{8});
  end
 elseif strcmpi(Cam,'rlmhostidsa')&&ispc
   out=sprintf('"%s"_"%s#%s"_"%s"_"%s"',a{1},a{3},strrep(a{4},'user=',''), ...
      a{2},a{3},a{8});
     
 else % Old request
  out=sprintf('"%s"_"%s"_"%s"_"%s"_"%s"',a{[1 2 3 4 8]});
 end
 if nargout==0
  fprintf('Request info %s\n\n',out);clear out;
  if exist('sdtkey','file'); sdtkey('rlmid');end
 end
 
elseif comstR(Cam,'rlm')
%% #Rlm : check license status using RLMUTIL -2
 which('sdtrlm')
 sdtkey('licfile')
 pw0=pwd; 
 if ~isunix;sdtcheck('syspathadd;',fileparts(which('sdtrlm')));end
 if comstR(Cam,'rlmdiag')
   setenv('RLM_DIAGNOSTICS',fullfile(pwd,'rlmdiag.txt'));
   eval('sdtrlm(''unlock'');sdtkey(''has'',''base'');')
   eval('sdtrlm(''checkout'',''base'',''7.0'')');
 else
  try
   if isunix
    st1=fullfile(fileparts(which('sdtrlm')),'rlmutil');
    st1=sprintf('cd "%s";%s rlmstat -a -i sdt',fileparts(sdtkey('licfile')),st1);
    disp(st1);system(st1);
   else
    system(sprintf('rlmutil rlmstat -a -i sdt -c %s',sdtkey('licfile')));
    %system('rlmutil rlmstat -a -i sdt');
   end
  end
  RO.verSDT=sscanf(sdtkey('version'),'%s',1);
  checkRlmExpire(RO.verSDT,1);
 end
 cd(pw0);
 
elseif comstR(Cam,'newlic')

 st=sdtkey('newlic'); disp(st);
elseif comstR(Cam,'mkdir') 
 out = safe_mkdir(varargin{2});
elseif comstR(Cam,'set')
 sdtkey(CAM);

% -----------------------------------------------------------------------
% display message
elseif comstR(Cam,'message');
   un_message(varargin{2});
elseif comstR(Cam,'replacekey')    
 ReplaceKey(varargin{2:end});


%% #version ---------------------------------------------------------------
elseif comstR(Cam,'version')
 out=sdt_version;out=out(9:end);
elseif comstR(Cam,'favorite')
%% #favorite
fc = com.mathworks.mlwidgets.favoritecommands.FavoriteCommands.getInstance(); %#ok<*JAPIMATHWORKS> 
r1 = com.mathworks.mlwidgets.favoritecommands.FavoriteCommandProperties();
r1.setLabel('Open taglist of function');
r1.setCode('sdtweb _taglist');
r1.setName('xxx');
r1.setIsOnQuickToolBar(true)
% add the command to the favorite commands (the category is automatically created if it doesn't exist)
fc.addCommand(r1)

%% #helps ---------------------------------------------------------------
elseif comstR(Cam,'helps')
 i1=version;Rel=str2double(i1(1:3));
 if i1>=7.4;
 end

 st1=fullfile(docroot,'r12doctoc.xml'); Rel=12;
 if strncmp(version,'7',1)||strncmp(version,'8',1); Rel=14;
 elseif ~exist(st1,'file'); st1=fullfile(docroot,'mwdoctoc.xml'); Rel=13;
 end
 if Rel>=7.4
  % build search database if possible
  st1=sprintf('builddocsearchdb(''%s'')', ...
   fullfile(fileparts(which('sdtcheck')),'help'));
  sd_pref('set','SDT','Browser','-helpbrowser');
  fprintf('Building help search with \n%s\n',st1);
  warning('Off','MATLAB:doc:DocNotInstalled')
  try;eval(st1);end
  warning('On','MATLAB:doc:DocNotInstalled')
  if ~exist(fullfile(fileparts(which('sdtcheck')),'help','helpsearch'),'dir')||...
   ~exist(fullfile(fileparts(which('sdtcheck')),'help','helpsearch','segments'),'file')
   sdtw('_nb','Doc search build failed')
  end

 elseif Rel>7  % Edit the info.xml for R14
  
  if exist(fullfile(ua.toolbox,'help'),'dir'); st=fullfile(ua.toolbox,'help');
  else; st=fullfile(ua.help,ua.hsubdir{1});
  end
  st=strrep(st,'\','/');st1=docroot;st1=strrep(st1,'\','/');
  if ~isempty(st1); st=strrep(st,st1,'$docroot');end
  ReplaceKey(fullfile(ua.toolbox,'info.xml'), ...
   fullfile(tempdir,'info_sdt.xml'),'help_location',st);
  
 else % Edit the doctoc.xml for R12 and R13
  add_item(st1,fullfile(tempdir,'r12doctoc.xml'), ...
   'toolbox/xpc/xpctoc.xml', ...
   [' <subtoc location="toolbox/sdt/sdttoc.xml" ' ...
   'product="Structural Dynamics Toolbox"></subtoc>'])
  
  st1=fullfile(docroot,'r12docindex.xml');
  if ~exist(st1,'file'); st1=fullfile(docroot,'mwdocindex.xml');end
  
  add_item(st1, fullfile(tempdir,'r12docindex.xml'), ...
   'toolbox/xpc/xpcindex.xml', ...
   [' <subindex target="toolbox/sdt/sdtindex.xml" ' ...
   'product="Structural Dynamics Toolbox"></subindex>'])
  
  try
   st1=which('infor12.xml','all');
   st2=fileparts(which('sdtcheck'));
   if Rel==12 && ~isempty(st1) && strncmp(st1,st2,length(st2))
    st2=sprintf(['copyfile(fullfile(''%s'',''infor12.xml''),' ...
     'fullfile(''%s'',''info.xml''))'],st2,st2);
    if isempty(strfind(st2,'sdt.cur')); eval(st2);fprintf('%s %% Done\n',st2);
    else
     fprintf('For proper integration into Matlab R12 run\n')
     fprintf('%s\n',st2);
    end
   end
  end
 end % Edit the info.xml

 
% -----------------------------------------------------------------------
%% #path set MATLAB path, does rehash if contains 'toolbox'
elseif comstR(Cam,'path'); [CAM,Cam]=comstR(CAM,5);
if comstR(pwd, fileparts(which('sdtcheck'))) && ~isempty(Cam)
 error('You should not be in SDT home directory'); 
end
RunOpt.pw0=pwd;
st=which('sdtroot');
if isempty(st); RunOpt.wd=pwd;else;RunOpt.wd=fileparts(st);end
% First clean the path #pathnone
% make sure we clear femesh if openfem was loaded as SDT init kills it !
st1=which('feplot','-all');
if any(~cellfun(@isempty,strfind(st1,fullfile('sdt3','feplot'))));
 disp('femesh cleared');clear femesh;
end
j1=1;
st={'hexa8','feplot','comstr','sp_util','spfmex', ...
    'demo_fe','nas2up','prospadd','of_mk','of_time',...
    'miss','missread','miss_io_file','t_contact','mass_hyper', ...
    'feplotj','id_acq','t_stress'};
list={};
while j1<=length(st);
  st1=which(st{j1},'-all');
  wd='';if j1==1&&~isempty(st1);wd=fileparts(fileparts(st1{1}));end;
  if strcmp(st{j1},'nas2up')&&~isempty(st1);
   wd=fullfile(fileparts(st1{1}),'..');
  end
  if ~isempty(wd)% other standard possibly non .m file directories
    if ~exist('sdtkey','file')
       st2={'.','7.5','sdtdev'};
       for j2=1:length(st2)
        if exist(fullfile(wd,st2{j2},'sdtkey.p'),'file');st2=st2{j2};break
        elseif exist(fullfile(wd,st2{j2},'sdtkey.m'),'file');st2=st2{j2};break
        end
       end
       pw0=pwd;cd(fullfile(wd,st2));r2=feval('sdtkey','disdirlist');cd(pw0);
    %elseif [100 1]*sscanf(version,'%i.%i')<801&&exist('sdtrlm','file')
    %  rmpath(fileparts(which('sdtrlm')));r2=feval('sdtkey','disdirlist');
    else
        r2=feval('sdtkey','disdirlist');
    end
    st2=r2.subdir;st2=[st2(:);{'7.8'}];
    for j2=1:length(st2)
     if exist(fullfile(wd,st2{j2}),'dir');list{end+1}=fullfile(wd,st2{j2});end %#ok<AGROW>
    end
  end
  for j2=1:length(st1);
   wd=fileparts(st1{j2});
   if ~isempty(wd)&&~isequal(wd,pwd);
    if strncmp(wd,'c:\balmes\matlab',16);error('DevError');end
    try; list{end+1}=wd; end %#ok<AGROW>
   end
  end
  j1=j1+1;
end
list=unique(list);
if ~isempty(list);
    l1=list;st2=path;i1=1:length(l1); 
    for j1=1:length(l1);
        if isempty(strfind(st2,l1{j1}));i1(j1)=0;end
    end
    if ~isempty(find(i1)); rmpath(list{find(i1)}); end
end
    
if comstR(Cam,'none'); cd(RunOpt.pw0);return; end

% then try to do something
pw0=pwd;

% allow path specification in argument
if isempty(CAM) && nargin==2; CAM=varargin{2};end
if ~isempty(CAM)&&exist(CAM,'dir'); wd=CAM; 
else; wd=fileparts(which('sdtcheck'));
end
if ~isempty(strfind(wd,'patch'))
 wd=wd(1:end-6);
end
if any(exist('sdtkey','file')==[2 6])
 if isempty(wd); ua=sdtkey('disdirlist');
 else; ua=sdtkey('disdirlist',['-dir' wd]);
 end
elseif exist(fullfile(wd,'sdtdev'),'dir')
 addpath(fullfile(wd,'sdtdev'),'-end');
 if isempty(wd); ua=sdtkey('disdirlist');
 else; ua=sdtkey('disdirlist',['-dir' wd]);
 end
elseif exist(fullfile(RunOpt.wd,'sdtkey.m'),'file')
 addpath(RunOpt.wd,'-end');cd(fileparts(RunOpt.wd));ua=sdtkey('disdirlist');
elseif exist(fullfile(RunOpt.wd,'sdtkey.p'),'file')
    cd(RunOpt.wd);addpath(RunOpt.wd,'-end');ua=sdtkey('disdirlist');
else
 error('You must have a copy of sdtkey.p in the SDT directory or specify a target');
end
if isempty(wd);wd=pwd; end
if ~isfield(ua,'subdir'); ua=sdtkey('disdirlist',wd);end
% remove any sdt entry from path
st = path; i1=strfind(st,[filesep 'sdt']);
i2 = [0 find(st==pathsep) length(st)+1];
for j1=1:length(i1)
  st1=st(i2(max(find(i2<i1(j1))))+1:i2(min(find(i2>i1(j1))))-1); 
  if ~isempty(strfind(path,st1)); rmpath(st1); end
end

% add patch directory structure if needed
if isempty(wd); wd=ua.toolbox;end
if exist(fullfile(wd,'patch'),'dir')
 wd0=wd;wd=fullfile(wd,'patch');
 for j1=1:length(ua.subdir)
   st1=fullfile(wd,ua.subdir{j1});
   if isempty(ua.subdir{j1});   addpath(wd,'-end');
   elseif any(ua.subdir{j1}=='@') 
   elseif exist(st1,'dir'); addpath(st1,'-end');
   end
 end
 wd=wd0;
end

% add directories
RO.Rehash=0;
for j1=1:length(ua.subdir)
 if isempty(ua.subdir{j1});addpath(wd,'-end');
 elseif any(ua.subdir{j1}=='@') 
 else 
   st1=fullfile(wd,ua.subdir{j1});
   if ~isempty(strfind(st1,'toolbox'));RO.Rehash=1;end
   if exist(st1,'dir'); 
       if exist(fullfile(st1,['sdtrlm.' mexext]),'file')
        if mislocked('sdtrlm');munlock('sdtrlm');clear('sdtrlm');end
        if mislocked('sdtkey');munlock('sdtkey');clear('sdtkey');end
       end
       addpath(st1,'-end');
   end
 end
end
cd(pw0);%path
if RO.Rehash;rehash('toolboxreset');end

% handle python
if isunix
 try; 
  %r1=textscan(getenv('LD_LIBRARY_PATH'),'%s','delimiter',':');
  %fprintf('LD_LIBRARY_PATH:\n%s',sprintf('%s\n',r1{1}{:}));
  sdtcheck pyenv
 catch; sdtw('_nb','Problem with python environment, see sdtchek(''pyenv'')')
 end
end
% Library paths for DLL
%% #PathMexJavaCheck -2
sdtcheck('syspathmex');
if ~exist('sd','file')&&~exist('o:/sdtdata','dir');
   sdtcheck('PatchJavaPathSet;');
end

%% #Pyenv: python environment setup check
elseif comstR(Cam,'pyenv'); [CAM,Cam]=comstr(CAM,6);
 v1=sdtdef('verm');
 [i1,pe]=sdtdef('in','python'); pe0=sdth.fileutil('cffile',pe);

 if v1<804; error('python is not supported before 804-R2014b'); end
 if ~i1||~exist(pe,'file')||isunix
  if isunix % check desired version
   r1=getenv('LD_LIBRARY_PATH');
   if ~isempty(r1)
    r1=textscan(r1,'%s','delimiter',pathsep); r1=r1{1};
    i2=contains(r1,'python');
    %i3=contains(r1,matlabroot);
    if any(i2) % set version to the specified one
     %if any(i2&~i3); i2=i2&~i3; end
     stpy=r1{find(i2,1,'first')};
     pe=fullfile(stpy,'python');
    else
     sdtw('_nb',['You must point to your python-scipy libraries '...
      'in LD_LIBRARY_PATH prior to starting MATLAB.']);
    end
   else; % warn for problems
    sdtw('_nb',['You must point to your python-scipy libraries '...
     'in LD_LIBRARY_PATH prior to starting MATLAB']);
   end
   %   else % for ispc
   %    % MATLAB loads what it finds in getenv('PATH')
   %    % gv: assume it resolved needed version by itself, report to SDTools if not
   %    % if python is not in path, user should set it up in sdtdef directly
   %    %   so as not to add uneeded version handling complexity here
   %    r1=getenv('PATH');
   %    r1=textscan(r1,'%s','delimiter',pathsep); r1=r1{1};
   %    i2=contains(r1,'Python');
   %    if any(i2)
   %     stpy=r1{find(i2,1,'first')};
   %     pe=fullfile(stpy,'python');
   %    else
   %     sdtw('_nb','No Python intallation found in Windows PATH')
   %    end
  end % linux/pc path handling
  if isempty(pe) % not unix or not found
   if v1>906;    pe=pyenv; pe=pe.Executable; else; [u1,pe]=pyversion; end
  end
  pe=sdth.fileutil('cffile',pe);
  if ~isequal(pe0,pe)
   fprintf('\nUpdating python path preference to %s\n',pe)
   sdtdef('python -setpref',pe);
  end
 end % lib check
 err=[]; pe2=''; ve2=[];
 if v1>906
  try; pe1=pyenv('Version',pe); ve1=char(pe1.Version); pe1=char(pe1.Executable);
   % error even if same file in some versions
  catch err;  pe2=pyenv; ve2=char(pe2.Version); pe2=char(pe2.Executable);
  end
 else
  try; pyversion(pe), [ve1,pe1]=pyversion;
  catch err; [ve2,pe2]=pyversion;
  end
 end
 if ~isempty(pe2)&&~isempty(err); vok=0; % failed call
  % in some versions it fails even if the called path is identical to the current one
  if ~isequal(sdth.fileutil('cffile',pe),sdth.fileutil('cffile',pe2))
    rethrow(err)
  else; pe1=pe2; ve1=ve2;
  end
 else; vok=1;
 end
 if vok % then carry on with specific setup
  % define PYTHONPATH to let python find SDT .py files
  r1=getenv('PYTHONPATH');
  st1=sdth.fileutil('cffile',fileparts(which('sdtslave.py')));
  if ~isempty(r1);
   r1=textscan(r1,'%s','delimiter',pathsep); r1=r1{1};
   for j1=1:length(r1); r1{j1}=sdth.fileutil('cffile',r1{j1}); end
   r1=[st1;r1]; [u1,i1]=unique(r1); r1=r1(i1);
  else; r1={st1};
  end
  stpp=sprintf(sprintf('%%s%s',pathsep),r1{:});
  setenv('PYTHONPATH',stpp);
  if isunix % run python w/ its own libs to avoid mkl seg with matlab
   % keep eval to avoid early loading by matlab
   eval('py.sys.setdlopenflags(int32(10));') %#ok<EVLCS>
  else % if ispc: add syspathlib
   stpy=fileparts(pe1);
   stlib = {stpy
    fullfile(stpy, 'Library', 'mingw-w64', 'bin')
    fullfile(stpy, 'Library', 'usr', 'bin')
    fullfile(stpy, 'Library', 'bin')
    fullfile(stpy, 'Scripts')    };
   sdtcheck('syspathadd -begin',stlib);
  end
 end % vok
 fprintf(1,'Python setup using %s\n',pe1)
 if nargout>0; out=pe1;
  if nargout>1
   % post version number, robust and forecast subver handling in the future
   i1=[0 strfind(ve1,'.') length(ve1)+1]; out1=0;
   for j1=1:length(i1)-1
    out1=out1+10^(2*(length(i1)-j1)-2)*str2double(ve1(i1(j1)+1:i1(j1+1)-1));
   end
  end
 end

%% #syspath edit syspath ---------------------------------  
elseif comstR(Cam,'syspath'); [CAM,Cam]=comstR(CAM,8); 
    
%% #SyspathAdd sdtcheck('syspathadd-begin',wd) - - -
if comstR(Cam,'add')||isempty(Cam);
 if isunix
  st=getenv('LD_LIBRARY_PATH');
  if isempty(st);st1='';else; st1=textscan(st,'%s','whitespace',':');st1=st1{1};end
  carg=2;
  if carg<=nargin % Dynamic setting of LD_LIBRARY_PATH does not work
   wd=varargin{carg};carg=carg+1;
   if ~exist(wd,'dir');error('%s is not a directory',wd); end
   st3=sprintf('Start MATLAB in bash with\n %s', ...
      sprintf('export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%s;matlab',wd));
   if ~isempty(strfind(wd,'mklserv/64')) 
    st2=st1(~cellfun('isempty',regexp(st1,'mklserv/64')));
    if ~isempty(st2); b=dir(st2{1}); a=dir(wd);
      if isequal(a,b);
       if Cam(end)~=';';fprintf('\nLD_LIBRARY_PATH %s seems correct %s\n', ...
              st2{1},'nothing needed');
          fprintf(st3);
       end
       return
      end
    end
   end
   if ismember(wd,st1)
    if Cam(end)~=';';fprintf('\n%s already in LD_LIBRARY_PATH\n',wd);end
   else; error(st3);
   end
   if ~isempty(strfind(Cam,'begin'));
     st1(strcmpi(wd,st1))=[]; st1=[{wd} st1(:)'];
   elseif ~any(strcmpi(st1,wd)); st1{end+1}=wd; % Append at end 
   end
  end
  fprintf('%s\n',st1{:});
  if nargin>1
    st2=sprintf('%s:',st1{:});st2(end)='';
    %setenv('LD_LIBRARY_PATH',st2) % dynamic setting does not work
  end
 else
  %% windows
  [i1,st]=system('path'); 
  % st=strrep(st,'C:\cygwin64C:','C:'); setenv('PATH',st(6:end));
  st1=textscan(st,'%s','whitespace',';');st1=st1{1};
  st1{1}=strrep(st1{1},'PATH=','');
  carg=2;
  if carg<=nargin
   wd=varargin{carg};carg=carg+1;
   if ~iscell(wd); wd={wd};end
   i1=cellfun(@(x)exist(x,'dir'),wd);
   wd(i1==0)=[]; if isempty(wd); return;end
   wd=cellfun(@(x)fullfile(x),wd(:),'uni',0);
   if contains(Cam,'begin') %~isempty(strfind(Cam,'begin'));
     st1(ismember(st1,wd))=[]; st1=[wd(:)' st1(:)'];
   elseif contains(Cam,'remove') %~isempty(strfind(Cam,'begin'));
   st1(ismember(lower(st1),lower(wd)))=[];
   else
     i1=strcmpi(st1,wd);st1(i1)=[]; 
     st1=[st1(:)' wd(:)' ]; % Append at end 
   end
  end
  % avoid repetitions
  try; [u1,i1]=unique(lower(st1),'stable'); st1=st1(i1); end
  if isempty(Cam)||Cam(end)~=';';fprintf('%s\n',st1{:});end
  if nargin>1
    st2=sprintf('%s;',st1{:});%st2(end)='';
    setenv('PATH',st2);
  end
 end 
elseif comstR(Cam,'mex')
 %% #SyspathMex : check validity of MSVC libraries
 RO.li={'comstr','of_mk','sp_util','spfmex','mkl_utils','mklserv_client', ...
     'sdtrlm'};
 RO.needSys=0;
 for j1=1:length(RO.li)
  if exist(RO.li{j1},'file')==3
    try;feval(RO.li{j1},'cvs');
    catch; RO.needSys=1; disp(RO.li{j1})
    end
  end
 end
 if ~RO.needSys
 elseif ispc
  sdtcheck('syspathadd',fullfile(fileparts(which('sdtcheck')),'sys'))   
 else
  error('Please report system path problem to SDTools');
 end
 
elseif comstR(Cam,'lib')
 %% #SyspathLib : libraries are stored an linked in $SDT/mklserv/64 or 32
 % When using a directory, you can generate links 
 %  unix : ln -s Otherloc/*.so* $SDT/mklserv/64/.
 %  windows as administrator : 
 %  cd $SDT/mklserv/64/.; mklink  mkl_rt.dll c:\other_loc\mkl_rt.dll
 wd1=sdtcheck('SDTRootDir');
 %sdtcheck('syspathadd',fullfile(wd1,'7.5'));
 %[un1,un1,ext]=fileparts(which('sp_util'));
 %st=''; if length(ext)==7; st=ext(end-1:end); end
 ext=mexext;st=ext(end-1:end);
 if isempty(st)
 elseif exist(fullfile(wd1,'mklserv',st),'dir')
  sdtcheck(['syspathadd' Cam(end)],fullfile(wd1,'mklserv',st));
 else;
  sdtweb('_link','sdtcheck(''PatchMkl'')','Run patching script')
 end
elseif comstR(Cam,'rem')
%% #SyspathRem : remove directory from system path
 if isunix; error('SyspathRem not implemented');end
 [i1,st1]=system('path');wd=varargin{2};
 i2=strfind(st1,wd);
 if ~isempty(i2); 
    if strncmpi(st1(i2+length(wd):end),';',1);st1(i2+(0:length(wd)+1))='';
    else; st1(i2+(1:length(wd)))='';
    end
    setenv('PATH',st1);
 end
else; error('SysPath%s',CAM);
end
% ---------------------------------------------------------------------------
% ---------------------------------------------------------------------------
%% #Depends  dependency testing  ------------------------------
% walker call on windows
%   SDT expects to find depends.exe in $SDT/7.5
% ldd on linux
%  sdtcheck('depends mkl_utils')
elseif comstR(Cam,'depends'); [CAM,Cam]=comstR(CAM,8); 

 if comstR(Cam,'tbb')   
  %% #DependsTbb sdtcheck('dependstbbCheck');
  % maxNumCompThreads(1) % Avoid calls to tbb
  if nargin>=2;tname=varargin{2};carg=3;
  elseif comstR(Cam,'tbbcheck')
  
   [RO.ver,RO.file]=sdtcheck('dependstbb');
   [st1,fname,ext]=fileparts(RO.file);
   [RO.v2,RO.f2]=sdtcheck('dependstbb',fullfile(s_libpath,[fname ext]));
   if str2double(RO.v2{1,2})>str2double(RO.ver{1,2})
    sdtw('_nb', ...
    '%s v%s > %s v%s \n   consider doing (as Administrator)\n cp "%s" "%s"', ...
     RO.f2,RO.v2{1,2},RO.file,RO.ver{1,2},RO.f2,RO.file)
   else;fprintf('Using %s v%s\n',RO.file,RO.ver{1,2})
   end
   return
  else
   wd=getenv('MATLAB_ARCH');if isempty(wd);wd=getenv('ARCH');end
   wd=fullfile(matlabroot,'bin',wd);
   if isunix;
       tname=dir(fullfile(wd,'libtbb.so*'));tname=fullfile(wd,tname.name);
   else; tname=fullfile(wd,'tbb.dll');
   end
  end
  if exist(tname,'file')
     fid=fopen(tname,'r');st=fread(fid,'char=>char')';fclose(fid);
     st1={'TBB: VERSION';'TBB: BUILD_DATE'};
     for j1=1:size(st1,1)
      st(1:strfind(st,st1{j1,1})+length(st1{j1,1}))='';i2=strfind(st,'TBB');
      st1{j1,2}=comstR(st(1:i2(1)-1),1);st1{j1,2}(st1{j1,2}<32)='';
     end
  else; st1='Not found';
  end
  if nargout>0; out1=tname; out=st1; else; fprintf('%s\n',tname);disp(st1); end
  
 elseif comstR(Cam,'msvc')||nargin>1
 %% sdtcheck #dependsmsvc
   if nargin==1;
     st1={'comstr','sp_util','of_mk','spfmex','of_time', ...
         'mklserv_client','mkl_utils'};
     for j1=1:length(st1);
         if ~exist(st1{j1},'file'); continue;end
         sdtcheck('DependsMsvc',st1{j1});
     end
     return;
   else;fname=varargin{2};%carg=carg+1;
   end
   [st1,st2,st3]=fileparts(fname);
   if isempty(st3);fname=which(fname);end
   fid=fopen(fname);st=fread(fid,'char=>char')';fclose(fid);
   i1=strfind(lower(st),'msvc');
   if isempty(i1);i1=strfind(lower(st),'vcrun');end;out=cell(length(i1),1);
   for j1=1:length(i1)
    st1=st(i1(j1)+(0:20));st1(st1<32|st1>128)='';
    st1=regexprep(lower(st1),'\.dll.*','');
    out{j1}=sprintf('%s -> %s',fname,st1);
   end
   i1=strfind(lower(st),'$revision'); out1=cell(length(i1),1);
   for j1=1:length(i1)
    st1=st(i1(j1)+(0:50));st1(find(st1<32,1,'first'):end)='';
    out1{j1}=st1;
   end
   
   RA=struct('root','https://www.microsoft.com/en-us/download/details.aspx?id=', ...
       'li',{{'msvcp100','14632';'msvcr100','14632';'msvcr80','18471';
       'vcruntime140','48145';'msvcr120','40784'
       }});
   
   if nargout==0; 
       for j1=1:size(out,1); 
        st1=regexprep(out{j1},'(.*>) ','');
        i2=find(ismember(st1,RA.li(:,1)));
        if ~isempty(i2)
            fprintf('%s : from %s%s\n',out{j1},RA.root,RA.li{i2,2})
        else;fprintf('%s\n',out{j1})
        end
       end
     %fprintf('\n https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads\n')
     clear out
       if ~isempty(out1);fprintf('%s\n',out1{:});clear out1;end
   end
 elseif comstR(Cam,'unixmkl')   
  %% #DependsUnixMKL sdtcheck('dependsUnixMKL');
  % readelf  -h ./libtbb.so.2 % reads versions of unix libraries
  if ~isunix; error('Command only working for unix');end
 if exist('t_mkl','file');r1=t_mkl('tbbpath');else;r1=[];end
 
 wd=fullfile(sdtcheck('SDTRootDir'),'mklserv','64');
 st1=textscan(getenv('LD_LIBRARY_PATH'),'%s','whitespace',':');
 st1=st1{1};disp(st1)
 sdtweb('_link',sprintf('!ldd %s ',which('mkl_utils')))
 [a,st1]=system(sprintf('ldd %s | grep "not found"',which('mkl_utils')));
 
 if ~isempty(st1)
   if isempty(r1); disp(st1); return; end
   st1=textscan(st1,'%s');st1=st1{1};st1(ismember(st1,{'=>','not','found'}))=[];
   for j1=1:length(st1);
    if isempty(r1); 
    elseif ~isempty(strfind(st1{j1},'tbb'));st2=fullfile(r1.TbbLib,st1{j1});
    else;st2=fullfile(r1.MklLib,st1{j1});
    end
    %fprintf('ln -s %s .\n',st2); 
    fprintf('!cp %s .\n',st2); 
   end
  fprintf('!cp /opt/intel/Compiler/11.0/083/lib/intel64/libiomp5.so .')
  comgui('\n\ncd o:/distrib/lib');wd=pwd;a=dir('*.so*');
 elseif ~isempty(r1) % Copy from ref location
   [a,st1]=system(sprintf('ldd %s | grep "tbb"',which('mkl_utils')));
   st1=textscan(st1,'%s');st1=st1{1};st1(ismember(st1,{'=>','not','found'}))=[];
   st1=regexprep(st1,'\(.*\)','');
   st1=st1(~strncmpi(st1,'/',1)&~cellfun('isempty',st1));
   st1=st1';st1(2,:)={r1.TbbLib};st1(3,:)={wd};st1=st1([2 1 3],:);
    fprintf('!cp %s/%s %s/.\n',st1{:}); 
    
   [a,st1]=system(sprintf('ldd %s | grep "mkl"',which('mkl_utils')));
   st1=textscan(st1,'%s');st1=st1{1};st1(ismember(st1,{'=>','not','found'}))=[];
   st1=regexprep(st1,'\(.*\)','');
   st1=st1(~strncmpi(st1,'/',1)&~cellfun('isempty',st1));
   st1=st1';st1(2,:)={r1.MklLib};st1(3,:)={wd};st1=st1([2 1 3],:);
   fprintf('!cp %s/%s %s/.\n',st1{:}); 
 else; fprintf('mkl_utils is properly linked');
 end
 %fprintf('cd %s\n',fullfile(matlabroot,'bin',getenv('ARCH')))
 %for j1=1:length(a);fprintf('ln -s %s .\n',fullfile(wd,a(j1).name));end

 else
 %%
 if isempty(CAM);CAM='mkl_utils';end
if ~isunix
 % Windows check of dependencies install Dependency Walker in SDT/7.5
 RO.tname=nas2up('tempnamedepend.txt');
 RO.exe=fullfile(sdtcheck('SDTRootDir'),'7.5','depends.exe');
 st2=which(CAM);if isempty(st2);st2=CAM;end
 RO.Cam=sprintf('"%s" /ot:"%s" /C "%s"',RO.exe,RO.tname, ...
     strrep(st2,'/','\'));
 disp(RO.Cam);
 [i0,st0]=system(RO.Cam); %eval(RO.Cam);
 fid=fopen(RO.tname,'r');st=fread(fid,'char=>char')';fclose(fid);
 ind=find(st==10);
 RO.tag={'mkl_rt.dll';'error opening'};
 RO.cell=cell(1,length(RO.tag));
 for j1=1:length(RO.tag)
   RO.cell{j1}=strfind(lower(st),RO.tag{j1});
 end
 i1=horzcat(RO.cell{:});
 st1=cell(length(i1),1);
 for j1=1:length(i1); 
     i2=find(ind<i1(j1),1,'last');
     st2=deblank(st(ind(i2)+1:ind(i2+1)-1));
     for j2=1:length(RO.tag)
      i3=strfind(lower(st2),RO.tag{j2}); if isempty(i3);continue;end
      st2(i3+length(RO.tag{j2}):end)='';
     end
     st1{j1}=st2;
 end
 fprintf('%s\n',st1{:})
 sdtweb('_link',sprintf('open %s',RO.tname));
 disp(RO.Cam)
else
 [i1,st]=system(sprintf('ldd "%s"',which(CAM)));
 disp(st)
end
if nargout>0;out=RO;end
end
if 1==2; % Check version of DLL
  fid=fopen('mkl_rt.dll','r');st=fread(fid,'char=>char')';fclose(fid);
  if isempty(strfind(st,'_lp64'))&&~isempty(strfind(mexext,'64'))
     error('32 bit version on 64 machine');
  end
  
end
 if 1==2 % Manual editing of path, see t_mkl('winpath')
  [i1,st]=system('path'); 
  st1=textscan(st,'%s','whitespace',';');st1=st1{1};
  st1(~cellfun('isempty',regexp(st1,'composer')))=[];
  st1(~cellfun('isempty',regexp(st1,'Intel.Shared Libraries')))=[];
  st1{1}=strrep(st1{1},'PATH=','');
  st1{end+1}='O:\distrib\lib\mklserv\64';
  st2=sprintf('%s;',st1{:});st2(end)='';
  setenv('PATH',st2);!path
  sdtcheck depends
 end
%% End

%% #Patch utilities  sdtcheck('patch')
elseif comstR(Cam,'patch'); [CAM,Cam]=comstR(CAM,6); 

if nargin>1&&isstruct(varargin{2});RO=varargin{2};
else; RO=struct('getURL',0,'wd','');
end
 i1=strfind(Cam,'-geturl');
 if ~isempty(i1); RO.getURL=1; CAM=CAM([1:i1-1 i1+6:end]); Cam=lower(CAM);
 else;
  i1=strfind(Cam,'-wd');
  if ~isempty(i1)
   try
    i2=strfind(CAM,'"'); i3=i2(find(i2>i1,2,'first'));
    RO.wd=CAM(i3(1)+1:i3(2)-1); CAM=CAM([1:i1-1 i3(2)+1:end]); Cam=lower(CAM);
   catch; sdtw('_nb','Command -wd was detected but input was wrong')
   end
  end
 end
if comstR(Cam,'upgrade');[CAM,Cam]=comstR(CAM,8); 
%% #patchupgrade : download an SDT update -2
%     sdtcheck 'patchupgrade' % For latest beta
%     sdtcheck 'patchupgrade ../download/daily/sdtdaily_dis.p' 'target' % For daily

if isempty(Cam)%Update SDT
 r1=struct('fname','sdtcur_dis.p','in','beta/sdtcur.zip','back',2,'reset',1);
elseif comstr(Cam,'contact')
 r1=struct('fname','beta/contact_patch_dis.p','back',2,'reset',1);
elseif ~isempty(strfind(Cam,'_dis.p'))
 r1=struct('fname',CAM,'back',2,'reset',1);
end
r1.pw0=fileparts(which('sdtcheck'));
fclose('all'); % Make sure file can be updated
if nargin==2; target=varargin{2}; 
 %% attempt at displaying extract command from start
 if ~exist(target,'dir');error('''%s'' does not exist',target);end
 st1=['extract -patch -d ' target];
 fprintf('\nsdtkey(''%s'',''%s'',''%s'')\n',st1,sdtkey('licfile'),r1.fname);
end

try; r1.licfile=sdtkey('licfile');end
RO_patchfile=[]; r1.Err=[];
if ~exist(sdtdef('tempdir'),'dir')
   error('Please set sdtdef(''tempdir'',''my_dir'') to a valid directory')
end
try; f1=sdtcheck('PatchFile',r1); %
     RO=RO_patchfile;cd(r1.pw0);
catch
 RO=RO_patchfile;
 if isfield(RO,'ErrWarn'); warning(RO.ErrWarn);end % Captured error
 f1=RO.LocalName;
end

[wd,f2,ext]=fileparts(f1); cd(wd);
if ~strcmp(ext,'.p');f2=fullfile(pwd,'sdtcur_dis.p');
else; f2=fullfile(wd,[f2 ext]);
end
try;if isfield(RO,'licfile');copyfile(RO.licfile,wd);end;end
cd(r1.pw0); % extract from directory of sdtcheck 

if nargin==2; target=varargin{2};
    if ~exist(target,'dir');error('''%s'' does not exist',target);end
elseif ~strcmp(RO.pw0,wd);target=RO.pw0; % Localization of starting sdtcheck 
else; target=fileparts(which('feplot'));
end

% sdtkey('extract -d user_target',sdtkey('licfile'),'source_dis.p')
st1=['extract -patch -d ' target];
fprintf('\nsdtkey(''%s'',''%s'',''%s'')\n',st1,sdtkey('licfile'),f2);
sdtkey(st1,sdtkey('licfile'),f2)

if ~exist('mklserv_client','file');
 sdtweb('_link','sdtcheck(''PatchMkl'');')
 sdtweb('_link','sdtcheck(''PatchExtractInSDT'');')
end

elseif comstR(Cam,'mkl_rt');
%% #mkl_rt -2
  fname=fullfile(matlabroot,'bin',getenv('MATLAB_ARCH'),'mkl_rt.dll');
  if isunix
  elseif ~exist(fname,'file')&&strcmpi(mexext,'mexw64')
   st1=fullfile(sdtcheck('SDTRootDir'),'mklserv','64','mkl_rt.dll');
   warning('Missing %s copied from %s',fname,st1);copyfile(st1,fname);
  elseif ~exist(fname,'file')&&strcmpi(mexext,'mexw32')
   st1=fullfile(sdtcheck('SDTRootDir'),'mklserv','32','mkl_rt.dll');
   error('Missing %s should be copied from %s',fname,st1);
  elseif 1==2
   [i1,st1]=system('which mkl_rt.dll');st1=strrep(st1,'/cygdrive/c','c:');
   st1=fullfile(st1);st1(st1<32)='';
   copyfile(st1,fname)
  end
  
elseif comstR(Cam,'mklpath');
%% #MklPath : verifies path for mkl_utils and mklserv_utils -2
% windows mkl_rt.dll in $Matlabroot/bin/win64/mkl_rt.dll
% linux  system(sprintf('ldd %s | grep sdt',which('mkl_utils')));
% fullfile(matlabroot,'extern','lib',getenv('ARCH'))
  if sd_pref('is','SDT','MklServPath');sd_pref('rm','SDT','MklServPath');end
  rehash('toolboxreset')
  which mkl_utils -all
  if exist('mkl_utils','file')==2; cd('..');end
  if exist('mkl_utils','file')~=3; 
    error(['You should use the mkl_utils.%s file \n'...
     'check that your current directory is not the SDT base directory.\n '],mexext)
  end
  if ~isunix;
   sdtcheck('patchmkl_rt');
  else
   [i1,st1]=system(sprintf('ldd %s | grep "not found"',which('mkl_utils')));
   if i1==0 % if no match, grep status is 1, and no output is generated
    st1=textscan(strrep(st1,'=> not found',''),'%s');st1=st1{1};
    fprintf('\n As user "root" do\n')
    fprintf('\ncd %s',fullfile(sdtcheck('SDTRootDir'),'mklserv','64'))
    fprintf('\ncp %s %s\n', sprintf('%s ',st1{:}), ...
     fullfile(matlabroot,'extern','lib',getenv('ARCH'),'.'))
   end
  end
  sdtcheck('syspathlib;')
  st1='';try; mkl_utils('cvs'); catch;st1='failed';end
  try; feval('mklserv_client','cvs'); catch;st1='failed';end
  if ~isempty(st1)
    warning(sprintf('%s\n','mkl_utils mex load failed, consider ', ...
        '- sdtcheck(''depends mklserv_client''), ', ...
        '- sdtcheck(''depends mklserv_utils''), ', ...
        '  after installing $sdt/7.5/depends.exe from www.dependencywalker.com', ...
        ' - if showing MSVCR...DLL unknown you need MSVC redistributables, see', ...
    '- if missing MKL you should run sdtcheck(''syspathlib'')', ...
    '- other cases please report'))
  end
  try
   fprintf('Trying Pardiso server');
   ofact mklserv_utils;mklserv_utils('clear');mklserv_utils('clear')
   fprintf('Done\n');
  catch ER
   disp(ER)
   fprintf('Pardiso server failed\n');
  end
  
elseif comstR(Cam,'extract')
%% #PatchExtract : default extraction of a file -2
% sdtcheck('PatchExtract');sdtcheck('PatchExtractInSdt');

RO=LastPatch;
if comstR(Cam,'extractinsdt') % sdtcheck('PatchExtractInSdt');
 if sdtkey('isdev'); error('Should be checked');end
 clear mkl_utils mklserv_client 
 munlock sdtrlm; clear sdtrlm
 munlock sp_util;clear sp_util
 fprintf('Starting unzip to %s \n',RO.SdtRoot)
 unzip(RO.LocalName,RO.SdtRoot);
 fprintf('Ended unzip to %s \n',RO.SdtRoot)
end

elseif comstR(Cam,'file')
%% #PatchFile : see if in path or in tempdir/sdtdemos, if not download -2
% f1=sdtcheck('PatchFile',struct('fname','ubeamcb.dat','in','NasSE.zip','back',1));

if ~isfield(RO,'wd')||isempty(RO.wd)||~exist(RO.wd,'dir')
 RO.wd=fullfile(sdtdef('tempdir'),'sdtdemos');
end
f2=which(RO.fname); if ~isfield(RO,'reset');RO.reset=0;end
if ~exist(f2,'file');f2=fullfile(RO.wd,RO.fname);end
if ~exist(f2,'file');
 clear sdtweb; f3=sdtweb('_find',RO.wd,RO.fname);
 if ~isempty(f3); if iscell(f3);f2=f3{1}; else; f2=f3; end; end
end
if ~exist(f2,'file')||(isfield(RO,'reset')&&RO.reset)
 %% Download is needed
 RB=RO;
 if isfield(RO,'in'); RO.fname=RO.in;% Actually in a zip file
  sdtkey('mkdir',RO.wd);
  if ~isfield(RO,'PostFcn')&&(~isempty(strfind(lower(RO.fname),'.zip')) || ...
      ~isempty(strfind(lower(in),'.zip')) )%#ok<STREMP>
      RO.PostFcn='cd(RO.wd);unzip(RO.in);';
  end
 end 
 if length(dbstack)>1;assignin('caller','RO_patchfile',RO);end
 RO=sdtcheck('patchget',RO); % Download the patch
 if length(dbstack)>1;assignin('caller','RO_patchfile',RO);end
 if isfield(RO,'Err')&&~isempty(RO.Err)
 elseif ~isfield(RO,'in');
 elseif ~exist(RO.in,'file')
   if exist(fullfile(RO.wd,RO.in),'file'); RO.in=fullfile(RO.wd,RO.in);
     eval(RO.PostFcn); % Do the extraction
   elseif exist(fullfile(RO.wd,regexprep(RO.in,'([^/]*/)','')),'file'); 
       RO.in=fullfile(RO.wd,regexprep(RO.in,'([^/]*/)',''));
     eval(RO.PostFcn); % Do the extraction
   else
      out='Download failed';return;
   end
 else;
  eval(RO.PostFcn); % Do the extraction
 end
 if length(dbstack)>1;assignin('caller','RO_patchfile',RO);end
 if exist(f2,'file');out=f2; % Directly in dir
 else
  sdtweb('_wd') % reset scanned dirs if anything was added
  f2=sdtweb('_find',RO.wd,RB.fname); % possibly in subdir
  if isempty(f2)
   sdtweb('_link',sprintf('delete(''%s'')',RO.in))
   error('Did not find ''%s'' in ''%s'', possibly delete zip and restart',RB.fname,RO.in);
  elseif iscell(f2);f2=f2{1};
  end
 end
 if length(dbstack)>1;assignin('caller','RO_patchfile',RO);end
 out=f2;
else;out=f2; 
end

elseif comstR(Cam,'get')
%% #PatchGet : generic download of a patch -2
% sdtcheck('PatchGet',struct('url','http://www.sdtools.com/contrib','fname','cc_mode.op2','back',1));
% sdtcheck('PatchGet',struct('fname','cc_mode.op2','back',1));
% f1=sdtcheck('PatchFile',struct('fname','ubeamcb.dat','in','NasSE.zip','back',1));
% https://fr.mathworks.com/matlabcentral/answers/92506-how-can-i-configure-matlab-to-allow-access-to-self-signed-https-servers

pw0=pwd;
if ~isfield(RO,'wd')||isempty(RO.wd)||~exist(RO.wd,'dir')
 RO.wd=fullfile(sdtdef('tempdir'),'sdtdemos');
end
if ~exist(RO.wd,'dir')
 sdtw('_nb','Creating temporary directory %s', RO.wd)
 try;sdtkey('mkdir',RO.wd);
 catch; error('Failed to create %s, please choose an accessible directory',RO.wd)
 end
end
if ~isfield(RO,'url'); % Default behaviour : get from contrib
    RO.url='https://www.sdtools.com/contrib';
    if ~isfield(RO,'back')||~RO.back;RO.back=1;end
end
if RO.url(end)~='/'&&~isempty(RO.fname); RO.RemoteName=[RO.url '/' RO.fname];
else; RO.RemoteName=[RO.url RO.fname];
end
[un1,fname,ext]=fileparts(RO.fname);RO.LocalName=fullfile(RO.wd,[fname ext]);
RO.SdtRoot=sdtcheck('SDTRootDir');


if isfield(RO,'getURL')&&RO.getURL
 fprintf(1,'2/ Download \n%s%s\n\n',RO.RemoteName);
else
 try
 % File exist and reuse asked
 if isfield(RO,'back')&&RO.back&&exist(RO.LocalName,'file')
    if RO.back==2;st1='Force download';
    else;
      fprintf('\nUsing existing %s\n',RO.LocalName);
      st1='Reuse file';
    end
 else;
  % Otherwise download needed
  st1='Build PostFcn';
  fprintf('step1/ Getting %s\n  to be placed in ''%s''\n',RO.RemoteName,RO.wd)
  fprintf('  If failed perform manually and execute the step2 link below\n');  
 end
 LastPatch=RO;st2='';
 if isfield(RO,'PostFcn')&&~isempty(RO.PostFcn)
   if strncmpi(RO.PostFcn,'extract',7);
    st2=sprintf('sdtcheck(''Patch%s'');',RO.PostFcn);
   else
    st2=sprintf('\nRO=%s\n%%\n%s\n',comstr(RO,-30,struct('NoClip',1)),RO.PostFcn);
   end
   fprintf('\nstep2/ Post will be done by link below %s\n\n%s\n\n', ...
      repmat('-',1,30),st2);
   RO.PostLink=st2;   
   sdtweb('_links',RO.PostLink,'step2/ click to finish patching');fprintf('\n');
   if comstR(RO.PostFcn,'@');eval(RO.PostFcn(2:end));end
 elseif nargout==1&&isfield(RO,'back')&&RO.back;out=RO.LocalName;
 else; fprintf('No PostFcn for PatchGet\n'); 
 end
 if ~strcmp(st1,'Reuse file'); 
  fprintf('Starting download ...');
  st1='download';
  if ~exist(RO.RemoteName,'file'); 
    st2=sprintf('websave(''%s'',''%s'')',RO.LocalName,RO.RemoteName);
    RO.LocalName=websave(RO.LocalName,RO.RemoteName);
  else; 
    st2=sprintf('copyfile(''%s'',''%s'')',RO.RemoteName,RO.LocalName);
    copyfile(RO.RemoteName,RO.LocalName)
  end
  fprintf(' done download to %s\n ',RO.LocalName);
 end
 RO.AttemptPost=1;
 LastPatch=RO;
 catch ERR
  st1=sprintf('\n%s\nFailed during \n  %s\n %s\n %s\n %s\n', ...
      ERR.message,st2,'please report or download manually ', ...
      sprintf(' %s to %s ',RO.RemoteName,RO.LocalName), ...
      sprintf('then extract with unzip to %s or click on link',fileparts(RO.LocalName)));
  if isfield(RO,'Err');
     RO.Err=ERR; % Possibly handle error below
     RO.ErrWarn=st1;
  else
   warning(st1);
   sdtweb('_links',RO.PostLink,'step2/ click to finish patching');
   error('Download failed read warning above');   
  end
 end
 if isfield(RO,'AttemptPost')
    try; 
     fprintf('Running step2: %s',RO.PostLink); eval(RO.PostLink)
     fprintf('Done');RO.AttemptPost='done';
    catch ERR
      disp(ERR)
    end
 end
end
cd(pw0); if nargout>0;out=RO;end

  
elseif comstR(Cam,'javapath'); [CAM,Cam]=comstR(CAM,9);
 %% #javapathSet : sdtcheck PatchJavapathset target - - - - - - - - - - - - - 
 if comstR(Cam,'set'); [CAM,Cam]=comstR(CAM,4);
  [CAM,Cam,forceStartupDir]=strutil('-forcestartupdir',[-25 3],CAM,Cam);
  [CAM,Cam,formcc]=strutil('-mcc',[-25 3],CAM,Cam);
  % MATLAB only reads a single classpath.txt, the customized classpath.txt
  % thus has to contain the complete default one
  % fullfile(matlabroot,'toolbox','local','classpath.txt')
  % and the additional ones in a local dir:
  % -> Before 800, fullfile(fileparts(which('startup')),'classpath.txt')
  %     This is too dangerous by default: matlab dependent
  %     stra=try to modify the initial classpath, option to force startup mod
  % -> From ver 800, fullfile(prefdir,'javaclasspath.txt') instead 
  carg=2;
  if carg<=nargin; fcin=varargin{carg}; carg=carg+1;
   if ~exist(fcin,'file')&&~formcc
    error('The file provided for cinguj.jar does not exist')
   end
  else
   fcin=which('cinguj.jar');
   if isempty(fcin)
    error(['You do not have a cinguj.jar file in your SDT installation, '...
     'something is wrong'])
   end
  end
  if carg<=nargin; fname=varargin{carg}; carg=carg+1;
  else
   if sdtdef('verm')>=800; fname='javaclasspath.txt'; wd=prefdir;
   elseif forceStartupDir
    fname='classpath.txt';
    try
     wd=fileparts(which('startup'));
     if isempty(wd); wd=textscan(userpath,'%s','delimiter',':'); wd=wd{1}{1}; end
    end
    if ~exist(wd,'dir')
     error('Could not locate userpath, please report to SDTools');
    end
   else % by default try to alter base MATLAB file for multi matlab compat. security
    fname=which('classpath.txt');
    [wd,fname,ext]=fileparts(fname); fname=[fname ext];
   end
   fname=fullfile(wd,fname);
  end
  if ~isempty(strfind(fcin,'sdt.cur'))&&~isempty(strfind(Cam,'reset'))
    fprintf('Not changing path for %s, force with \n%',fcin,...
        'sdtcheck(''PatchJavaPathSet Reset'')');return
  end
  fjpath=which('classpath.txt');
  fid=fopen(fname,'r');
  if fid==-1; fid=fopen(fjpath,'r');end
  st1=textscan(fid,'%s','delimiter','\n');st1=st1{1};
  fclose(fid);
  % check in uncommented lines presence of cinguj.jar
  i1=find(~cellfun(@any,regexp(st1,'^#.*'))); st2=st1(i1);
  i2=~cellfun(@isempty,regexp(st2,'cinguj.jar','match')); i3=false;
  if ~any(i2) % need to add to the javapath cinguj.jar
   st1=vertcat(st1,{'# SDTools java utilities';fcin});i3=true;
  else % check that the path is ok or reset
   st2=st2(i2);
   if length(st2)>1; % should not happen mutli def: remove duplicate and reset
    st1(i1(i2))=[];st1=vertcat(st1,st2{1});i3=true;
    i1=find(~cellfun(@any,regexp(st1,'^#.*'))); st2=st1(i1);
    i2=~cellfun(@isempty,regexp(st2,'cinguj.jar','match'));st2=st2{1};
   else; st2=st2{1};
   end
   if ~isequal(st2,fcin)||formcc % referenced path is not current
    i3=true; 
    if sdtdef('verm')<909||~formcc; st1{i1(i2)}=fcin;
    else; st1{i1(i2)}=['#' fcin]; % java classes unnecessary pb 909 segfault with $ctfroot
    end
   end
  end
  if i3 % reset file
   st1(cellfun(@isempty,st1))=[];
   try
    fprintf(1,'\nEditing %s',fname);
    fid=fopen(fname,'w');
    fprintf(fid,'%s\n',st1{:});
    fclose(fid);
    if ~formcc
     fprintf(2,['\n***\nThe Java class path file has been reset, you have to restart MATLAB' ...
      ' to make it effective\n***\n']);
     sdtw('_gr','Java Path: Please restart MATLAB to finalize this operation')
    end
   catch
    sdtw('_nb','Failed to edit %s. Please refer to the documentation for alternatives (see link below)',fname)
    sdtweb('_link','sdtweb sdtcheck','open documentation for java path setup')
   end
  elseif ~isempty(CAM)&&any(CAM==';'); 
  else; fprintf(1,'Java class path was correclty set for SDT\n');
  end
 else
  %% #javapath - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  st1=javaclasspath('-static');
  i1=~cellfun(@isempty,regexp(st1,'cinguj.jar','match'));
  if ~any(i1); out='';  
  else
   st1=st1(i1); out=st1{1}; wd1=fileparts(out); wd2=path; 
   if isunix; wd2=textscan(wd2,'%s','delimiter',':'); 
   else; wd2=textscan(wd2,'%s','delimiter',';');
   end
   wd2=wd2{1};
   if isunix; i0=ismember(wd1,wd2); else; i0=ismember(lower(wd1),lower(wd2)); end
   if exist('sdtkey','file')==2; i1=0; % not for isdev
   elseif ~i0&&~isdeployed % cinguj.jar is present but in another SDT
    wd3=fullfile(sdtcheck('SDTRootDir'),'7.5');
    if strcmpi(wd1,wd3); wd3=fileparts(which('cinguj.jar'));end
    s=warning('query','backtrace'); warning('off','backtrace');
    warning('SDT:JarLocation',['SDT java utilities (cinguj.jar) are present but refer to'...
     ' %s: an SDT different from the one in current use (%s). To reset the'...
     ' path, click on the link below to edit classpath.txt and restart MATLAB.'],...
     wd1,wd3);
    sdtweb('_link','sdtcheck(''PatchJavaPathSet'')','modify javaclasspath')
    warning(s);
   end
  end
  if isempty(out)
   s=warning('query','backtrace'); warning('off','backtrace');
   warning('SDT:JarLocation',['SDT java utilities (cinguj.jar) are not declared in the static'...
    ' MATLAB java path (classpath.txt). This will block some SDT functionalities. To activate it, ' ...
    'click on the link below to edit classpath.txt and restart MATLAB.'])
   sdtweb('_link','sdtcheck(''PatchJavaPathSet'')','modify javaclasspath')
   warning(s);
  end
  if nargout==0; fprintf(1,'JavaPath check, using %s\n',out);clear out; end
  
 end
    
else
% List of known patches
    
 % #PatchMkl : download and install the MklPatch -2
 % t_mkl('distrib');
 li={'mkl',struct('url','https://www.sdtools.com/contrib/', ...
    'fname','mklserv.zip','PostFcn','ExtractInSDT')
     };

 i1=strcmpi(Cam,li(:,1));
 if any(i1);
 i1=find(i1); RO=li{i1(1),2};RO.back=1;
 sdtcheck('PatchGet',RO)
 else;error('Patch%s unknown',CAM);
 end
end
elseif Cam(1)=='@';out=eval(CAM);
else; error('%s unknown',CAM);

end % function


% -----------------------------------------------------------------------
% -----------------------------------------------------------------------
% -----------------------------------------------------------------------

function out=current_sputil
out=5.0008;

function out=current_comstr
out=5.0005;

% -----------------------------------------------------------------------

function w=keep_errors(w);

j1=1;if isempty(w); return; end

ind = [0 find(w==10) length(w)+1];
while j1<length(ind)
 st=comstR(w(ind(j1)+1:ind(j1+1)-1),1);
 if strncmpi(st,'inflating',9)||strncmpi(st,'archive',7)
  w=w([1:ind(j1) ind(j1+1)+1:end]);
  ind = [0 find(w==10) length(w)+1];
 else; j1=j1+1;
 end
end

% -----------------------------------------------------------------------
function  un_message(varargin);
  
  CAM=varargin{1}; carg=2; 
  if strcmpi(CAM,'_nb'); carg=3;CAM=varargin{2};end
  if   carg<=nargin; st1=sprintf(CAM,varargin{carg:end});
  else; st1=CAM;
  end


  cf=findobj('tag','sdt4i'); 
   if isempty(cf); fprintf(1,'%s\n',st1);
   elseif comstR(st1,'_RESET') 
      set(findobj(cf,'tag','messages'),'string',{''},'value',1);
   else
    fprintf(1,'%s\n',st1);
    mes=get(findobj(cf,'tag','messages'),'string');
    i1=[0 find(st1==10) length(st1)+1];
    st2={};
    for j1=1:length(i1)-1 
     st3=st1(i1(j1)+1:i1(j1+1)-1); if isempty(st3); st3=' '; end
     st2{j1}=st3; %#ok<AGROW>
    end
    if ~isa(mes,'cell'); mes={mes}; end
    mes={mes{:},st2{:}};
    set(findobj(cf,'tag','messages'),'string',mes, ...
         'value',length(mes));
    drawnow
   end

%% -----------------------------------------------------------------------
function [CAM,Cam,st]=comstR(CAM,ind,opt)

if nargin==2&&ischar(ind) %initial string comparison

   if ~isempty(ind) && length(CAM)>=length(ind)
    if all(CAM(1:length(ind))==ind); CAM=1;return; end
   end
   CAM=0; return;

elseif ischar(ind)&&nargin>2 % parameter extraction utility

   if length(CAM)<length(ind); ind=ind(1:length(CAM));end
   i1=min([find(lower(CAM(1:length(ind)))~=ind) length(ind)+1 length(CAM)+1]);
   CAM=CAM(i1:length(CAM));
   if ~isempty(CAM)
    i1=find(CAM==','); if ~isempty(i1); CAM(i1)=char(32*ones(size(i1)));end
    i1=find(CAM==''''); if ~isempty(i1); CAM(i1)=char(32*ones(size(i1)));end
   end
   if ischar(opt) % format given
     if comstR(opt,'%s'); [i1,i2,i3,i4]=sscanf(CAM,opt,1);
     else; [i1,i2,i3,i4]=sscanf(CAM,opt);end
     Cam=CAM(i4:length(CAM));CAM=i1(:)';
     if ~isempty(Cam)
      ind = find(Cam~=32);ind = [min(ind):max(ind)];
      if ~isempty(ind); Cam = Cam(ind); else; Cam=[]; end
     end
     if nargout==3; st=lower(Cam);
     elseif nargout==2 && ischar(CAM); Cam=lower(CAM); end
   else; Cam=lower(CAM); 
   end % return the string

elseif length(ind)==1 && ind(1)>0  % eliminate front and tail blanks

   CAM = CAM(ind:length(CAM));

   if ~isempty(CAM)
    ind = find(CAM~=32&CAM~=0);
    if ~isempty(ind)
       CAM = CAM(ind(1):ind(length(ind))); Cam=lower(CAM);
    else; CAM='';Cam='';
    end
   else; Cam='';
   end

end

% -----------------------------------------------------------------------
% -----------------------------------------------------------------------
% -----------------------------------------------------------------------
function s=safe_mkdir(st)

s=sdtkey('mkdir',st);

%% -----------------------------------------------------------------------
function ReplaceKey(f_ori,f_temp,key,st_new)

try

fprintf('In file %s\nSetting XML KEY %s = %s\n',f_ori,key,st_new);
if exist(f_ori,'file')
  [fi,mes]=fopen(f_ori,'rb');if ~isempty(mes); error(mes); end
  if ischar(f_temp)
   if exist(f_temp,'file'); delete(f_temp); end
   if exist(f_temp,'file');
     error('Deletion of preexisting %s failed',f_temp);
   end
   [fo,mes]=fopen(f_temp,'w');  if ~isempty(mes);error(mes); end
  else; fo=f_temp;
  end
  st=fscanf(fi,'%c');fclose(fi);

  i1=strfind(st,sprintf('<%s>',key));
  i2=strfind(st,sprintf('</%s>',key))+length(key)+3;
  if ~isempty(i1)&&~isempty(i2)
    st=sprintf('%s<%s>%s</%s>%s',st(1:i1(1)-1),key,st_new,key,st(i2(1)+1:end));
  end

  fprintf(fo,'%c',st);
  if ischar(f_temp)
   fclose(fo);
   if ~exist(f_temp,'file');error('Creation of %s failed',f_temp);end
   delete(f_ori); copyfile(f_temp,f_ori);
   if ~exist(f_ori,'file')
     error('copy of %s to %s failed',f_tem,f_ori);
   end
  end
else; sprintf('''%s'' does not exist',f_ori);
end

catch
 un_message('_nb','\n Editing of %s failed\n',f_ori);
 if ~ischar(f_temp)
 elseif exist(f_temp,'file')
  un_message('_nb','\n To finish install copy %s to %s\n',f_temp,f_ori);
 else
  un_message('_nb','\n To finish install edit s\n',f_ori);
 end
 if ~isempty(mes); un_message(mes); else; un_message(lasterr);end %#ok<LERR>
end

%% -----------------------------------------------------------------------
function add_item(f_ori,f_temp,st_o,st_new)

try

if exist(f_ori,'file')
  [fi,mes]=fopen(f_ori,'r');if ~isempty(mes); error(mes); end
  if exist(f_temp,'file'); delete(f_temp); end
  if exist(f_temp,'file');
    error('Deletion of preexisting %s failed',f_temp);
  end
  [fo,mes]=fopen(f_temp,'w');  if ~isempty(mes); error(mes); end
  st=fscanf(fi,'%c');fclose(fi);
  if isempty(strfind(st,st_new))
    i1=find(st==10|st==13);i2=strfind(st,st_o);
    i2=i1([max(find(i1<i2)) min(find(i1>i2))]);
    if st(i2(2))==st(i2(1)); i2(1)=i2(1)+1; end
    st=[st(1:i2(2))  st_new st(i2(2):end)];
  end
  fprintf(fo,'%c',st); fclose(fo);
  if ~exist(f_temp,'file')
   error('Creation of %s failed',f_temp);
  end
  delete(f_ori);
  copyfile(f_temp,f_ori);
  if ~exist(f_ori,'file')
   error('copy of %s to %s failed',f_tem,f_ori);
  end
end

catch
 un_message('_nb','\n Editing of %s failed\n',f_ori);
 if exist(f_temp,'file')
  un_message('_nb','\n To finish install copy %s to %s\n',f_temp,f_ori);
 else
  un_message('_nb','\n To finish install edit s\n',f_ori);
 end
 if ~isempty(mes); un_message(mes); else; un_message(lasterr);end %#ok<LERR>
end

% -----------------------------------------------------------------------
% -----------------------------------------------------------------------
% -----------------------------------------------------------------------
function tname=s_libpath

tname=fullfile(sdtcheck('SDTRootDir'),'mklserv');
    if ~isempty(strfind(mexext,'32'));tname=fullfile(tname,'32');
    else;tname=fullfile(tname,'64');
    end
    
function st=sdt_version

[st,st1,st2]=fileparts(which('sdtcheck'));
try 
  fin=fopen(fullfile(st,'Contents.m'));
  st=fscanf(fin,'%c',100);i1=find(st==10);
  st=st(i1(1)+3:i1(2)-1);
  fclose(fin);
catch
  st='Unknown version';
end

function out=cleanGetEnv(r1)
while ~isempty(r1)
 out=getenv(r1{1}); r1(1)=[];
 if ~isempty(out); break; end
end

function checkRlmExpire(verSDT,checkExp);
 if nargin==1; checkExp=1;end
 
     r1=sdtrlm('products',[],verSDT);
     r1(cellfun(@isempty,r1(:,1)),:)=[];
     if isempty(r1)
       if ischar(verSDT);verSDT=str2double(verSDT);end
       fprintf('No feature for version %.1f',verSDT)
     else
      fprintf('\n');
      for j1=1:size(r1,1)
       if r1{j1,3}>3e4
        if ~checkExp
         fprintf('Feature ''%s'' v%s is permanent\n',r1{j1,1:2});
        end
       else
        if checkExp
          if r1{1,3}<60
           fprintf('Warning : feature ''%s'' v%s will expire in %i days\n',r1{j1,:});
          end
        else
          fprintf('Feature ''%s'' v%s will expire in %i days\n',r1{j1,:});
        end
       end
      end
     end

 
function out=checkShellEnv
persistent checked
if isunix
 out=getenv('SHELL'); % shell interpreter for MATLAB system commands under linux
 if isempty(strfind(out(end-min(3,length(out)-1):end),'bash'))&&isempty(checked)
  r1=warning('query','backtrace');
  warning('off','backtrace')
  warning(['System commands are not called with bash, but with "%s".\n' ...
  'Consider starting matlab under bash'],out);
  warning(r1.state,'backtrace')
  checked=1;
 end
else; out=''; 
end
