def addDerivedFeatures(allClinDict, auxName):

    print " "
    print " "
    print " in addDerivedFeatures ... "

    keyList = allClinDict.keys()
    keyList.sort()

    for aKey in keyList:

        if (aKey == "bcr_patient_barcode"):
            continue
        (keyType, nCount, nNA, nCard, labelList, labelCount) = miscClin.lookAtKey(allClinDict[aKey])
        print " considering key <%s> " % (aKey), keyType, nCard

        if (keyType == "NOMINAL"):
            if (nCard > 2 and nCard < 25):

                tmpKey = aKey.lower()

                tmpList = []
                for aLabel in labelList:
                    tmpL = str(aLabel)
                    if (tmpL not in tmpList):
                        tmpList += [tmpL]
                labelList = tmpList

                if (1):
                    print " considering this categorical feature ... ", aKey, keyType, nCard, labelList, labelCount

                    (mapDict, newNames) = getMappingDict(aKey, auxName)

                    # if there is no mapping file, then we won't be making any
                    # new features ...
                    if (len(newNames) == 0):
                        continue

                    # sanity check ...
                    if (0):
                        for bKey in mapDict.keys():
                            if ( stringInList_CaseInsens ( bKey, labelList ) ):
                                print " ERROR ??? mapping does not match this feature ??? "
                                print mapDict
                                print labelList
                                sys.exit(-1)
                    if (1):
                        for bLabel in labelList:
                            try:
                                if ( not stringInList_CaseInsens ( bLabel, mapDict.keys() ) ):
                                    print " ************************************************** "
                                    print " ERROR ??? feature value not in mapDict ??? ", bLabel
                                    print " labelList : ", labelList
                                    print " mapDict   : ", mapDict
                                    print " --> WILL NOT ADD ANY DERIVED FEATURES AT THIS TIME "
                                    print " ************************************************** "
                                    continue
                                    # sys.exit(-1)
                            except:
                                doNothing = 1

                    # if there is no mapping file, then we won't be making any
                    # new features ...
                    if (len(newNames) == 0):
                        continue

                    # but if we do have one or more mappings, then we need
                    # to create those features ...
                    for ithName in range(len(newNames)):
                        aName = newNames[ithName]
                        print " looping over %d mappings ... " % len(newNames), ithName, aName

                        # the first thing we need to figure out is whether this is another
                        # categorical feature, or a numerical one ...
                        isNum = 1
                        uVec = []
                        for bKey in mapDict.keys():
                            curVal = mapDict[bKey][ithName]
                            if (curVal == "NA"):
                                continue
                            if ( stringInList_CaseInsens ( curVal, uVec ) ):
                                uVec += [curVal]
                            try:
                                fVal = float(curVal)
                            except:
                                isNum = 0

                        print " is numerical ??? ", isNum
                        if (len(uVec) == 1):
                            print " mapping to a constant ??? "
                            sys.exit(-1)
                        elif (len(uVec) == 2):
                            print " mapping is binary "
                            # if the mapping produces a binary feature, then
                            # over-ride the numerical feature
                            if (isNum):
                                print " over-riding the fact that the features LOOKS numerical ... "
                                isNum = 0

                        if (aName[1] == ":"):
                            if (aName[0] == "N"):
                                if (not isNum):
                                    print " ERROR ??? new feature does not look to be numerical ???? "
                                    print aName, uVec
                                    sys.exit(-1)

                        # start setting up the new feature ...
                        newLabel = aName
                        if (newLabel in allClinDict.keys()):
                            print " this feature label already exists ??? ", newLabel
                            sys.exit(-1)

                        curV = allClinDict[aKey]
                        numClin = len(curV)
                        tmpV = [0] * numClin

                        for kk in range(numClin):
                            if (curV[kk].upper() == "NA"):
                                tmpV[kk] = "NA"
                            else:
                                try:
                                    tmpV[kk] = getMapping ( mapDict, curV[kk], ithName )
                                    ## tmpV[kk] = mapDict[curV[kk]][ithName]
                                except:
                                    print " ERROR ??? failed to map ??? setting to NA but MUST FIX !!! "
                                    print kk, curV[kk], ithName
                                    print mapDict
                                    if (1):
                                        tmpV[kk] = "NA"
                                    else:
                                        sys.exit(-1)

                        numNA = 0
                        notNA = 0
                        for kk in range(numClin):
                            if (tmpV[kk] == "NA"):
                                numNA += 1
                            else:
                                notNA += 1

                        if (numNA > 10 * notNA):
                            print " --> NOT adding this new feature <%s> " % newLabel, list(set(tmpV)), numNA, notNA
                        else:
                            print " --> ADDING new feature !!! <%s> " % newLabel, list(set(tmpV)), numNA, notNA
                            allClinDict[newLabel] = tmpV

                    print " "

    print " "
    print " "
    print " RETURNING from addDerivedFeatures ... "

    return (allClinDict)