function varargout = extract(obj,block,varargin)
%

%   Copyright 2020-2022 The MathWorks, Inc.

            obj.BlockH = Sldv.utils.getObjH(block, true);
            
            % obj.BlockH will always be valid as callers of this function have performed block validation
            assert(ishandle(obj.BlockH));

            if obj.Status
                if ~Sldv.Extract.checkIsActive(obj.BlockH)
                    obj.Status = false;
                    subModelH = bdroot(obj.BlockH);
                    err_id = 'Sldv:EXTRACT:ContentForExtractionMustNotBe';
                    err_msg = getString(message(err_id));                    
                    err_msg = strrep(err_msg,newline,' ');    
                    sldvshareprivate('avtcgirunsupcollect','clear');
                    sldvshareprivate('avtcgirunsupcollect','push',obj.BlockH,'sldv',err_msg, err_id);                        

                    % Fill error structure
                    obj.ErrMsg = sldvshareprivate('avtcgirunsupdialog', subModelH, obj.ShowUI); 
                else
                    obj.OrigModelH = bdroot(obj.BlockH);
                    obj.Opts = obj.validateExtractArgs(varargin{:});
    
                    % Enter into extraction phase
                    obj.PhaseId = 1;
    
                    % Perform extraction using SL Test APIs
                    [obj.ModelH, ~, error_occ, extractExc] = Simulink.harness.internal.extractModelref(obj.BlockH);
    
                    if error_occ
                        err_msg   = getString(message('Sldv:SubSysExtract:InvalidFirstArg', obj.UtilityName));
                        msgid = 'Sldv:SubSysExtract:InvalidFirstArg';
    
                        ME = MException(msgid, err_msg);
                        ME = ME.addCause(extractExc);
                        
                        obj.setExtractError(err_msg, msgid);
                        obj.Status = false;
                        obj.ModelH = [];
                        obj.deriveErrorMsg(ME);
                    else
                        % Configure coverage of blocks that get inserted while generating SLDV
                        % compatible harness
                        sldvshareprivate('configSLDVCompatibleHarness', obj.OrigModelH, obj.ModelH);
                        origBlockName = get_param(obj.BlockH,'Name');                        
                        obj.renameExtractedBlock(origBlockName);
                        if ~obj.IsModelSlicer
                            obj.setFixedStepSolver;
                        end                    
                        obj.saveExtractedModel;
                    end
                end
            end

            varargout{1} = obj.Status;
            varargout{2} = obj.ModelH;
            varargout{3} = obj.ErrMsg;
end

