function [THIS,NPATH,SSTATESUCCESS] = myupdatemodel(THIS,P,ASSIGNPOS,STDCORRPOS,OPT)
% MYUPDATEMODEL  [Not a public function] Update parameters, sstate, solve, and refresh.
%
% Backend IRIS function.
% No help provided.

% -IRIS Toolbox.
% -Copyright (c) 2007-2012 Jaromir Benes.

%**************************************************************************

% TODO: Add a `'chksstate='` option. Create and supply a ready-to-use
% function or code that checks the sstate quickly.

SSTATESUCCESS = true;
NPATH = 1;
    
assignNan = isnan(ASSIGNPOS);
ASSIGNPOS = ASSIGNPOS(~assignNan);
stdcorrNan = isnan(STDCORRPOS);
STDCORRPOS = STDCORRPOS(~stdcorrNan);

% Update regular parameters and run refresh if needed.
refreshed = false;
if any(~assignNan)
    THIS.Assign(1,ASSIGNPOS) = P(~assignNan);
end

% Update stds and corrs.
if any(~stdcorrNan)
    THIS.stdcorr(1,STDCORRPOS) = P(~stdcorrNan);
end

% Refresh dynamic links. The links can refer/define std devs and
% cross-corrs.
if nargin > 4 && OPT.refresh && ~isempty(THIS.Refresh)
    THIS = refresh(THIS);
    refreshed = true;
end

% If only stds or corrs have been changed, no values have been refreshed,
% and no user preprocessor is called, return immediately as there's no need
% to re-solve or re-sstate the model.
if all(assignNan) && ~isa(OPT.sstate,'function_handle') && ~refreshed
    return
end

if THIS.linear
    % Linear models.
    if OPT.solve
        if OPT.fastsolve
            % Trigger fast solve by passing in only one input. This
            % only handles one parameterisations and does not compute
            % expansion matrices.
            [THIS,NPATH] = mysolve(THIS);
        else
            % Regular solve; compute also expansion matrices.
            [THIS,NPATH] = mysolve(THIS,1);
        end
        if OPT.refresh && ~isempty(THIS.Refresh)
            THIS = refresh(THIS);
        end
    else
        NPATH = 1;
    end
    if OPT.sstate
        THIS = mysstatelinear(THIS);
    end
else
    % Non-linear models.
    if isstruct(OPT.sstate)
        % Call to the IRIS sstate solver.
        [THIS,SSTATESUCCESS] = mysstatenonlin(THIS,OPT.sstate);
        if OPT.refresh && ~isempty(THIS.Refresh)
            THIS = refresh(THIS);
        end
    elseif isa(OPT.sstate,'function_handle')
        % Call to a user-supplied sstate solver.
        [THIS,SSTATESUCCESS] = OPT.sstate(THIS);
        if OPT.refresh && ~isempty(THIS.Refresh)
            THIS = refresh(THIS);
        end
    end
    if OPT.solve
        if OPT.fastsolve
            % Trigger fast solve by passing in only one input. This
            % does not compute expansion matrices.
            [THIS,NPATH] = mysolve(THIS);
        else
            % Regular solve; compute also expansion matrices.
            [THIS,NPATH] = mysolve(THIS,1);
        end
    else
        NPATH = 1;
    end
end

end
