function obj = slslicer( model, opts )
    % SLSLICER - Creates an API object for invoking Model Slicer
    %
    %  OBJ = SLSLICER(MODEL) - Creates an API object OBJ for model MODEL
    %  exposing methods for invoking Model Slicer.  Uses currently available
    %  Model Slicer options and configurations associated with MODEL, as
    %  defined by SLSLICEROPTIONS.
    %  Throws an error if MODEL is not loaded in memory.
    %
    %  OBJ = SLSLICER(MODEL, OPTS) - Creates an API object OBJ for model MODEL
    %  using the options object OPTS as defined by SLSLICEROPTIONS.
    %  Throws an error if MODEL is not loaded in memory or if Model Slicer is
    %  already instantiated for MODEL.
    %
    % API Methods
    %  obj.activate        - Configures model for analysis
    %  obj.unlock          - Disposes analysis data while retaining highlights
    %  obj.terminate       - Disposes analysis data and reverts highlighting (invoked
    %                        when object goes out of scope)
    %  obj.highlight       - Updates the highlighting
    %  obj.unhighlight     - Removes highlighting without changing activation
    %  obj.slice           - Creates a sliced model
    %  obj.simulate(t1,t2) - Apply simulation time window from time "t1" to
    %                        time "t2" for simulation.
    %
    %  obj.ActiveBlocks    - Returns non-virtual block handles that are active.
    %
    % Example:
    %
    % mdl = 'sldvdemo_cruise_control';
    % open_system(mdl)
    % % Create a Model Slicer API object
    % obj = slslicer(mdl);
    % % Activate the model
    % activate(obj);
    % % Add a starting point
    % addStartingPoint(obj,'sldvdemo_cruise_control/Controller/Switch1');
    % % Highlight the model
    % highlight(obj);
    % % Apply simulation time window by running simulation
    % simulate(obj,0,1);
    % % Generate sliced model
    % slicedModel = slice(obj);
    % % Terminate the model
    % terminate(obj);
    % % clear the Model Slicer API object
    % clear obj
    %
    % See also SLSLICEROPTIONS, SLSLICERTRACE.

    %   Copyright 2015-2020 The MathWorks, Inc.
    
    if nargin < 1
        error('ModelSlicer:API:InvalidNumInputs',getString(message('Sldv:ModelSlicer:SLSlicerAPI:InvalidUsageOfSlslicer')));
    end
    
    model = convertStringsToChars(model);
    if nargin < 2
        opts = [];
    else
        opts = convertStringsToChars(opts);
    end
    if ~bdIsLoaded(model)
        error('ModelSlicer:API:ModelMustBeLoaded',getString(message('Sldv:ModelSlicer:SLSlicerAPI:ModelMustBeLoaded',model)));
    end
    modelH = get_param(model,'Handle');
    if bdIsLibrary(model)
        error('ModelSlicer:API:InvalidModel',getString(message('Sldv:ModelSlicer:SLSlicerAPI:SlslicerCannotCalledA')));
    end
    
    msObj = modelslicerprivate('slicerMapper','get',modelH);
    if isa(msObj,'ModelSlicer')
        if ~isempty(msObj.dlg)
            error('ModelSlicer:API:UIisOpened',getString(message('Sldv:ModelSlicer:SLSlicerAPI:SlslicerCannotCalledWhen')));
        else
            error('ModelSlicer:API:AnotherAPIObjectFound',getString(message('Sldv:ModelSlicer:SLSlicerAPI:AnotherAPIObjectFound')));
        end
    end
    
    % If already compiled, exit early
    if slslicer.internal.checkDesiredSimulationStatus(modelH, 'isSimStatusPausedOrCompiled') && isempty(msObj)
        error('ModelSlicer:API:AlreadyCompiled', ...
            getString(message('Sldv:ModelSlicer:SLSlicerAPI:ModelIsAlreadyActivated')));
    end
    
    if isempty(opts)
        % Create new SlicerConfiguration and attach it.
        % If the model has SlicerConfiguration in SLX package, it will be
        % used.
        scfg = SlicerConfiguration.getConfiguration(modelH);
%         scfg.createSessionIfNeeded;
        obj = SLSlicerAPI.SLSlicer(modelH,scfg);
    elseif ischar(opts)
        % Load existing SlicerConfiguration from slms file.
        scfg = SlicerConfiguration.loadConfigurationFromFile(modelH,opts);
        scfg.createSessionIfNeeded;
        obj = SLSlicerAPI.SLSlicer(modelH, scfg);
    elseif isa(opts,'SLSlicerAPI.SLSlicerOptions')
        % SLSlicerOption object is specified.
        obj = SLSlicerAPI.SLSlicer(modelH,opts);
        updateSlicerConfiguration(obj,modelH);
    else
        error('ModelSlicer:API:InvalidInput',getString(message('Sldv:ModelSlicer:SLSlicerAPI:InvalidInputArgumentIsGiven')));
    end
end
