// simple callback enabling packages on main doc
int EnablePackageOnParentDocument(Model* m, SBMLErrorLog *, void* userdata)
{
  if (m == NULL) return LIBSBML_OPERATION_FAILED;

  // pull information out of userdata
  disable_info * info = static_cast<disable_info*>(userdata);
  
  SBMLDocument *mainDoc = static_cast<SBMLDocument*>(info->doc);
  std::set<std::pair<std::string, std::string> > disabled = 
    static_cast<std::set <std::pair <std::string, std::string> > >(info->disabledPkgs);


  if (mainDoc == NULL) return LIBSBML_OPERATION_FAILED;

  XMLNamespaces *mainNS = mainDoc->getSBMLNamespaces()->getNamespaces();

  XMLNamespaces *ns = m->getSBMLNamespaces()->getNamespaces();
  for (int i = 0; i < ns->getLength(); i++)
  {
    std::string nsURI = ns->getURI(i);
    std::string prefix = ns->getPrefix(i);
    if (prefix.empty() == true)
    {
      continue;
    }
    else if (mainNS->containsUri(nsURI) == false)
    {
      bool alreadyDisabled = false;
      for (set<pair<string, string> >::iterator pkg = disabled.begin();
           pkg != disabled.end(); pkg++)
      {
        if ((*pkg).first == nsURI)
        {
          alreadyDisabled = true;
          break;
        }
      }
      // just in case
      if (m->getSBMLDocument() == NULL)
      {
        continue;
      }
      if (m->isPackageEnabled(prefix) == true)
      {
        mainNS->add(nsURI, prefix);
        mainDoc->enablePackage(nsURI, prefix, true);
        mainDoc->setPackageRequired(prefix, 
          m->getSBMLDocument()->getPackageRequired(prefix));
        

        // we also need to make sure that if m was a modelDefinition
        // that we enable the package on its parent model
        Model * parent = dynamic_cast<Model*>(m->getAncestorOfType(SBML_MODEL));
        if (parent != NULL)
        {
          parent->enablePackageInternal(nsURI, prefix, true);
        }
      }
      else if (m->getSBMLDocument()->hasUnknownPackage(nsURI) == true)
      {
        // here we are dealing with an unknown package
        // need to decide whether to add the ns or not
        bool addNS = true;
        // if it was listed to be stripped do not add
        if (info->strippedPkgs.contains(prefix) == true) 
        {
          addNS = false;
        }
        // if it has already been disabled do not add
        else if (alreadyDisabled == true) 
        {
          addNS = false;
        }
        // if it is an unflattenable package and flags dicatate do not add
        else if (info->stripUnflattenable == true)
        {
          if (info->abortForRequiredOnly == false)
          {
            addNS = false;
          }
          else if (m->getSBMLDocument()->getPackageRequired(nsURI) == true)
          {
            addNS = false;
          }
        }

        if (addNS == true)
        {
          // we have an unknown package so we cannot enable it
          // but we do tell the parent doc about it
          mainNS->add(nsURI, prefix);
          mainDoc->addUnknownPackageRequired(nsURI, prefix,
            m->getSBMLDocument()->getPackageRequired(nsURI));
        }
      }
    }
  }

  return LIBSBML_OPERATION_SUCCESS;
}