def getFeatureString(ff, e1, e2, morecs, csignal_para_dict):
    feature_str = ""
    (eidx1, tid1, _, eclass1, _, _) = ff.entities[e1]
    (eidx2, tid2, _, eclass2, _, _) = ff.entities[e2]
    (token1, sentid1, lemma1, pos1, mainvb1, entity1, chunk1, conn1, mainpos1, tense1, aspect1, pol1, supersense1) = ff.tokens[tid1]
    (token2, sentid2, lemma2, pos2, mainvb2, entity2, chunk2, conn2, mainpos2, tense2, aspect2, pol2, supersense2) = ff.tokens[tid2]
    (pos_path1, pos_pol1) = ff.getPOSPath(tid1) #get POS path (for verb, noun and adj are based on dependent verb) and polarity from POS
    (pos_path2, pos_pol2) = ff.getPOSPath(tid2) #get POS path (for verb, noun and adj are based on dependent verb) and polarity from POS
    
    (sent_distance, ent_distance, ent_order) = ff.getDistance(sentid1, sentid2, eidx1, eidx2) 
    if ent_order == "reverse":
        (dep_rel, dep_order) = ff.getDependency(tid2, tid1)
        (dep_path, path_order) = ff.getDependencyPath(tid2, tid1)
    else:
        (dep_rel, dep_order) = ff.getDependency(tid1, tid2)
        (dep_path, path_order) = ff.getDependencyPath(tid1, tid2)
    samePOS = (pos1 == pos2)
    sameClass = (eclass1 == eclass2)
    sameTense = (tense1 == tense2)
    sameAspect = (aspect1 == aspect2)
    samePol = (pol1 == pol2) 
    
    #(marker, marker_position, dep_mark_e1, dep_mark_e2) = (["O"],"O","O","O")
    (marker, marker_position, dep_mark_e1, dep_mark_e2) = ([],"O","O","O")
    if ent_order == "reverse": (causal_signal, causal_signal_pos, dep_signal_e1, dep_signal_e2) = ff.getCausalSignal(e2, e1)
    else: (causal_signal, causal_signal_pos, dep_signal_e1, dep_signal_e2) = ff.getCausalSignal(e1, e2)
    if causal_signal != "O":
        causal_signals = []
        if morecs and ((e1, e2) in ff.clink or (e2, e1) in ff.clink):
            for cs in __getParaphraseCausalSignal(causal_signal, csignal_para_dict):
                causal_signals.append(cs)
        causal_signals.append(causal_signal)
            
        (marker, marker_position, dep_mark_e1, dep_mark_e2) = (causal_signals, causal_signal_pos, dep_signal_e1, dep_signal_e2)
        
    else:
        if ent_order == "reverse": (causal_conn, causal_conn_pos, dep_conn_e1, dep_conn_e2) = ff.getCausalConnective(e2, e1)
        else: (causal_conn, causal_conn_pos, dep_conn_e1, dep_conn_e2) = ff.getCausalConnective(e1, e2)
        if causal_conn != "O":
            causal_conns = []
            causal_conns.append(causal_conn)
            (marker, marker_position, dep_mark_e1, dep_mark_e2) = (causal_conns, causal_conn_pos, dep_conn_e1, dep_conn_e2)
        else:
            if ent_order == "reverse": (causal_verb, dep_e1, dep_e2) = ff.getCausativeVerb(e2, e1)
            else: (causal_verb, dep_e1, dep_e2) = ff.getCausativeVerb(e1, e2)
            if causal_verb != "O":
                causal_verbs = []
                causal_verbs.append(causal_verb)
                (marker, marker_position, dep_mark_e1, dep_mark_e2) = (causal_verbs, "BETWEEN", dep_e1, dep_e2)
                
            
    (csignal_e1, csignal_pos_e1) = ff.getCSignalDependency(e1)
    (csignal_e2, csignal_pos_e2) = ff.getCSignalDependency(e2)
    (cverb_e1, cverb_pos_e1) = ff.getCVerbDependency(e1)
    (cverb_e2, cverb_pos_e2) = ff.getCVerbDependency(e2)
                
    coref = "O"
    if (e1, e2) in ff.coref_events or (e2, e1) in ff.coref_events: coref = "COREF"

    tlink = "O"
    if ent_order == "reverse":
        if (e2, e1) in ff.tlink and ff.tlink[(e2, e1)] != "NONE": tlink = ff.tlink[(e2, e1)]
        elif (e1, e2) in ff.tlink and ff.tlink[(e1, e2)] != "NONE": tlink = ff.getInverseRelation(ff.tlink[(e1, e2)])
        else: tlink = "O"
    else:
        if (e1, e2) in ff.tlink and ff.tlink[(e1, e2)] != "NONE": tlink = ff.tlink[(e1, e2)]
        elif (e2, e1) in ff.tlink and ff.tlink[(e2, e1)] != "NONE": tlink = ff.getInverseRelation(ff.tlink[(e2, e1)])
        else: tlink = "O"
    
    conceptnet = "O"
    #if ent_order == "reverse":
    #    conceptnet = __getConceptRel(lemma2, lemma1)
    #else:
    #    conceptnet = __getConceptRel(lemma1, lemma2)

    pair_str = ""

    feature_strings = ""
    
    for m in marker:
        feature_str = ""
        if ent_order == "reverse":
            feature_str += "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" % \
                (e2, e1, token2, token1, lemma2, lemma1, mainpos2+"-"+mainpos1, chunk2+"-"+chunk1, sent_distance, ent_distance, conceptnet, dep_rel, dep_order, dep_path, path_order, str(mainvb2)+"-"+str(mainvb1), eclass2+"-"+eclass1, tense2+"-"+tense1, aspect2+"-"+aspect1, pol2+"-"+pol1, samePOS, sameClass, sameTense, sameAspect, samePol, pos_path2+"-"+pos_path1, pos_pol2+"-"+pos_pol1, m, marker_position, dep_mark_e1, dep_mark_e2, csignal_e2, csignal_pos_e2, csignal_e1, csignal_pos_e1, cverb_e2, cverb_pos_e2, cverb_e1, cverb_pos_e1, tlink, coref, supersense2, supersense1, entity2, entity1)
        else:
            feature_str += "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" % \
                (e1, e2, token1, token2, lemma1, lemma2, mainpos1+"-"+mainpos2, chunk1+"-"+chunk2, sent_distance, ent_distance, conceptnet, dep_rel, dep_order, dep_path, path_order, str(mainvb1)+"-"+str(mainvb2), eclass1+"-"+eclass2, tense1+"-"+tense2, aspect1+"-"+aspect2, pol1+"-"+pol2, samePOS, sameClass, sameTense, sameAspect, samePol, pos_path1+"-"+pos_path2, pos_pol1+"-"+pos_pol2, m, marker_position, dep_mark_e1, dep_mark_e2, csignal_e1, csignal_pos_e1, csignal_e2, csignal_pos_e2, cverb_e1, cverb_pos_e1, cverb_e2, cverb_pos_e2, tlink, coref, supersense1, supersense2, entity1, entity2)

        #clink
        clink = "O"
        if ent_order == "reverse":
            if (e2, e1) in ff.clink: clink = "CLINK"
            elif (e1, e2) in ff.clink: clink = "CLINK-R"
            else: clink = "O"
        else:
            if (e1, e2) in ff.clink: clink = "CLINK"
            elif (e2, e1) in ff.clink: clink = "CLINK-R"
            else: clink = "O"

        feature_strings += feature_str + "\t" + clink + "\n"

    return feature_strings