function obj = subsasgn( obj, S, varargin )
%SUBSASGN Composite subsasgn method assigns remote values
%   C(I) = {B} sets the entry of C on lab I to the value B 
%   C(1:end) = {B} sets all entries of C to the value B
%   C([I1, I2]) = {B1, B2} assigns different values on labs I1 and I2
%   
%   C{I} = B sets the entry of C on lab I to the value B
    
% Copyright 2008-2015 The MathWorks, Inc.
    value = varargin{1};
    if isempty( obj )
        % First check - ensure we're not doing something like x(3) = C where x
        % doesn't currently exist
        error(message('parallel:lang:spmd:CompositeSubsasgnNoIdxCreate'));
    end
    
    if strcmp( S(1).type, '.' )
        error(message('parallel:lang:spmd:CompositeSubsasgnNoDotRef'));
    end
    
    % Composites do not support multiple levels of subscripting.
    if length( S ) ~= 1
        error(message('parallel:lang:spmd:CompositeSubsasgnOnlySimple'));
    end

    % Error early in the case where the pool is closed
    if ~obj.isResourceSetOpen()
        error(message('parallel:lang:spmd:CompositeSubsasgnInvalid'));
    end

    switch S.type
      case '()'
        % In this case, RHS must be either 1-element cell, or cell of the right
        % length to match the indices
        
        if ~iscell( value )
            error(message('parallel:lang:spmd:CompositeSubsasgnRHSCell'));
        end
        
        % Handle the [obj(:)] = {1} case - in this case, S.subs is {':'}
        labidxs = S.subs{1};
        if ischar( labidxs ) 
            if parallel.internal.indexing.isColonLiteral( labidxs )
                labidxs = 1:length( obj.KeyVector );
            else
                error(message('parallel:lang:spmd:CompositeSubsasgnUnhandledSubscript', labidxs));
            end
        end
        
        % Convert logicals to indices
        if islogical( labidxs )
            allIdxs = 1:length( obj );
            labidxs = allIdxs( labidxs );
        end

        % Check that we know the type of what we're dealing with
        if ~isnumeric( labidxs )
            error(message('parallel:lang:spmd:CompositeSubsasgnUnhandleSubsType', class( labidxs )));
        end
        
        gotCorrectNumValues = ( length( value ) == length( labidxs ) || ...
                                length( value ) == 1 );
        
        if gotCorrectNumValues
            try
                if length( value ) == length( labidxs )
                    for ii=1:length( labidxs )
                        obj = setValOrError( obj, labidxs(ii), value{ii} );
                    end
                elseif length( value ) == 1
                    for ii=1:length( labidxs )
                        obj = setValOrError( obj, labidxs(ii), value{1} );
                    end
                else
                    error(message('parallel:lang:spmd:CompositeSubsasgnUnexpectedRequest'));
                end
            catch E
                EE = MException(message('parallel:lang:spmd:CompositeSubsasgnInvalidRequest'));
                EE = addCause( EE, E );
                throw( EE );
            end
        else
            % mismatch
            error(message('parallel:lang:spmd:CompositeSubsasgnLengthMismatch', length( value ), length( labidxs )));
        end
        
      case '{}'
        % Apply the change
        try
            labidx = S.subs{1};
            if parallel.internal.indexing.isColonLiteral(labidx)
                labidx = 1:length( obj );
            end
            if numel( varargin ) < numel( labidx )
                error( message( 'MATLAB:needMoreRhsOutputs' ) );
            end
            for idx = 1:numel( labidx )
                obj = setValOrError( obj, labidx(idx), varargin{idx} );
            end
        catch E
            EE = MException(message('parallel:lang:spmd:CompositeSubsasgnInvalidRequest'));
            EE = addCause( EE, E );
            throw( EE );
        end
      otherwise
        % Never get here - '.' indexing already handled.
        error(message('parallel:lang:spmd:CompositeSubsasgnUnexpectedRequest'));
    end
end
