function scrunchSubsystemPorts(subsysH)

    [outPortHs, inPortHs] = findAllPortBlocks(subsysH);
    
    if (isempty(outPortHs) && isempty(inPortHs))
        return;
    end
    
    
    % Scrunch the inputs to their destination ports
    for idx = 1:numel(inPortHs)
        blkH = inPortHs(idx);
        [destPortH, lineH] = dest_portH(blkH);
        if (destPortH>0)
            [blkPos, blkOrient] = compute_block_layout(destPortH, true);
            scrunch_block(true, blkPos, blkOrient, destPortH, blkH, lineH);
        end
    end
    
    % Scrunch the outports to their source ports
    for idx = 1:numel(outPortHs)
        blkH = outPortHs(idx);
        [srcPortH, lineH] = src_portH(blkH);
        if (srcPortH>0)
            [blkPos, blkOrient] = compute_block_layout(srcPortH, false);
            scrunch_block(false, blkPos, blkOrient, srcPortH, blkH, lineH);
        end
    end
    
    function scrunch_block(isInput, blkPos, blkOrient, portH, blkH, lineH)
        set_param(blkH,     'Position',       blkPos, ...
                            'Orientation',    blkOrient, ...
                            'ShowName',       'off');
              
        ports = get_param(blkH, 'PortHandles');
        portPos = get_param(portH, 'Position');
        
        if (isInput)
            srcPos = get_param(ports.Outport(1), 'Position');
            linePoints = [srcPos;portPos];
        else
            destPos = get_param(ports.Inport(1), 'Position');
            linePoints = [portPos;destPos];
        end
        
        set_param(lineH,'Points',linePoints);
    end
end

function [outPortHs, inPortHs] = findAllPortBlocks(subsysH)
    outPortHs = find_system(subsysH,'SearchDepth',             1, ...
                                'FindAll',          'on', ...
                                'LookUnderMasks',   'off', ...
                                'BlockType',         'Outport');
    
    inPortHs = find_system(subsysH, 'SearchDepth',             1, ...
                                'FindAll',          'on', ...
                                'LookUnderMasks',   'off', ...
                                'BlockType',         'Inport');
end


function [portH, lineH] = dest_portH(blkH)
    ports = get_param(blkH, 'PortHandles');
    lineH = get_param(ports.Outport(1), 'Line');
    if lineH==-1
        portH = -1;
    else
        portH = get_param(lineH,'DstPortHandle');
        portH = portH(1);
    end
end

function [portH, lineH] = src_portH(blkH)
    ports = get_param(blkH, 'PortHandles');
    lineH = get_param(ports.Inport(1), 'Line');
    if lineH==-1
        portH = -1;
    else
        portH = get_param(lineH,'SrcPortHandle');
        portH = portH(1);
    end
end


function [blkPos, blkOrient] = compute_block_layout(portH, isInput)
    
    % Layout constants
    BlockWidth = 4;
    BlockHeight = 4;
    LineLength = 2;
    
    portPos = get_param(portH, 'Position');
    
    % Block should have the same orientation as the block being connected
    portBlock = get_param(portH,'Parent');
    blkOrient = get_param(portBlock,'Orientation');
    
    switch(blkOrient)
    case 'right'
        if isInput
            dir = 'L';
        else
            dir = 'R';
        end
    case 'left'
        if isInput
            dir = 'R';
        else
            dir = 'L';
        end
    case 'down'
        if isInput
            dir = 'U';
        else
            dir = 'D';
        end
    case 'up'
        if isInput
            dir = 'D';
        else
            dir = 'U';
        end
    end
    
    % BlkPos = [left top right bottom]
    % PortPos = [horz vert]
    if (dir=='L' || dir=='R')
        top = portPos(2) - BlockHeight/2;
        bottom = portPos(2) + BlockHeight/2;
        if dir=='L'
            right = portPos(1) - LineLength;
            left = right - BlockWidth;
        else
            left = portPos(1) + LineLength;
            right = left + BlockWidth;
        end
    else
        left = portPos(1) - BlockWidth/2;
        right = portPos(1) + BlockWidth/2;
        if dir=='U'
            bottom = portPos(2) - LineLength;
            top = bottom - BlockHeight;
        else
            top = portPos(2) + BlockHeight;
            bottom = top + BlockHeight;
        end
    end
    
    blkPos = [left top right bottom];
end
