def convert(value, row):
    """CFED rules
       1. IF ORI_invalid flag = False: 
         
          a. Try to code CFED using ORI on crosswalk_ORI
          b. Try to code CFED using ORI[2:5] on crosswalk_ORI_POS_3-5
          c. Try to code CFED using ORI[7:9] on crosswalk_ORI_POS_8-9
          
       2. IF ORI_invalid flag = True:
          
          a. Try to code CFED using CRTNAME on crosswalk_CRTNAME
          b. Try to code CFED using CRTNAME on crosswalk_CRTNAME_EMBED

       3. If CFED is not coded after step 2:
          
          a. Recover data from arrest file. Match on first entry of CASENUM 
             AND CYCNUM, and bring back CFED=AFED.  
             
             If CSOURCE=1 and CSTATE=99 (UNKNOWN), also bring back 
             CSTATE = ASTATE
          
          b. If is not recovered at 4a (no matched case or matched case 
             with returning 9):
             
             i. If CSOURCE =2, code CFED=2.
             ii. If CSOURCE not equal 2 (or RAPSTATE=not a state), code CFED=9

        * All cases coded via 1b, 1c, 2b, 3a, or 3b should be reviewed 
          and ORIs added to crosswalk_1. Create a review table including 
          CORI, ARRNAME, and CFED for review and approval. Once approved, 
          add to crosswalk_1 and crosswalk_2, as appropriate.  
          Upgrade crosswalk_2 only if ORI is missing or not legitimate.
    """
    
    fed, astate, afed = None, None, None
    ori = key_as_str(row['cori'])
    crtname = key_as_str(row['crtnamex']) 
    csource = row['csource']
    
    c = 0

    #setup rule 1
    if not row['cori_invalid']:
        xwalk_list = [('ori', ori), ('ori_pos_3-5', ori[2:5]), ('ori_pos_8-9', ori[7:9])]  
    #setup rule 2
    else:
        xwalk_list =  [('crtname', crtname), ('crtname_embed', crtname)]
    
    #apply rule 1 and 2       
    for xwalk in xwalk_list:
        c += 1
        try:
            fed = crosswalk[xwalk[0]].convert(xwalk[1])
            break
        except ConvertError:
            continue 

    #rule 3    
    if not fed:
        cached = add_info.get('%s|%s' % (row['casenum'], row['cycnum']), (9,99))
        if cached:
            afed, astate = cached 
        if csource == 1 and row['cstate'] == 99:
            row['cstate'] = astate
        
        if not afed or afed == 9:
            fed = 2 if csource == 2 else 9    
        else:
            fed = afed
        
    #write log if fed coded by anything other than rule 1a or 2a
    if c > 1:
        if row['cori'] == '999999999':
            log.write('cfed_unknown', [row['id'], row['rapstatex'], row['cstate'], row['cori'], row['crtnamex'], fed], 1)
        else:
            log.write('cfed', [row['id'], row['rapstatex'], row['cstate'], row['cori'], row['crtnamex'], fed], 1)
    
    return fed