function [LP, codistr] = hBuildFromReplicatedImpl(codistr, srcWorker, X)
; %#ok<NOSEM> % Undocumented
% Implementation of method for codistributor2dbc.

%   Copyright 2009-2022 The MathWorks, Inc.

sizeX = size(X);
supported = distributedutil.Allocator.supportsCreation(X);
classX = class(X);

if srcWorker ~= 0
    % All workers other than srcWorker need to know what the size of X is
    % and whether we support its use. Broadcast both in one go to minimize
    % collective communication.
    data = spmdBroadcast(srcWorker, {size(X), supported, classX});
    [sizeX, supported, classX] = deal(data{:});
end

if ~supported
    error(message('parallel:codistributors:BuildUnsupportedClass', classX));
end

ndims = length(sizeX);
if ndims > 2
    error(message('parallel:codistributors:c2dbcUnsupportedNDim', ndims));
end

% We need to work with a completely specified codistributor with the correct
% global size.
codistr = codistr.hGetCompleteForSize(sizeX);

if srcWorker == 0
    rowInd = codistr.globalIndices(1, spmdIndex);
    colInd = codistr.globalIndices(2, spmdIndex);
    LP = X(rowInd, colInd);
else
    % Have srcWorker send the appropriate portions to the other workers.
    mwTag = 31683;
    if spmdIndex == srcWorker
        for destWorker = 1:spmdSize
            if destWorker ~= srcWorker
                rowInd = codistr.globalIndices(1, destWorker);
                colInd = codistr.globalIndices(2, destWorker);
                spmdSend(X(rowInd, colInd), destWorker, mwTag);
            end
        end
        % Retain the portion that corresponds to our local part.
        rowInd = codistr.globalIndices(1, spmdIndex);
        colInd = codistr.globalIndices(2, spmdIndex);
        LP = X(rowInd, colInd);
    else
        LP = spmdReceive(srcWorker, mwTag);
    end
end

LP = distributedutil.hEnsureComplexityMatches(LP, X);
end % End of hBuildFromReplicatedImpl.
