# File lib/columnize.rb, line 56
  def columnize(list, displaywidth=80, colsep = '  ', 
                arrange_vertical=true, ljust=true, lineprefix='')

    # Some degenerate cases
    if not list.is_a?(Array)
      return ''
    end
    if list.size == 0
      return  "<empty>\n"
    end
    l = list.map{|li| li.to_s}
    if 1 == l.size
      return "#{l[0]}\n"
    end

    nrows = ncols = 0  # Make nrows, ncols have more global scope
    colwidths = []     # Same for colwidths
    displaywidth = [4, displaywidth - lineprefix.length].max
    if arrange_vertical
      array_index = lambda {|nrows, row, col| nrows*col + row }
      # Try every row count from 1 upwards
      1.upto(l.size-1) do |_nrows|
        nrows = _nrows
        ncols = (l.size + nrows-1) / nrows
        colwidths = []
        totwidth = -colsep.length

        0.upto(ncols-1) do |_col|
          col = _col
          # get max column width for this column
          colwidth = 0
          0.upto(nrows-1) do |_row|
            row = _row
            i = array_index.call(nrows, row, col)
            if i >= l.size
              break
            end
            colwidth = [colwidth, l[i].size].max
          end
          colwidths << colwidth
          totwidth += colwidth + colsep.length
          if totwidth > displaywidth
            ncols = col
            break
          end
        end
        if totwidth <= displaywidth
          break
        end
      end
      # The smallest number of rows computed and the
      # max widths for each column has been obtained.
      # Now we just have to format each of the
      # rows.
      s = ''
      0.upto(nrows-1) do |_row| 
        row = _row
        texts = []
        0.upto(ncols-1) do |_col|
          col = _col
          i = array_index.call(nrows, row, col)
          if i >= l.size
            x = ""
          else
            x = l[i]
          end
          texts << x
        end
        while texts and texts[-1] == ''
          texts = texts[0..-2]
        end
        if texts.size > 0
          0.upto(texts.size-1) do |_col|
            col = _col
            if ljust
                texts[col] = texts[col].ljust(colwidths[col])
            else
                texts[col] = texts[col].rjust(colwidths[col])
            end
          end
          s += "%s%s\n" % [lineprefix, texts.join(colsep)]
        end
      end
      return s
    else
      array_index = lambda {|nrows, row, col| ncols*(row-1) + col }
      # Try every column count from size downwards
      # Assign to make enlarge scope of loop variables 
      totwidth = i = rounded_size = 0  
      l.size.downto(0) do |_ncols|
        ncols = _ncols
        # Try every row count from 1 upwards
        min_rows = (l.size+ncols-1) / ncols
        min_rows.upto(l.size) do |_nrows|
          nrows = _nrows
          rounded_size = nrows * ncols
          colwidths = []
          totwidth = -colsep.length
          colwidth = row = 0
          0.upto(ncols-1) do |_col|
            col = _col
            # get max column width for this column
            1.upto(nrows) do |_row|
              row = _row
              i = array_index.call(nrows, row, col)
              if i >= rounded_size 
                break
              elsif i < l.size
                colwidth = [colwidth, l[i].size].max
              end
            end
            colwidths << colwidth
            totwidth += colwidth + colsep.length
            if totwidth > displaywidth
              break
            end
          end
          if totwidth <= displaywidth
            # Found the right nrows and ncols
            nrows  = row
            break
          elsif totwidth >= displaywidth
            # Need to reduce ncols
            break
          end
        end
        if totwidth <= displaywidth and i >= rounded_size-1
            break
        end
      end
      # The smallest number of rows computed and the
      # max widths for each column has been obtained.
      # Now we just have to format each of the
      # rows.
      s = ''
      1.upto(nrows) do |row| 
        texts = []
        0.upto(ncols-1) do |col|
          i = array_index.call(nrows, row, col)
          if i >= l.size
            break
          else
            x = l[i]
          end
          texts << x
        end
        0.upto(texts.size-1) do |col|
          if ljust
            texts[col] = texts[col].ljust(colwidths[col])
          else
            texts[col] = texts[col].rjust(colwidths[col])
          end
        end
        s += "%s%s\n" % [lineprefix, texts.join(colsep)]
      end
      return s
    end
  end