function [objH, charStart, charEnd] = sid_resolve_innermost(compositeSidStr)
% Interpret the appropriate innermost object given a CR delimited list of SSIDs

%   Copyright 2010-2020 The MathWorks, Inc.

    objH = -1;
    charStart = -1;
    charEnd = -1;

    if isempty(compositeSidStr)
        return;
    end

    objCnt = sum(compositeSidStr == newline) + 1;

    allObj = zeros(1,objCnt);
    allStart = zeros(1,objCnt);
    allEnd = zeros(1,objCnt);
    allInsideSFMask = false(1,objCnt);
    
    strRem = compositeSidStr;
    innerSid = '';
    innerIdx = -1;

    for idx = 1:objCnt
        [thisSid, strRem] = strtok(strRem,newline);           %#ok<STTOK>
        if ~isempty(thisSid)
            [allObj, allStart, allEnd, allInsideSFMask, innerSid, innerIdx] = resolveSid(thisSid, allObj, allStart, allEnd, allInsideSFMask, innerSid, innerIdx, idx, objCnt);
        end        
    end

    if innerIdx > 0
        objH = allObj(innerIdx);
        charStart = allStart(innerIdx);
        charEnd = allEnd(innerIdx);
    end
end


function out = is_parent_sf_mask(blockH)
    out = false;
    try
        parentH = get_param(blockH,'Parent');
        out = slprivate('is_stateflow_based_block', parentH);
    catch Mex    %#ok<NASGU>
    end
end

function [allObj, allStart, allEnd, allInsideSFMask, innerSid, innerIdx] =  resolveSid(thisSid, allObj, allStart, allEnd, allInsideSFMask, innerSid, innerIdx, idx, objCnt)
    thisObj = [];
    try
        [thisObj, thisAux] = Simulink.ID.getHandle(thisSid);
    catch ME %#ok<NASGU>
    end

    % g996629. thisObj will be [] if thisSid is of the form 'model_name:0'.
    % This is the case with synthesized blocks.
    if isempty(thisObj)
        return;
    end

    if isfloat(thisObj) && numel(thisObj)==1
        allObj(idx) = thisObj;
        allInsideSFMask(idx) = is_parent_sf_mask(thisObj);
    elseif thisObj.isa('Stateflow.Object')
        allObj(idx) = thisObj.Id;
    else
        allObj(idx) = thisObj.Handle;
    end


    % Compare this SID with the existing inner SID
    if isempty(innerSid)
        if ~allInsideSFMask(idx) || idx==objCnt
            innerIdx = idx;
            innerSid = thisSid;
        end
    else
        if contains(thisSid, innerSid) && ~allInsideSFMask(idx)
            innerIdx = idx;
            innerSid = thisSid;
        end
    end

    if ~isempty(thisAux)
        [startStr,endStr] = strtok(thisAux,'-');
        allStart(idx) = str2double(startStr);
        allEnd(idx) = -str2double(endStr);
    else
        allStart(idx) = -1;
        allEnd(idx) = -1;
    end
end