bool variesIn(string id, Model* model,  const map<string, vector<double> >& results)
{
  if (variesIn(id, results)) return true;
  Rule* rule = model->getRule(id);
  if (rule != NULL) {
    if (rule->getTypeCode() == SBML_RATE_RULE) return true;
    return variesIn(rule->getMath(), model, results);
  }
  if (!getConstant(id, model, results)) {
    //The variable might be set by an algebraic rule
    for (unsigned long r=0; r<model->getNumRules(); r++) {
      if (model->getRule(r)->getTypeCode() == SBML_ALGEBRAIC_RULE) {
        if (appearsIn(id, model->getRule(r)->getMath()) &&
            variesBesides(id, model->getRule(r)->getMath(), model, results)) return true;
      }
    }
  }
  for (unsigned long e=0; e<model->getNumEvents(); e++) {
    Event* event = model->getEvent(e);
    for (unsigned long ea=0; ea<event->getNumEventAssignments(); ea++) {
      if (event->getEventAssignment(ea)->getVariable() == id) return true;
    }
  }
  Species* species = model->getSpecies(id);
  if (species==NULL) return false;
  if (species->isSetBoundaryCondition() && species->getBoundaryCondition()==true) return false;
  for (unsigned long r=0; r<model->getNumReactions(); r++) {
    Reaction* rxn = model->getReaction(r);
    if (variesIn(id, rxn->getListOfReactants(), results)) return true;
    if (variesIn(id, rxn->getListOfProducts(), results)) return true;
  }
  return false;
}
void checkSpecies(Model* model, set<string>& components, set<string>& tests,  const map<string, vector<double> >& results, int type)
{
  //Must call this after 'checkCompartments' because we look in 'tests' for 'NonUnityCompartment'.
  if (model->getNumSpecies() > 0) {
    components.insert("Species");
    if (type==0) {
      tests.insert("Amount||Concentration");
    }
    else if (type==2) {
      tests.insert("Amount");
    }
	set<string> compartments;
    for (unsigned int s=0; s<model->getNumSpecies(); s++) {
      Species* species = model->getSpecies(s);
      if (species->isSetBoundaryCondition() && species->getBoundaryCondition()) {
        tests.insert("BoundaryCondition");
      }
      if (species->getConstant()) {
        tests.insert("ConstantSpecies");
      }
      if (species->isSetConversionFactor()) {
        tests.insert("ConversionFactors");
      }
      if (species->isSetHasOnlySubstanceUnits() && species->getHasOnlySubstanceUnits()) {
        tests.insert("HasOnlySubstanceUnits");
      }
      if (!species->isSetInitialAmount() && !species->isSetInitialConcentration()) {
        tests.insert("InitialValueReassigned");
      }
      else if (species->isSetId() && initialOverriddenIn(species->getId(), model, results, tests)) {
        tests.insert("InitialValueReassigned");
      }
      if (species->isSetCompartment()) {
        compartments.insert(species->getCompartment());
      }
    }
    if (tests.find("MultiCompartment") != tests.end() && compartments.size()==1 && model->getNumSpecies() > 1) {
      cerr << "Error:  multiple compartments discovered, but all species are in a single compartment." << endl;
      tests.insert("ERRORMultiCompartment");
    }
  }
}