void
ASTNaryFunctionNode::reduceOperatorsToBinary()
{
  unsigned int numChildren = getNumChildren();
  /* number of children should be greater than 2 */
  if (numChildren < 3)
    return;

  /* only work with times and plus */
  int type = getType();
  if (type != AST_TIMES && type != AST_PLUS)
    return;


  ASTFunction* op = new ASTFunction( getExtendedType() );
  ASTFunction* op2 = new ASTFunction( getExtendedType() );

  // add the first two children to the first node
  op->addChild(getChild(0));
  op->addChild(getChild(1));

  op2->addChild(op);

  for (unsigned int n = 2; n < numChildren; n++)
  {
    op2->addChild(getChild(n));
  }

  swapChildren(op2);

  // valgrind says we are leaking a lot of memory here 
  // but we cannot delete op2 since its children are the children of the
  // current element
  // neither addChild not swapChildren make copies of things

  // we could remove the children and delete the object
  // removeChild does not destroy the object
  // merely removes it from the mChildren vector
  unsigned int i = op2->getNumChildren();
  while (i > 0)
  {
    op2->removeChild(i-1);
    i--;
  }

  delete op2;

  setReducedToBinary(true);

  reduceOperatorsToBinary();
}
bool
ASTNaryFunctionNode::read(XMLInputStream& stream, const std::string& reqd_prefix)
{
  bool read = false;
  ASTBase * child = NULL;
  const XMLToken element = stream.peek ();

  ASTBase::checkPrefix(stream, reqd_prefix, element);

  const char*      name = element.getName().c_str();

  int type = getTypeFromName(name);
  setType(type);
  ASTBase::read(stream, reqd_prefix);

  unsigned int numChildrenAdded = 0;

  if (getExpectedNumChildren() > 0)
  {
    while (stream.isGood() && numChildrenAdded < getExpectedNumChildren())
    {
      stream.skipText();

      name = stream.peek().getName().c_str();

      if (representsNumber(ASTBase::getTypeFromName(name)) == true)
      {
        child = new ASTNumber();
      }
      else 
      {
        child = new ASTFunction();
      }

      read = child->read(stream, reqd_prefix);

      stream.skipText();

      if (read == true && addChild(child) == LIBSBML_OPERATION_SUCCESS)
      {
        numChildrenAdded++;
      }
      else
      {
        delete child;
        child = NULL;
        read = false;
        break;
      }
    }
  }
  else
  {
    stream.skipPastEnd(element);
    read = true;
  }

  if (read == true && type == AST_FUNCTION_ROOT 
    && getExpectedNumChildren() == 1 
    && ASTFunctionBase::getChild(0)->getType() != AST_QUALIFIER_DEGREE)
  {
    /* HACK TO REPLICATE OLD BEHAVIOUR */
    /* we need to add the qualifier child for the degree 2 */
    ASTFunction * degree = new ASTFunction(AST_QUALIFIER_DEGREE);
    ASTNumber * int2 = new ASTNumber(AST_INTEGER);
    int2->setInteger(2);
    degree->addChild(int2->deepCopy());
    this->prependChild(degree->deepCopy());
    delete int2;
    delete degree;

  }

  //if (read == false)
  //{
  //  stream.skipPastEnd(element);
  //}

  return read;
}