function [ssInBlkHs, ssOutBlkHs, ssTriggerBlkHs, ssEnableBlkHs, ssFcnCallInHs] = getBlockHandlesForPortsInSubsys(subsysH)
    % getBlockHandlesForPortsInSubsys is another version of 
    % 'Sldv.utils.getSubSystemPortBlks' that returns a grouped set of outputs
    % ssInBlkHs, ssOutBlkHs based on their corresponding portNumbers

%   Copyright 2019-2022 The MathWorks, Inc.

    % ssInBlkHs(i) : inport block for the port number i. Incase of multiple
    % In Bus elements sharing the same portNumber i, ssInBlkHs(i)
    % represents on such block handle (the first signal that appears on the canvas)

    % ssOutBlkHs(i) : outport block for the port number i. Incase of multiple
    % Out Bus elements sharing the same portNumber i, ssOutBlkHs(i)
    % represents on such block handle (the first signal that appears on the canvas)
    isBlkNames = ischar(subsysH);
    [nonConsolidatedInportBlks, nonConsolidatedOutportBlks, ssTriggerBlkHs, ssEnableBlkHs, ssFcnCallInHs] = Sldv.utils.getSubSystemPortBlks(subsysH);
    mdlHasRootLvlBEP = any(strcmp(get_param([nonConsolidatedInportBlks; nonConsolidatedOutportBlks],...
        'IsBusElementPort'),'on'));
    if ~isempty(nonConsolidatedInportBlks) && mdlHasRootLvlBEP
        ssInBlkHs = (getConsolidatedSourceModelinportBlocks(nonConsolidatedInportBlks,isBlkNames))';
    else
        ssInBlkHs = nonConsolidatedInportBlks;
    end
    if ~isempty(nonConsolidatedOutportBlks) && mdlHasRootLvlBEP
    ssOutBlkHs = (getConsolidatedSourceModelOutportBlocks(nonConsolidatedOutportBlks,isBlkNames))';
    else
        ssOutBlkHs = nonConsolidatedOutportBlks;
    end

end

function inportBlkHandles = getConsolidatedSourceModelinportBlocks(nonConsolidatedInportBlks,isBlkNames)
    % 'getConsolidatedSourceModelinportBlocks' generates inport block
    % handles by grouping all the inports belonging to same port number. 
    
    % we index the output arrays inportBlkHandles based 
    % on the port numbers
    
    % Incase of multiple out bus elements sharing the same port number, 
    % if 'portHandle' is the port number of one such inport,
    % inportBlkHandles(portHandle) will reflect a block handle of one of
    % the multiple out bus elements that share a port number
        
        testSubsysinportsH = unique(str2double(get_param(nonConsolidatedInportBlks,'Port')));
        if ~isBlkNames
            inportBlkHandles(length(testSubsysinportsH)) = 0;
            % Consolidate inports based on the portNumber of each inport block
            % In Bus elements belonging to the same In Bus will share the same
            % port Number. These ports should be grouped together.
            for idx=1:length(nonConsolidatedInportBlks)
                portHandle = str2double(get_param(nonConsolidatedInportBlks(idx),'Port'));
                if ~(inportBlkHandles(portHandle) > 0) % This means the blockhandle was found
                    inportBlkHandles(portHandle) = nonConsolidatedInportBlks(idx);
                end
            end
        else
            inportBlkHandles{length(testSubsysinportsH)} = '';
            for idx=1:length(nonConsolidatedInportBlks)
                portHandle = str2double(get_param(nonConsolidatedInportBlks(idx),'Port'));
                if isempty(inportBlkHandles{portHandle}) % This means the blockhandle was found
                    currentInportID = Simulink.ID.getSID(nonConsolidatedInportBlks(idx));
                    if (sldvshareprivate('isBusElem',currentInportID))
                        inportBlkHandles(portHandle) = get_param(currentInportID,'portName');
                    else
                        inportBlkHandles(portHandle) = nonConsolidatedInportBlks(idx);
                    end
                end
            end
        end
end

function outportBlkHandles = getConsolidatedSourceModelOutportBlocks(nonConsolidatedOutportBlks,isBlkNames)
    % 'getConsolidatedSourceModelOutportBlocks' generates outport block
    % handles by grouping all the outports belonging to same port number. 
    
    % we index the output arrays outportBlkHandles based 
    % on the port numbers
    
    % Incase of multiple out bus elements sharing the same port number, 
    % if 'portHandle' is the port number of one such outport,
    % outportBlkHandles(portHandle) will reflect a block handle of one of
    % the multiple out bus elements that share a port number
        
        testSubsysOutPortsH = unique(str2double(get_param(nonConsolidatedOutportBlks,'Port')));
        if ~isBlkNames
            outportBlkHandles(length(testSubsysOutPortsH)) = 0;
            % Consolidate outports based on the portNumber of each outport block
            % In Bus elements belonging to the same In Bus will share the same
            % port Number. These ports should be grouped together.
            for idx=1:length(nonConsolidatedOutportBlks)
                portHandle = str2double(get_param(nonConsolidatedOutportBlks(idx),'Port'));
                if ~(outportBlkHandles(portHandle) > 0) % This means the blockhandle was found
                outportBlkHandles(portHandle) = nonConsolidatedOutportBlks(idx);
                end
            end
        else
            outportBlkHandles{length(testSubsysOutPortsH)} = '';
            for idx=1:length(nonConsolidatedOutportBlks)
                portHandle = str2double(get_param(nonConsolidatedOutportBlks(idx),'Port'));
                if isempty(outportBlkHandles{portHandle}) % This means the blockhandle was found
                    currentOutportID = Simulink.ID.getSID(nonConsolidatedOutportBlks(idx));
                    if (sldvshareprivate('isBusElem',currentOutportID))
                        outportBlkHandles(portHandle) = get_param(currentOutportID,'portName');
                    else
                        outportBlkHandles(portHandle) = nonConsolidatedOutportBlks(idx);
                    end
                end
            end
        end
end


% LocalWords:  Incase Modelinport