/* (non-Javadoc)
 * @see Expression#evaluate(IVariablePool)
 */
EvaluationResult::ConstPointer
AdaptExpression::Evaluate(IEvaluationContext* context) const
{
  if (fTypeName.size() == 0)
    return EvaluationResult::FALSE_EVAL;
  Object::ConstPointer var = context->GetDefaultVariable();
  Object::ConstPointer adapted;
  IAdapterManager* manager = Platform::GetAdapterManager();
  if (Expressions::IsInstanceOf(var.GetPointer(), fTypeName))
  {
    adapted = var;
  }
  else
  {
    if (!manager->HasAdapter(var.GetPointer(), fTypeName))
      return EvaluationResult::FALSE_EVAL;

    adapted = manager->GetAdapter(var.GetPointer(), fTypeName);
  }
  // the adapted result is null but hasAdapter returned TRUE_EVAL check
  // if the adapter is loaded.
  if (adapted.IsNull())
  {
    if (manager->QueryAdapter(var.GetPointer(), fTypeName) == IAdapterManager::NOT_LOADED)
    {
      return EvaluationResult::NOT_LOADED;
    }
    else
    {
      return EvaluationResult::FALSE_EVAL;
    }
  }
  DefaultVariable scope(context, adapted);
  return this->EvaluateAnd(&scope);
}
EvaluationResult::ConstPointer IterateExpression::Evaluate(IEvaluationContext* context) const
{
  Object::ConstPointer var = context->GetDefaultVariable();
  const ObjectList<Object::Pointer>* col = dynamic_cast<const ObjectList<Object::Pointer>*>(var.GetPointer());
  if (col)
  {
    switch (col->size())
    {
    case 0:
    {
      if (fEmptyResult == -1)
      {
        return fOperator == AND ? EvaluationResult::TRUE_EVAL
            : EvaluationResult::FALSE_EVAL;
      }
      else
      {
        return fEmptyResult == 1 ? EvaluationResult::TRUE_EVAL
            : EvaluationResult::FALSE_EVAL;
      }
    }
    case 1:
    {
      IEvaluationContext::Pointer scope(new DefaultVariable(context,
                                                            col->front()));
      return this->EvaluateAnd(scope.GetPointer());
    }
    default:
      IteratePool iter(context, col->begin(), col->end());
      EvaluationResult::ConstPointer result = fOperator == AND ? EvaluationResult::TRUE_EVAL
          : EvaluationResult::FALSE_EVAL;
      while (iter.HasNext())
      {
        switch (fOperator)
        {
        case OR:
          result = result->Or(this->EvaluateAnd(&iter));
          if (result == EvaluationResult::TRUE_EVAL)
            return result;
          break;
        case AND:
          result = result->And(this->EvaluateAnd(&iter));
          if (result != EvaluationResult::TRUE_EVAL)
            return result;
          break;
        }
        iter.Next();
      }
      return result;
    }
  }
  else
  {
    IIterable::ConstPointer iterable = Expressions::GetAsIIterable(var,
                                                              Expression::ConstPointer(this));
    if (iterable.IsNull())
      return EvaluationResult::NOT_LOADED;

    int count = 0;
    IteratePool iter(context, iterable->begin(), iterable->end());
    EvaluationResult::ConstPointer result = fOperator == AND ? EvaluationResult::TRUE_EVAL
                                                             : EvaluationResult::FALSE_EVAL;
    while (iter.HasNext())
    {
      count++;
      switch (fOperator)
      {
      case OR:
        result = result->Or(this->EvaluateAnd(&iter));
        if (result == EvaluationResult::TRUE_EVAL)
          return result;
        break;
      case AND:
        result = result->And(this->EvaluateAnd(&iter));
        if (result != EvaluationResult::TRUE_EVAL)
          return result;
        break;
      }
      iter.Next();
    }
    if (count > 0)
    {
      return result;
    }
    else
    {
      if (fEmptyResult == -1)
      {
        return fOperator == AND ? EvaluationResult::TRUE_EVAL
            : EvaluationResult::FALSE_EVAL;
      }
      else
      {
        return fEmptyResult == 1 ? EvaluationResult::TRUE_EVAL
            : EvaluationResult::FALSE_EVAL;
      }
    }
  }
}