'2-dimensional pivoting of a list of unique items
@param items: list of unique items as dicts
@param pkey_colname: column name of the primary key
@param rows_colname: column name of the row dimension
@param cols_colname: column name of the column dimension
@return: tuple of (cell matrix, row headers, column headers),
where cell matrix is a 2-dimensional array [rows[columns]]
and row headers and column headers each are lists (in the
same order as the cell matrix)'

@staticmethod
def _pivot(items, pkey_colname, rows_colname, cols_colname):

    rvalues = Storage()
    cvalues = Storage()
    cells = Storage()
    rindex = 0
    cindex = 0
    for item in items:
        rvalue = (item[rows_colname] if rows_colname else None)
        cvalue = (item[cols_colname] if cols_colname else None)
        if (rvalue not in rvalues):
            r = rvalues[rvalue] = rindex
            rindex += 1
        else:
            r = rvalues[rvalue]
        if (cvalue not in cvalues):
            c = cvalues[cvalue] = cindex
            cindex += 1
        else:
            c = cvalues[cvalue]
        if ((r, c) not in cells):
            cells[(r, c)] = [item[pkey_colname]]
        else:
            cells[(r, c)].append(item[pkey_colname])
    matrix = []
    for r in xrange(len(rvalues)):
        row = []
        for c in xrange(len(cvalues)):
            row.append(cells[(r, c)])
        matrix.append(row)
    rnames = ([None] * len(rvalues))
    for (k, v) in rvalues.items():
        rnames[v] = k
    cnames = ([None] * len(cvalues))
    for (k, v) in cvalues.items():
        cnames[v] = k
    return (matrix, rnames, cnames)
