function cmds = sortCmds(cmds)

% SORTCMDS sort a command list so that all inputs and outputs are valid.
% 
% M Hewitson 27-03-07
% 

disp('   + sorting command list');

nswapped = 1;
while nswapped > 0

  nswapped = 0;
  % first assign numbers
  for j=1:length(cmds)
    cmds(j).n = j;
  end

  nc = length(cmds);
  for j=1:nc
    
    cmd = cmds(j);
    % if I have inputs, find the commands
    % that come before me
    cs = [];
    if ~isempty(cmd.ins)
      % go through my inputs
      for i=1:length(cmd.ins)
        input = cmd.ins{i};
        % check against all commands
        for k=1:nc
          outputs = cmds(k).outs;
          for o=1:length(outputs)
            if strcmp(outputs{o}, input)
              cs = [cs k];
            end
          end
        end
      end
    end
    
    % go through these
    for k=1:length(cs)
      csj  = cs(k);
      cmdn = j;

      if csj > cmdn
%         disp(sprintf('** swapping %d and %d', csj, cmdn))
        nswapped = nswapped + 1;
        c1 = cmds(csj);
        c2 = cmds(cmdn);
        % swap
        cmds(cmdn) = c1;
        cmds(csj)  = c2;
      end
    end
    
  end
  
  % they should be sorted now so renumber
  for j=1:length(cmds)
    cmds(j).n = j;
  end

end

% DON'T NEED THIS

% now remove unnecessary commands
% - find all commands whose output is not an input
useful = [];
newcmds = [];
for k=1:length(cmds)
  
  cmd = cmds(k);
  outs = cmd.outs;
  
  % go through each of my outputs
  hasUse = 0;
  for j=1:length(outs)
    out = char(outs{j});
    % check against all other inputs
    for i=k+1:length(cmds)
      ccmd = cmds(i);
      ins = ccmd.ins;
      for a=1:length(ins)
        in = char(ins(a));
%         disp(sprintf('------- checking out(%s) against in(%s) ', out,
%         in))
        if strcmp(out, in)
          hasUse = 1;
        end
      end
    end
  end
  % All sinks fail this test but we don't want to discard them. In fact, we
  % only want to discard lines that have an output and this output is not
  % used.
  if isempty(outs)
    hasUse = 1;
  end
    
%   if hasUse
    newcmds = [newcmds cmd];
%   else
%     disp(sprintf('## Discarding %s', cmd.cmd))
%   end
%   
end

% now we have a slightly reduced list. The next step of cleaning up should
% come in the fncs that run and write m files.
cmds = newcmds;


% END