class SoapCallFactory {

  @SuppressWarnings("unchecked")
  public OMElement createCall(String sessionId, String methodPath, Object arg) {
    OMElement method = fac.createOMElement(CORE_CALL, mag);

    // Register XML namespaces in method
    method.declareNamespace(soapEnc);
    method.declareNamespace(soapXml);
    method.declareNamespace(xsi);
    method.declareNamespace(xsd);

    OMElement paramSession = fac.createOMElement(SESSION_ID, noNs);
    paramSession.addChild(fac.createOMText(paramSession, sessionId));
    method.addChild(paramSession);

    OMElement resourcePath = fac.createOMElement(RESOURCE_PATH, noNs);
    resourcePath.addChild(fac.createOMText(resourcePath, methodPath));
    method.addChild(resourcePath);

    OMElement paramArgs;
    if (arg instanceof Iterable) {
      Iterable<Object> args = (Iterable<Object>) arg;
      paramArgs = fac.createOMElement(ARGUMENTS, noNs);
      paramArgs.addAttribute("arrayType", xsd.getPrefix() + ":ur-type[" + Iterables.size(args) + "]", soapEnc);
      paramArgs.addAttribute("type", soapEnc.getPrefix() + ":Array", xsi);

      for (Object argument : args) {
        paramArgs.addChild(typedElement(noNs, "item", argument));
      }
    } else if (arg instanceof Map) {
      Map<String, Object> args = (Map<String, Object>) arg;
      paramArgs = typedElement(noNs, ARGUMENTS, arg);
      paramArgs.addAttribute("arrayType", xsd.getPrefix() + ":Map[" + args.size() + "]", soapEnc);
      paramArgs.addAttribute("type", soapEnc.getPrefix() + ":Array", xsi);
    } else if (arg != null && (arg.getClass().isArray() || arg.getClass().getName().equals("sun.org.mozilla.javascript.internal.NativeArray"))) {
      Object[] args = (Object[]) arg;
      paramArgs = fac.createOMElement(ARGUMENTS, noNs);
      paramArgs.addAttribute("arrayType", xsd.getPrefix() + ":ur-type[" + args.length + "]", soapEnc);
      paramArgs.addAttribute("type", soapEnc.getPrefix() + ":Array", xsi);

      for (Object argument : args) {
        paramArgs.addChild(typedElement(noNs, "item", argument));
      }
    } else {
      paramArgs = typedElement(noNs, ARGUMENTS, arg);
    }
    method.addChild(paramArgs);

    return method;
  }

  public  SoapCallFactory(OMMetaFactory omMetaFactory);
  public  SoapCallFactory();

}