function self = restoreSolver(self, CheckPointFile, optionsIn)
% private to BlackboxModelOptimizer class.

%   Copyright 2018-2022 The MathWorks, Inc.

% Load 'BlackboxModelOptimizerData from the file (assuming there is no data)
warnState = warning('query','MATLAB:load:variableNotFound');
warning('off','MATLAB:load:variableNotFound')            
try
    load(CheckPointFile,'-mat', 'CheckPointData');
    warning(warnState)
catch ME
    warning(warnState)
    rethrow(ME)
end

try
    BlackboxModelConstantData = CheckPointData.BlackboxModelConstantData;
    
    for ii = 1:length(self.constantVars)
        var = self.constantVars{ii};
        self.(var) = BlackboxModelConstantData.(var);
    end
    
    BlackboxModelOptimizerData = CheckPointData.BlackboxModelOptimizerData;
    
    for ii = 1:length(self.changingVars)
        var = self.changingVars{ii};
        self.(var) = BlackboxModelOptimizerData.(var);
    end
    
catch ME
    error(message('globaloptim:surrogateopt:CheckpointDataNotConsistent'))
end

% timeoffset is set to already elapsed time
self.info.timeoffset = self.state.elapsedtime;

if ~isempty(fieldnames(optionsIn))
    % Take new options if provided (not all options can be changed)
    optionsIn = globaloptim.bmo.parseSurrogateopt(optionsIn, self.info.nvars);
    
    self.options.MaxTime = optionsIn.MaxTime; % + self.state.elapsedtime;
    self.options.MaxFunctionEvaluations = optionsIn.MaxFunctionEvaluations; %+ self.state.funccount;
    self.options.PlotFcn = optionsIn.PlotFcn;
    self.options.OutputFcn = optionsIn.OutputFcn;
    self.options.Display = optionsIn.Display;
    self.options.Verbosity = optionsIn.Verbosity;
    self.options.ObjectiveLimit = optionsIn.ObjectiveLimit;
    self.options.UseParallel = optionsIn.UseParallel;
    self.options.UseVectorized = optionsIn.UseVectorized;
    self.options.BatchUpdateInterval = optionsIn.BatchUpdateInterval;
    self.options.CheckpointInterval = optionsIn.CheckpointInterval;

    % Setup ObjectiveSenseManager internal option and create wrapper output
    % function for all user output and plot functions. The display option
    % or user-specified output/plot fcns may have changed from the stored
    % manager properties. Need to re-set.
    createOuputFcnWrapper = true;
    self.options = optim.internal.utils.ObjectiveSenseManager.setup(self.options,createOuputFcnWrapper);
    
    self.options.CheckpointFile = optionsIn.CheckpointFile;
    self = self.copyOptions(self.options);
    
end

% Recreate ModelManager
self.modelMgr = globaloptim.bmo.ModelManager(self.expensive,self.options, ... 
    self.Verbosity);
self.modelMgr.EvaluationCount = self.state.funccount;

% Restore random state
rng(self.state.rngstate);
                    
self.solverRef = globaloptim.bmo.solver(struct('setup',true));
if ~isfield(self.solverRef,'id')
    error(message('globaloptim:surrogateopt:SurrogateSolverInitFailed.'));
end

self.trialRequest.id = self.solverRef.id;
self.statusRequest.id = self.solverRef.id;
self.resultsRequest.id = self.solverRef.id;

if ~isempty(self.options.CheckpointFile)
     self.saveRequest.id = self.solverRef.id;
else
    self.saveRequest = [];
end



% Now, restore the solver
restoreRequest = optionsIn;
restoreRequest.id = self.solverRef.id;
restoreRequest.request = true;
restoreRequest.load = true;
restoreRequest.restorefile = CheckPointFile;

% Setup solver interface boiler plate
response = globaloptim.bmo.solver(restoreRequest);
 % Ensure no error
 if response.retcode == -100
     error(response.messageID,response.message);
 end

end

