def processFile(translator, parser, outputFile):
    param2 = parser.getParameters()
    molecules, species, observables, observablesDict = parser.getSpecies(translator)
    compartments = parser.getCompartments()
    param, rules, functions = parser.getReactions(translator, True)
    param += param2
    writer.finalText(param, molecules, species, observables, rules,
                     functions, compartments, {}, outputFile)
def analyzeHelper(document, reactionDefinitions, useID, outputFile, speciesEquivalence, atomize, translator, database, bioGrid=False):
    '''
    taking the atomized dictionary and a series of data structure, this method
    does the actual string output.
    '''

    useArtificialRules = False
    parser = SBML2BNGL(document.getModel(), useID)
    parser.setConversion(database.isConversion)
    #database = structures.Databases()
    #database.assumptions = defaultdict(set)
    #translator,log,rdf = m2c.transformMolecules(parser,database,reactionDefinitions,speciesEquivalence)
        
    #try:
    #bioGridDict = {}
    #if biogrid:
    #    bioGridDict = biogrid()
    #if atomize:
    #    translator = mc.transformMolecules(parser,database,reactionDefinitions,speciesEquivalence,bioGridDict)
    #else:
    #    translator={}
    
    #except:
    #    print 'failure'
    #    return None,None,None,None
    
    #translator = {}
    param,zparam = parser.getParameters()
    rawSpecies = {}
    for species in parser.model.getListOfSpecies():
            rawtemp = parser.getRawSpecies(species,[x.split(' ')[0] for x in param])
            rawSpecies[rawtemp['identifier']] = rawtemp
    parser.reset()

    molecules, initialConditions, observables, speciesDict,\
        observablesDict, annotationInfo = parser.getSpecies(translator, [x.split(' ')[0] for x in param])

    # finally, adjust parameters and initial concentrations according to whatever  initialassignments say
    param, zparam, initialConditions = parser.getInitialAssignments(translator, param, zparam, molecules, initialConditions)

    # FIXME: this method is a mess, improve handling of assignmentrules since we can actually handle those
    aParameters, aRules, nonzparam, artificialRules, removeParams, artificialObservables = parser.getAssignmentRules(zparam, param, rawSpecies, 
                                                                                                                     observablesDict, translator)

    compartments = parser.getCompartments()
    functions = []
    assigmentRuleDefinedParameters = []

    reactionParameters, rules, rateFunctions = parser.getReactions(translator, len(compartments) > 1,
                                                                   atomize=atomize, parameterFunctions=artificialObservables, database=database)

    functions.extend(rateFunctions)

    for element in nonzparam:
        param.append('{0} 0'.format(element))
    param = [x for x in param if x not in removeParams]


    tags = '@{0}'.format(compartments[0].split(' ')[0]) if len(compartments) == 1 else '@cell'
    molecules.extend([x.split(' ')[0] for x in removeParams])

    if len(molecules) == 0:
        compartments = []
    observables.extend('Species {0} {0}'.format(x.split(' ')[0]) for x in removeParams)
    for x in removeParams:
        initialConditions.append(x.split(' ')[0] + tags + ' ' + ' '.join(x.split(' ')[1:]))

    ## Comment out those parameters that are defined with assignment rules
    ## TODO: I think this is correct, but it may need to be checked
    tmpParams = []

    for idx, parameter in enumerate(param):
        for key in artificialObservables:
            
            if re.search('^{0}\s'.format(key),parameter)!= None:
                assigmentRuleDefinedParameters.append(idx)
    tmpParams.extend(artificialObservables)
    tmpParams.extend(removeParams)
    tmpParams = set(tmpParams)
    correctRulesWithParenthesis(rules,tmpParams)

    for element in assigmentRuleDefinedParameters:
        param[element] = '#' + param[element]
    
    deleteMolecules = []
    deleteMoleculesFlag = True 

    for key in artificialObservables:
        flag = -1
        for idx,observable in enumerate(observables):
            if 'Species {0} {0}()'.format(key) in observable:
                flag = idx
        if flag != -1:
            observables.pop(flag)
        functions.append(artificialObservables[key])
        flag = -1
        
        if '{0}()'.format(key) in molecules:
            flag = molecules.index('{0}()'.format(key))
        
        if flag != -1:
            if deleteMoleculesFlag:
                deleteMolecules.append(flag)
            else:
                deleteMolecules.append(key)
            #result =validateReactionUsage(molecules[flag],rules)
            #if result != None:
            #    logMess('ERROR','Pseudo observable {0} in reaction {1}'.format(molecules[flag],result))
            #molecules.pop(flag)
            
        flag = -1
        for idx,specie in enumerate(initialConditions):
            if ':{0}('.format(key) in specie:
                flag = idx
        if flag != -1:
            initialConditions[flag] = '#' + initialConditions[flag]

    for flag in sorted(deleteMolecules,reverse=True):
        
        if deleteMoleculesFlag:
            logMess('WARNING:SIM101','{0} reported as function, but usage is ambiguous'.format(molecules[flag]) )
            result = validateReactionUsage(molecules[flag], rules)
            if result is not None:
                logMess('ERROR:Simulation','Pseudo observable {0} in reaction {1}'.format(molecules[flag],result))

            #since we are considering it an observable delete it from the molecule and
            #initial conditions list
            #s = molecules.pop(flag)
            #initialConditions = [x for x in initialConditions if '$' + s not in x]
        else:
            logMess('WARNING:SIM101','{0} reported as species, but usage is ambiguous.'.format(flag) )
            artificialObservables.pop(flag)
            
    sbmlfunctions = parser.getSBMLFunctions()

    functions.extend(aRules)
    #print functions

    processFunctions(functions,sbmlfunctions,artificialObservables,rateFunctions)
    for interation in range(0,3):
        for sbml2 in sbmlfunctions:
            for sbml in sbmlfunctions:
                if sbml == sbml2:
                    continue
                if sbml in sbmlfunctions[sbml2]:
                    sbmlfunctions[sbml2] = writer.extendFunction(sbmlfunctions[sbml2],sbml,sbmlfunctions[sbml])

    functions = reorderFunctions(functions)


    functions = changeNames(functions, aParameters)
    # change reference for observables with compartment name
    functions = changeNames(functions, observablesDict)
#     print [x for x in functions if 'functionRate60' in x]

    functions = unrollFunctions(functions)
    rules = changeRates(rules, aParameters)
    if len(compartments) > 1 and 'cell 3 1.0' not in compartments:
        compartments.append('cell 3 1.0')

    #sbml always has the 'cell' default compartment, even when it
    #doesn't declare it
    elif len(compartments) == 0 and len(molecules) != 0:
        compartments.append('cell 3 1.0')
    
    
    if len(artificialRules) + len(rules) == 0:
        logMess('ERROR:SIM203','The file contains no reactions')
    if useArtificialRules or len(rules) == 0:
        rules =['#{0}'.format(x) for x in rules]
        evaluate =  evaluation(len(observables),translator)

        artificialRules.extend(rules)
        rules = artificialRules
        


    else:
        artificialRules =['#{0}'.format(x) for x in artificialRules]
        evaluate =  evaluation(len(observables),translator)

        rules.extend(artificialRules)
    commentDictionary = {}
    
    if atomize:
        commentDictionary['notes'] = "'This is an atomized translation of an SBML model created on {0}.".format(time.strftime("%d/%m/%Y"))
    else:
        commentDictionary['notes'] = "'This is a plain translation of an SBML model created on {0}.".format(time.strftime("%d/%m/%Y"))
    commentDictionary['notes'] += " The original model has {0} molecules and {1} reactions. The translated model has {2} molecules and {3} rules'".format(parser.model.getNumSpecies(),parser.model.getNumReactions(),len(molecules),len(set(rules)))
    meta = parser.getMetaInformation(commentDictionary)

    

    finalString = writer.finalText(meta, param + reactionParameters, molecules, initialConditions, 
                                   list(OrderedDict.fromkeys(observables)), list(OrderedDict.fromkeys(rules)), functions, compartments,
                                   annotationInfo, outputFile)
    
    logMess('INFO:SUM001','File contains {0} molecules out of {1} original SBML species'.format(len(molecules), len(observables)))

    # rate of each classified rule
    evaluate2 = 0 if len(observables) == 0 else len(molecules)*1.0/len(observables)

    # add unit information to annotations

    annotationInfo['units'] = parser.getUnitDefinitions()
    return AnalysisResults(len(rules), len(observables), evaluate, evaluate2, len(compartments),
                           parser.getSpeciesAnnotation(), finalString, speciesDict, None, annotationInfo)

    '''