function [LP, codistr] = hCell2StructImpl(codistr, LP, fields, dim) 
    ; %#ok<NOSEM> % Undocumented

    %   hCell2StructImpl Implementation of cell2struct for codistributor2dbc

    %   Copyright 2012-2022 The MathWorks, Inc.

    blockSize = codistr.BlockSize;
    gsize = codistr.Cached.GlobalSize;
    grid = codistr.WorkerGrid;
    gridOrient = codistr.Orientation;

    if blockSize < numel(fields)
        blockSize = numel(fields);
        destCodistr = codistributor2dbc(grid, blockSize, gridOrient, gsize);
        [LP, codistr] = distributedutil.Redistributor.redistribute(codistr, LP, destCodistr);
    end

    gsize(dim) = 1;
    codistr = codistr.hGetNewForSize(gsize);
    if dim == 1
        codistr = codistr.pTransposeCodistributor();
    end
    LP = codistr.hCell2StructBuildLPImpl(LP, fields, dim);

    
    % MATLAB cell2struct always converts an N x M cell array into N x 1 or M x 1
    % struct array. However, this does not quite match the behavior we get when
    % building across dim = 1, when the matrix M dimension is greater then N. In
    % this case we end up with several M/spmdSize, 1 vectors, across the top row
    % of workers, which is equivalent to [M/spmdSize, spmdSize] matrix. To get the
    % expected [M, 1] output vector we have to perform a transpose on the local
    % part, and then global transpose across the worker grid.
    %
    % Example below:
    %
    % Consider 2 by 2 block size for 4 by 8 matrix on 2 by 2 worker grid, 
    % with cell2struct called with dim = 1
    %
    %   W 1   W 2   W 1   W 2
    % | 1 1 | 1 1 | 1 1 | 1 1 |
    % | 2 2 | 2 2 | 2 2 | 2 2 |
    % -------------------------
    %   W 3   W 4   W 3   W 4
    % | 3 3 | 3 3 | 3 3 | 3 3 |
    % | 4 4 | 4 4 | 4 4 | 4 4 |
    %
    % After first redistribution we will have blockSize of 4 and the following data
    %
    %     W 1       W 2
    % | 1 1 1 1 | 1 1 1 1 |
    % | 2 2 2 2 | 2 2 2 2 |
    % | 3 3 3 3 | 3 3 3 3 |
    % | 4 4 4 4 | 4 4 4 4 |
    % -------------------------
    %     W 3       W 4
    % | [0 x 4] | [0 x 4] |
    %
    % Next we perform two actions:
    % 1) Transpose the codistributor
    % 2) Create appropriate local parts.
    %
    % 2a) On workers that contain non-empty local parts we apply cell2struct.
    %
    % After converting cells to structures along the build dimension dim
    % our data on workers that contain non empty local parts will look like
    % the image below. The dimensions of resulting local parts match what 
    % is expected by the new codistributor.
    % 
    %   W 1       W 3  
    % | s       | s       |  <- Each array of structures if 4 x 1 . With the transposed codistributor 
    % | s       | s       |     the global size is 8 x 1. (Without transposing the codistributor 
    % | s       | s       |  <- the full global size is 4 x 2
    % | s       | s       |     but we were expecting 1 x 8. Cannot build an 1 x 8 out of this distribution
    % -------------             without some changes)
    %   W 2       W 4   
    % | [????] | [????]  | <- Cell2Struct is not applied to empty LocalParts
    %
    % 2b) On workers that contain empty local parts, the Cell2Struct
    % operation is not applied to the empty local parts. 
    %
    % Instead, to ensure that the output matches expected MATLAB output, we construct the empty local 
    % parts to match the dimensions expected by the transposed codistributor.
    %
    % After the codistributor transpose and build operation we get the expected result.
    %   W 1   W 3  
    % | s   | [4 x 0] |
    % | s   |         |
    % | s   |         |  
    % | s   |         |  
    % -------------  
    %   W 2   W 4   
    % | s  | [4 x 0 ] | 
    % | s  |          | 
    % | s  |          | 
    % | s  |          | 

end
