function [Z, prednames, XtoZ, groups, minmaxX] = br_expandvars(X, vars)

[n,px] = size(X);

% Create an empty predictor matrix
Z            = zeros(n, vars.pz);
prednames    = cell(1, vars.pz+1);
XtoZ         = zeros(1, vars.pz);
isvarexp     = false(1, vars.pz);
minmaxX      = NaN(2, vars.pz);

%% Create a predictor matrix from a data matrix
k = 1;
for j = 1:px
    %% If no expansion
    if (~vars.isVarCat(j))
        % Pass data straight through
        if (istable(X))
            Z(:,k) = X{:,j};
        else
            Z(:,k) = X(:,j);
        end
        
        minmaxX(:,j) = minmax(Z(:,k)');
        
        prednames{k} = vars.varnames{j};
        XtoZ(k) = j;            
        k = k+1;

    %% Otherwise, if categorical variable
    else
        if (length(vars.Categories{j}) > 2)
            isvarexp(j) = true;
        end
        
        % Expand into a number of columns equal to number of categories-1
        for i = 2:length(vars.Categories{j})
            if (istable(X))
                Z(X{:,j} == vars.Categories{j}{i}, k) = 1;
                prednames{k} = sprintf('%s.%s', vars.varnames{j}, vars.Categories{j}{i});
            else
                Z(X(:,j) == vars.Categories{j}(i),k) = 1;
                prednames{k} = sprintf('%s.%d', vars.varnames{j}, vars.Categories{j}(i));
            end
           
            XtoZ(k) = j;
            k = k+1;
        end
    end
end

%% Finally, if variables were expanded, all the expanded predictors associated with a variable should be grouped together
if (any(isvarexp))
    groups{1} = nan(1, vars.pz);
    Ix = find(isvarexp);
    
    % Assign predictors to associated variable groups
    g = 1;
    for i = Ix
        groups{1}(XtoZ == i) = g;
        g = g+1;
    end
else
    groups = cell(1,0);
end

%% Done
prednames{end} = '_cons';

return;