bool MethodResponseParser::testEndElement(const XML_Char *name)
{
  ULXR_TRACE("MethodResponseParser::testEndElement(const XML_Char*)");

  if (states.size() <= 1)
    throw RuntimeException(ApplicationError, "abnormal program behaviour: MethodResponseParser::testEndElement() had no states left");

  std::auto_ptr<ValueState> curr(getTopValueState());
  states.pop();
  ValueState *on_top = getTopValueState();

  switch(curr->getParserState() )
  {
    case eMethodResponse:
      setComplete(true);
      assertEndElement(name, "methodResponse");
      on_top->takeValue (curr->getValue());
      if (on_top->getValue() != 0)
        method_value = *on_top->getValue();
    break;

    case eFault:
      assertEndElement(name, "fault");
      on_top->takeValue (curr->getValue());
    break;

    case eParams:
      assertEndElement(name, "params");
      on_top->takeValue (curr->getValue());
    break;

    case eParam:
      assertEndElement(name, "param");
      on_top->takeValue (curr->getValue());
    break;

    default:
      states.push(curr.release());   // put back, someone else will process
      return false;
  }

  return true;
}
    bool MethodCallParser::testEndElement(const XML_Char *name)
    {
        ULXR_TRACE("MethodCallParser::testEndElement(const XML_Char*)");

        if (states.size() <= 1)
            throw RuntimeException(ApplicationError, "abnormal program behaviour: MethodCallParser::testEndElement() had no states left");

        std::auto_ptr<ValueState> curr(getTopValueState());
        states.pop();

//   ULXR_TRACE("\n  current data: <"
//              << curr->getCharData() << ">");

        switch(curr->getParserState() )
        {
        case eMethodName:
            assertEndElement(name, "methodName");
            methodcall.setMethodName(curr->getCharData());
            break;

        case eMethodCall:
            assertEndElement(name, "methodCall");
            setComplete(true);
            break;

        case eParams:
            assertEndElement(name, "params");
            break;

        case eParam:
            assertEndElement(name, "param");
            if (curr->getValue() != 0)
                methodcall.addParam(*curr->getValue());
            delete curr->getValue();
            break;

        default:
            states.push(curr.release());  // put back, someone else will process
            return false;
        }

        return true;
    }
ULXR_API_IMPL(bool) ValueParser::testEndElement(const XML_Char *name)
{
  ULXR_TRACE(ULXR_PCHAR("ValueParser::testEndElement(const XML_Char*)"));

  if (states.size() <= 1)
    throw RuntimeException(ApplicationError, ulxr_i18n(ULXR_PCHAR("abnormal program behaviour: ValueParser::testEndElement() had no states left")));

  std::auto_ptr<ValueState> curr(getTopValueState());
  states.pop();
/*
  ULXR_DOUT (ULXR_GET_STRING(name)
             << ULXR_PCHAR(" = cur-val: ")
             << std::hex << (void*) curr->getValue()
             << ULXR_PCHAR(" state: ")
             << std::hex << (void*) curr->getParserState()
             << ULXR_PCHAR(" prev state: ")
             << std::hex << (void*) curr->getPrevParserState()
             << std::dec);
*/
  states.top()->setPrevParserState(curr->getParserState());
  switch(curr->getParserState() )
  {
    case eBoolean:
      assertEndElement(name, "boolean");
      getTopValueState()->takeValue(new Value(Boolean(curr->getCharData())) );
    break;

    case eInt:
      assertEndElement(name, "int");
      getTopValueState()->takeValue(new Value(Integer(curr->getCharData())) );
    break;

    case eI4:
      assertEndElement(name, "i4");
      getTopValueState()->takeValue(new Value(Integer(curr->getCharData())) );
    break;

    case eDouble:
      assertEndElement(name, "double");
      getTopValueState()->takeValue(new Value(Double(curr->getCharData())) );
    break;

    case eString:
      assertEndElement(name, "string");
      getTopValueState()->takeValue(new Value(RpcString(curr->getCharData())) );
    break;

    case eBase64:
    {
      assertEndElement(name, "base64");
      Base64 b64;
      b64.setBase64(curr->getCharData()); // move raw data!
      getTopValueState()->takeValue(new Value(b64));
    }
    break;

    case eDate:
      assertEndElement(name , "dateTime.iso8601");
      getTopValueState()->takeValue(new Value(DateTime(curr->getCharData())) );
    break;

    case eMember:
      assertEndElement(name, "member");
      getTopValueState()->takeValue (curr->getValue());
    break;

    case eName:
      assertEndElement(name, "name");
      getTopValueState()->takeName((curr->getCharData()) );
    break;

    case eValue:
      assertEndElement(name, "value");
      if (curr->getValue() == 0)     // special case
      {
        if(curr->getPrevParserState() == eArray)            // not empty Array
           getTopValueState()->takeValue (new Value(Array()));

        else if (curr->getPrevParserState() == eStruct)     // not empty Struct
           getTopValueState()->takeValue (new Value(Struct()));

        else                                                // no type tag defaults to string
          getTopValueState()->takeValue (new Value(RpcString(curr->getCharData())));
      }
      else
        getTopValueState()->takeValue (curr->getValue());
    break;

    case eStruct:
      assertEndElement(name, "struct");
      getTopValueState()->takeValue (curr->getValue());
    break;

    case eArray:
      assertEndElement(name, "array");
      getTopValueState()->takeValue (curr->getValue());
    break;

    case eData:
      assertEndElement(name, "data");
      getTopValueState()->takeValue (curr->getValue());
    break;

    default:
      states.push(curr.release());
      return false;
  }

  return true;
}