/*

service.cpp

Service structures.

--------------------------------------------------------------------------------
gSOAP XML Web services tools
Copyright (C) 2001-2005, Robert van Engelen, Genivia Inc. All Rights Reserved.
This part of the software is released under one of the following licenses:
GPL or Genivia's license for commercial use.
--------------------------------------------------------------------------------
GPL license.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA

Author contact information:
engelen@genivia.com / engelen@acm.org
--------------------------------------------------------------------------------
A commercial use license is available from Genivia, Inc., contact@genivia.com
--------------------------------------------------------------------------------

TODO:	consider adding support for non-SOAP HTTP operations
        add headerfault output definitions

*/

#include "types.h"
#include "service.h"

static void comment(const char *start, const char *middle, const char *end, const char *text);
static void page(const char *page, const char *title, const char *text);
static void section(const char *section, const char *title, const char *text);
static void banner(const char*);
static void ident();
static void text(const char*);

////////////////////////////////////////////////////////////////////////////////
//
//	Definitions methods
//
////////////////////////////////////////////////////////////////////////////////

Definitions::Definitions()
{ }

void Definitions::collect(const wsdl__definitions &definitions)
{ // Collect information: analyze WSDL definitions and imported definitions
  analyze(definitions);
  for (vector<wsdl__import>::const_iterator import = definitions.import.begin(); import != definitions.import.end(); ++import)
    if ((*import).definitionsPtr())
      analyze(*(*import).definitionsPtr());
}

void Definitions::analyze(const wsdl__definitions &definitions)
{ // Analyze WSDL and build Service information
  for (vector<wsdl__binding>::const_iterator binding = definitions.binding.begin(); binding != definitions.binding.end(); ++binding)
  { // /definitions/binding/documentation
    const char *binding_documentation = (*binding).documentation;
    // /definitions/binding/soap:binding
    soap__binding *soap__binding_ = (*binding).soap__binding_;
    // /definitions/binding/soap:binding/@transport
    const char *soap__binding_transport = NULL;
    if (soap__binding_)
      soap__binding_transport = soap__binding_->transport;
    // /definitions/binding/soap:binding/@style
    soap__styleChoice soap__binding_style = rpc;
    if (soap__binding_ && soap__binding_->style)
      soap__binding_style = *soap__binding_->style;
    // /definitions/binding/http:binding
    http__binding *http__binding_ = (*binding).http__binding_;
    const char *http__binding_verb = NULL;
    if (http__binding_)
       http__binding_verb = http__binding_->verb;
    // /definitions/binding/operation*
    for (vector<wsdl__binding_operation>::const_iterator operation = (*binding).operation.begin(); operation != (*binding).operation.end(); ++operation)
    { // /definitions/portType/operation/ associated with /definitions/binding/operation
      wsdl__operation *wsdl__operation_ = (*operation).operationPtr();
      // /definitions/binding/operation/soap:operation
      soap__operation *soap__operation_ = (*operation).soap__operation_;
      // /definitions/binding/operation/soap:operation/@style
      soap__styleChoice soap__operation_style = soap__binding_style;
      if (soap__operation_ && soap__operation_->style)
        soap__operation_style = *soap__operation_->style;
      // /definitions/binding/operation/http:operation
      http__operation *http__operation_ = (*operation).http__operation_;
      // /definitions/binding/operation/http:operation/@location
      const char *http__operation_location = NULL;
      if (http__operation_)
        http__operation_location = http__operation_->location;
      // /definitions/binding/operation/input
      wsdl__ext_input *ext_input = (*operation).input;
      // /definitions/binding/operation/output
      wsdl__ext_output *ext_output = (*operation).output;
      // /definitions/portType/operation
      if (wsdl__operation_)
      { wsdl__input *input = wsdl__operation_->input;
        wsdl__output *output = wsdl__operation_->output;
        if (http__operation_)
        { // TODO: HTTP operation
        }
        else if (input && ext_input)
	{ soap__body *input_body = ext_input->soap__body_;
	  if (ext_input->mime__multipartRelated_)
	  { for (vector<mime__part>::const_iterator part = ext_input->mime__multipartRelated_->part.begin(); part != ext_input->mime__multipartRelated_->part.end(); ++part)
	      if ((*part).soap__body_)
	      { input_body = (*part).soap__body_;
	        break;
	      }
	  }
          // MUST have an input, otherwise can't generate a service operation
          if (input_body)
          { const char *URI;
            if (soap__operation_style == rpc)
              URI = input_body->namespace_;
            else
              URI = definitions.targetNamespace;
            if (URI)
            { const char *prefix = types.nsprefix(NULL, URI);
              const char *name = types.aname(NULL, NULL, (*binding).name); // name of service is binding name
              Service *s = services[prefix];
              if (!s)
              { s = services[prefix] = new Service();
                s->prefix = prefix;
                s->URI = URI;
                s->name = name;
                s->transport = soap__binding_transport;
                if ((*binding).portTypePtr())
                  s->type = types.aname(NULL, NULL, (*binding).portTypePtr()->name);
                else
                  s->type = NULL;
              }
              for (vector<wsdl__service>::const_iterator service = definitions.service.begin(); service != definitions.service.end(); ++service)
              { for (vector<wsdl__port>::const_iterator port = (*service).port.begin(); port != (*service).port.end(); ++port)
                { if ((*port).bindingPtr() == &(*binding))
                  { if ((*port).soap__address_)
                      s->location.insert((*port).soap__address_->location);
                    // TODO: HTTP address for HTTP operations
                    // if ((*port).http__address_)
                      // http__address_location = http__address_->location;
                    if ((*service).documentation)
                      s->service_documentation[(*service).name] = (*service).documentation;
                    if ((*port).documentation && (*port).name)
                      s->port_documentation[(*port).name] = (*port).documentation;
                    if (binding_documentation)
                      s->binding_documentation[(*binding).name] = binding_documentation;
                  }
                }
              }
              Operation *o = new Operation();
              o->name = types.aname(NULL, NULL, wsdl__operation_->name);
              o->prefix = prefix;
              o->URI = URI;
              o->style = soap__operation_style;
              o->documentation = wsdl__operation_->documentation;
              o->operation_documentation = (*operation).documentation;
              o->parameterOrder = wsdl__operation_->parameterOrder;
              if ((*operation).soap__operation_)
                o->soapAction = (*operation).soap__operation_->soapAction;
              else
              { o->soapAction = "";
                // determine if we use SOAP 1.2 in which case soapAction is absent, this is a bit of a hack due to the lack of WSDL1.1/SOAP1.2 support and better alternatives
                for (Namespace *p = definitions.soap->local_namespaces; p && p->id; p++)
                { if (p->out && !strcmp(p->id, "soap") && !strcmp(p->out, "http://schemas.xmlsoap.org/wsdl/soap12/"))
                  { o->soapAction = NULL;
                    break;
                  }
                }
              }
              o->input = new Message();
              o->input->name = (*operation).name; // RPC uses operation/@name
              if (soap__operation_style == rpc && !input_body->namespace_)
              { o->input->URI = "";
                fprintf(stderr, "Error: no soap:body namespace attribute\n");
              }
              else
                o->input->URI = input_body->namespace_;
              o->input->use = input_body->use;
              o->input->encodingStyle = input_body->encodingStyle;
              o->input->message = input->messagePtr();
              o->input->part = NULL;
	      o->input->multipartRelated = ext_input->mime__multipartRelated_;
	      o->input->content = NULL;
	      if (ext_input->mime__multipartRelated_ && !ext_input->mime__multipartRelated_->part.empty())
                o->input->header = ext_input->mime__multipartRelated_->part.front().soap__header_;
	      else
                o->input->header = ext_input->soap__header_;
	      if (ext_input->mime__multipartRelated_ && !ext_input->mime__multipartRelated_->part.empty() && ext_input->mime__multipartRelated_->part.front().soap__body_)
	        o->input->body_parts = ext_input->mime__multipartRelated_->part.front().soap__body_->parts;
              else
	        o->input->body_parts = input_body->parts;
	      if (ext_input->dime__message_)
	        o->input->layout = ext_input->dime__message_->layout;
	      else
	        o->input->layout = NULL;
              o->input->documentation = input->documentation;
              o->input->ext_documentation = ext_input->documentation;
              if (soap__operation_style == document)
                o->input_name = types.oname("__", o->URI, o->input->name);
              else
                o->input_name = types.oname(NULL, o->input->URI, o->input->name);
              if (output && ext_output)
	      { soap__body *output_body = ext_output->soap__body_;
                if (ext_output->mime__multipartRelated_)
	        { for (vector<mime__part>::const_iterator part = ext_output->mime__multipartRelated_->part.begin(); part != ext_output->mime__multipartRelated_->part.end(); ++part)
	            if ((*part).soap__body_)
	            { output_body = (*part).soap__body_;
	              break;
	            }
		}
		if (ext_output->mime__content_)
                { o->output = new Message();
                  o->output->name = NULL;
                  o->output->URI = NULL;
                  o->output->encodingStyle = NULL;
                  o->output->body_parts = NULL;
                  o->output->part = NULL;
                  o->output->multipartRelated = NULL;
                  o->output->content = ext_output->mime__content_;
                  o->output->message = output->messagePtr();
                  o->output->layout = NULL;
                  o->output->documentation = output->documentation;
                  o->output->ext_documentation = ext_output->documentation;
		}
		else if (output_body)
                { o->output = new Message();
                  o->output->name = (*operation).name; // RPC uses operation/@name with suffix 'Response' as set below
                  o->output->use = output_body->use;
                  // the code below is a hack around the RPC encoded response message element tag mismatch with Axis:
                  if (!output_body->namespace_ || output_body->use == encoded)
                    o->output->URI = o->input->URI; // encoded seems (?) to require the request's namespace
                  else
                    o->output->URI = output_body->namespace_;
                  o->output->encodingStyle = output_body->encodingStyle;
                  o->output->message = output->messagePtr();
                  o->output->part = NULL;
	          o->output->multipartRelated = ext_output->mime__multipartRelated_;
                  o->output->content = NULL;
	          if (ext_output->mime__multipartRelated_ && !ext_output->mime__multipartRelated_->part.empty())
                    o->output->header = ext_output->mime__multipartRelated_->part.front().soap__header_;
	          else
                    o->output->header = ext_output->soap__header_;
	          if (ext_output->mime__multipartRelated_ && !ext_output->mime__multipartRelated_->part.empty() && ext_output->mime__multipartRelated_->part.front().soap__body_)
	            o->output->body_parts = ext_output->mime__multipartRelated_->part.front().soap__body_->parts;
                  else
	            o->output->body_parts = output_body->parts;
	          if (ext_output->dime__message_)
	            o->output->layout = ext_output->dime__message_->layout;
	          else
	            o->output->layout = NULL;
                  o->output->documentation = output->documentation;
                  o->output->ext_documentation = ext_output->documentation;
                  char *s = (char*)soap_malloc(definitions.soap, strlen(o->output->name) + 9);
                  strcpy(s, o->output->name);
                  strcat(s, "Response");
                  if (soap__operation_style == document)
                    o->output_name = types.oname("__", o->URI, s);
                  else
                    o->output_name = types.oname(NULL, o->output->URI, s);
	        }
              }
              else
              { o->output_name = NULL;
                o->output = NULL;
              }
              // collect input headers and headerfaults
              if (ext_input)
              { const vector<soap__header> *soap__header_ = NULL;
		// check if soap header is in mime:multipartRelated
	        if (ext_input->mime__multipartRelated_)
                { for (vector<mime__part>::const_iterator part = ext_input->mime__multipartRelated_->part.begin(); part != ext_input->mime__multipartRelated_->part.end(); ++part)
                  if (!(*part).soap__header_.empty())
                  { soap__header_ = &(*part).soap__header_;
		    break;
		  }
		}
		if (!soap__header_)
		  soap__header_ = &ext_input->soap__header_;
	        for (vector<soap__header>::const_iterator header = soap__header_->begin(); header != soap__header_->end(); ++header)
                { Message *h = new Message();
                  h->message = (*header).messagePtr();
	          h->body_parts = NULL;
                  h->part = (*header).partPtr();
                  h->URI = (*header).namespace_;
                  if (h->part && h->part->element)
                    h->name = types.aname(NULL, NULL, h->part->element);
                  else if (h->URI && h->part && h->part->name && h->part->type)
                    h->name = types.aname(NULL, h->URI, h->part->name);
                  else
                  { fprintf(stderr, "Error in SOAP Header part definition: input part '%s' missing?\n", h->part && h->part->name ? h->part->name : "?");
                    h->name = "";
                  }
                  h->encodingStyle = (*header).encodingStyle;
                  h->use = (*header).use;
		  h->multipartRelated = NULL;
		  h->content = NULL;
		  h->layout = NULL;
                  h->ext_documentation = NULL;	// TODO: add document content
                  h->documentation = NULL;		// TODO: add document content
                  s->header[h->name] = h;
                  for (vector<soap__headerfault>::const_iterator headerfault = (*header).headerfault.begin(); headerfault != (*header).headerfault.end(); ++headerfault)
                  { // TODO: complete headerfault processing. This is rarely used.
                  }
                }
              }
              // collect output headers and headerfaults
              if (ext_output)
              { const vector<soap__header> *soap__header_ = NULL;
		// check if soap header is in mime:multipartRelated
	        if (ext_output->mime__multipartRelated_)
                { for (vector<mime__part>::const_iterator part = ext_output->mime__multipartRelated_->part.begin(); part != ext_output->mime__multipartRelated_->part.end(); ++part)
                  if (!(*part).soap__header_.empty())
                  { soap__header_ = &(*part).soap__header_;
		    break;
		  }
		}
		if (!soap__header_)
		  soap__header_ = &ext_output->soap__header_;
                for (vector<soap__header>::const_iterator header = soap__header_->begin(); header != soap__header_->end(); ++header)
                { Message *h = new Message();
                  h->message = (*header).messagePtr();
	          h->body_parts = NULL;
    	          h->part = (*header).partPtr();
    	          h->URI = (*header).namespace_;
    	          if (h->part && h->part->element)
    	            h->name = types.aname(NULL, NULL, h->part->element);
    	          else if (h->URI && h->part && h->part->name && h->part->type)
    	            h->name = types.aname(NULL, h->URI, h->part->name);
    	          else
                  { fprintf(stderr, "Error in SOAP Header part definition: output part '%s' missing?\n", h->part && h->part->name ? h->part->name : "?");
    	            h->name = "";
    	          }
    	          h->encodingStyle = (*header).encodingStyle;
    	          h->use = (*header).use;
		  h->multipartRelated = NULL;
		  h->content = NULL;
		  h->layout = NULL;
    	          h->ext_documentation = NULL;	// TODO: add document content
    	          h->documentation = NULL;	// TODO: add document content
    	          s->header[h->name] = h;
    	          for (vector<soap__headerfault>::const_iterator headerfault = (*header).headerfault.begin(); headerfault != (*header).headerfault.end(); ++headerfault)
    	          { // TODO: complete headerfault processing. This is rarely used.
    	          }
    	        }
    	      }
    	      // collect faults
              for (vector<wsdl__ext_fault>::const_iterator ext_fault = (*operation).fault.begin(); ext_fault != (*operation).fault.end(); ++ext_fault)
    	      { if ((*ext_fault).soap__fault_ && (*ext_fault).messagePtr())
    	        { Message *f = new Message();
    	          f->message = (*ext_fault).messagePtr();
	          f->body_parts = NULL;
    	          f->part = NULL;
    	          f->encodingStyle = (*ext_fault).soap__fault_->encodingStyle;
    	          f->URI = (*ext_fault).soap__fault_->namespace_;
    	          f->use = (*ext_fault).soap__fault_->use;
		  f->multipartRelated = NULL;
		  f->content = NULL;
		  f->layout = NULL;
    	          f->ext_documentation = (*ext_fault).documentation;
                  f->name = types.aname("_", f->URI, f->message->name);
    	          f->documentation = f->message->documentation;
    	          o->fault.push_back(f);
    	          s->fault[f->name] = f;
    	        }
    	        else
    	          fprintf(stderr, "Error: no wsdl:definitions/binding/operation/fault/soap:fault\n");
    	      }
    	      s->operation.push_back(o);
            }
    	    else
    	      fprintf(stderr, "Warning: no SOAP RPC operation namespace, operations will be ignored\n");
          }
          else
            fprintf(stderr, "Error: no wsdl:definitions/binding/operation/input/soap:body\n");
        }
        else
          fprintf(stderr, "Error: no wsdl:definitions/portType/operation/input\n");
      }
      else
        fprintf(stderr, "Error: no wsdl:definitions/portType/operation\n");
    }
  }
}

void Definitions::compile(const wsdl__definitions& definitions)
{ // compile the definitions and generate gSOAP header file
  const char *defs;
  if (definitions.name)
    defs = types.aname(NULL, NULL, definitions.name);
  else
    defs = "Service";
  ident();
  fprintf(stream, "/* NOTE:\n\n - Compile this file with soapcpp2 to complete the code generation process.\n - Use soapcpp2 option -I to specify paths for #import\n   To build with STL, 'stlvector.h' is imported from 'import' dir in package.\n - Use wsdl2h options -c and -s to generate pure C code or C++ code without STL.\n - Use 'typemap.dat' to control schema namespace bindings and type mappings.\n   It is strongly recommended to customize the names of the namespace prefixes\n   generated by wsdl2h. To do so, modify the prefix bindings in the Namespaces\n   section below and add the modified lines to 'typemap.dat' to rerun wsdl2h.\n - Use Doxygen (www.doxygen.org) to browse this file.\n - Use wsdl2h option -l to view the software license terms.\n\n*/\n");
  banner(definitions.targetNamespace?definitions.targetNamespace:"targetNamespace");
  // copy documentation from WSDL definitions
  if (definitions.documentation)
  { fprintf(stream, "/* WSDL Documentation:\n\n");
    text(definitions.documentation);
    fprintf(stream, "*/\n\n");
  }
  if (lflag)
  { banner("License");
    fprintf(stream, "/*\n%s*/\n\n", licensenotice);
  }
  // gsoap compiler options: 'w' disables WSDL/schema output to avoid file collisions
  if (cflag)
    fprintf(stream, "//gsoapopt cw\n");
  else
    fprintf(stream, "//gsoapopt w\n");
  banner("Import");
  if (dflag)
  { if (import_path)
      fprintf(stream, "#import \"%s/dom.h\"\n", import_path);
    else
      fprintf(stream, "#import \"dom.h\"\n");
  }
  if (!cflag && !sflag)
  { if (import_path)
      fprintf(stream, "#import \"%s/stlvector.h\"\n", import_path);
    else
      fprintf(stream, "#import \"stlvector.h\"\n");
  }
  if (mflag)
  { if (import_path)
      fprintf(stream, "#import \"%s/", import_path);
    else
      fprintf(stream, "#import \"");
    fprintf(stream, "xsd.h\"\t// import primitive XSD types.\n", import_path);
  }
  for (SetOfString::const_iterator u = exturis.begin(); u != exturis.end(); ++u)
  { bool found = false;
    size_t n = strlen(*u);
    for (SetOfString::const_iterator i = definitions.builtinTypes().begin(); i != definitions.builtinTypes().end(); ++i)
    { if (**i == '"' && !strncmp(*u, *i + 1, n))
      { found = true;
	break;
      }
    }
    if (!found)
      for (SetOfString::const_iterator j = definitions.builtinElements().begin(); j != definitions.builtinElements().end(); ++j)
      { if (**j == '"' && !strncmp(*u, *j + 1, n))
        { found = true;
	  break;
        }
      }
    if (!found)
      for (SetOfString::const_iterator k = definitions.builtinAttributes().begin(); k != definitions.builtinAttributes().end(); ++k)
      { if (**k == '"' && !strncmp(*u, *k + 1, n))
        { found = true;
	  break;
        }
      }
    if (found)
    { if (import_path)
        fprintf(stream, "#import \"%s/%s.h\"\t// %s = <%s>\n", import_path, types.nsprefix(NULL, *u), types.nsprefix(NULL, *u), *u);
      else
        fprintf(stream, "#import \"%s.h\"\t// %s = <%s>\n", types.nsprefix(NULL, *u), types.nsprefix(NULL, *u), *u);
    }
  }
  banner("Schema Namespaces");
  // determine if we must use SOAP 1.2, this is a bit of a hack due to the lack of WSDL1.1/SOAP1.2 support and better alternatives
  for (Namespace *p = definitions.soap->local_namespaces; p && p->id; p++)
  { // p->out is set to the actual namespace name that matches the p->in pattern
    if (p->out && !strcmp(p->id, "soap") && !strcmp(p->out, "http://schemas.xmlsoap.org/wsdl/soap12/"))
    { fprintf(stream, "// This service uses SOAP 1.2 namespaces:\n");
      fprintf(stream, schemaformat, "SOAP-ENV", "namespace", "http://www.w3.org/2003/05/soap-envelope");
      fprintf(stream, schemaformat, "SOAP-ENC", "namespace", "http://www.w3.org/2003/05/soap-encoding");
      break;
    }
  }
  if (definitions.types)
  { fprintf(stream, "\n/* NOTE:\n\nIt is strongly recommended to customize the names of the namespace prefixes\ngenerated by wsdl2h. To do so, modify the prefix bindings below and add the\nmodified lines to typemap.dat to rerun wsdl2h:\n\n");
    if (definitions.targetNamespace && *definitions.targetNamespace)
      fprintf(stream, "%s = \"%s\"\n", types.nsprefix(service_prefix, definitions.targetNamespace), definitions.targetNamespace);
    for (vector<xs__schema*>::const_iterator schema1 = definitions.types->xs__schema_.begin(); schema1 != definitions.types->xs__schema_.end(); ++schema1)
      if (!definitions.targetNamespace || strcmp((*schema1)->targetNamespace, definitions.targetNamespace))
        fprintf(stream, "%s = \"%s\"\n", types.nsprefix(NULL, (*schema1)->targetNamespace), (*schema1)->targetNamespace);
    fprintf(stream, "\n*/\n\n");
    for (vector<xs__schema*>::const_iterator schema2 = definitions.types->xs__schema_.begin(); schema2 != definitions.types->xs__schema_.end(); ++schema2)
      fprintf(stream, schemaformat, types.nsprefix(NULL, (*schema2)->targetNamespace), "namespace", (*schema2)->targetNamespace);
    for (vector<xs__schema*>::const_iterator schema3 = definitions.types->xs__schema_.begin(); schema3 != definitions.types->xs__schema_.end(); ++schema3)
    { if ((*schema3)->elementFormDefault == (*schema3)->attributeFormDefault)
        fprintf(stream, schemaformat, types.nsprefix(NULL, (*schema3)->targetNamespace), "form", (*schema3)->elementFormDefault == qualified ? "qualified" : "unqualified");
      else
      { fprintf(stream, schemaformat, types.nsprefix(NULL, (*schema3)->targetNamespace), "elementForm", (*schema3)->elementFormDefault == qualified ? "qualified" : "unqualified");
        fprintf(stream, schemaformat, types.nsprefix(NULL, (*schema3)->targetNamespace), "attributeForm", (*schema3)->attributeFormDefault == qualified ? "qualified" : "unqualified");
      }
    }
  }
  banner("Schema Types");
  // generate the prototypes first: these should allow use before def, e.g. class names then generate the defs
  // check if xsd:anyType is used
  if (!cflag && !pflag)
  { for (SetOfString::const_iterator i = definitions.builtinTypes().begin(); i != definitions.builtinTypes().end(); ++i)
    { if (!cflag && !strcmp(*i, "xs:anyType"))
      { pflag = 1;
        break;
      }
    }
  }
  // define xsd:anyType first, if used
  if (!cflag && pflag)
  { const char *s, *t;
    t = types.cname(NULL, NULL, "xs:anyType");
    s = types.deftypemap[t];
    if (s)
    { if (*s)
      { if (!mflag)
          fprintf(stream, "%s\n", s);
      }
      s = types.usetypemap[t];
      if (s)
      { if (mflag)
          fprintf(stream, "//  xsd.h must define type: %s\n", s);
        types.knames.insert(s);
      }
    }
    else
    { fprintf(stderr, "Error: no xsd__anyType defined in type map\n");
      pflag = 0;
    }
  }
  // produce built-in primitive types, limited to the ones that are used only
  for (SetOfString::const_iterator i = definitions.builtinTypes().begin(); i != definitions.builtinTypes().end(); ++i)
  { const char *s, *t;
    if (!cflag && pflag && !strcmp(*i, "xs:anyType"))
      continue;
    t = types.cname(NULL, NULL, *i);
    s = types.deftypemap[t];
    if (s)
    { if (*s)
      { if (**i == '"')
	  fprintf(stream, "\n/// Imported type %s from typemap %s.\n", *i, mapfile?mapfile:"");
        else
	  fprintf(stream, "\n/// Built-in type \"%s\".\n", *i);
	if (mflag)
          fprintf(stream, "//  (declaration removed by option -m) ");
        types.format(s);
      }
      s = types.usetypemap[t];
      if (s && *s)
      { if (mflag && **i != '"')
          fprintf(stream, "\n//  xsd.h must define type: %s\n", s);
        if (types.knames.find(s) == types.knames.end())
          types.knames.insert(s);
      }
    }
    else
    { s = types.tname(NULL, NULL, "xsd:string");
      if (!mflag)
      { if (**i == '"')
          fprintf(stream, "\n// Imported type %s defined by %s\n", *i, t);
        else
        { fprintf(stream, "\n/// Primitive built-in type \"%s\"\n", *i);
          fprintf(stream, "typedef %s %s;\n", s, t);
        }
      }
      else if (**i == '"')
        fprintf(stream, "\n//  Imported type %s defined by %s\n", *i, t);
      else
        fprintf(stream, "\n//  xsd.h must define type: %s\n", t);
      types.deftname(TYPEDEF, NULL, strchr(s, '*') != NULL, NULL, NULL, *i);
    }
    if (pflag && !strncmp(*i, "xs:", 3))		// only xsi types are polymorph
    { s = types.aname(NULL, NULL, *i);
      if (!mflag)
      { fprintf(stream, "\n/// Class wrapper for built-in type \"%s\" derived from xsd__anyType\n", *i);
        fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s);
        fprintf(stream, elementformat, types.tname(NULL, NULL, *i), "__item;");
        fprintf(stream, "\n};\n");
      }
      types.knames.insert(s);
    }
  }
  // produce built-in primitive elements, limited to the ones that are used only
  for (SetOfString::const_iterator j = definitions.builtinElements().begin(); j != definitions.builtinElements().end(); ++j)
  { const char *s, *t;
    t = types.cname("_", NULL, *j);
    s = types.deftypemap[t];
    if (s)
    { if (*s)
      { if (**j == '"')
	  fprintf(stream, "\n/// Imported element %s from typemap %s.\n", *j, mapfile?mapfile:"");
        else
	  fprintf(stream, "\n/// Built-in element \"%s\".\n", *j);
	if (mflag)
          fprintf(stream, "//  (declaration removed by option -m) ");
        types.format(s);
      }
      s = types.usetypemap[t];
      if (s && *s)
      { if (mflag && **j != '"')
          fprintf(stream, "\n//  xsd.h must define element: %s\n", s);
        if (types.knames.find(s) == types.knames.end())
          types.knames.insert(s);
      }
    }
    else
    { if (!mflag)
      { if (**j == '"')
	  fprintf(stream, "\n// Imported element %s declared as %s\n", *j, t);
        else
	{ fprintf(stream, "\n/// Built-in element \"%s\".\n", *j);
          fprintf(stream, "typedef _XML %s;\n", t);
        }
      }
      else if (**j == '"')
	fprintf(stream, "\n//  Imported element %s declared as %s\n", *j, t);
      else
        fprintf(stream, "\n//  xsd.h must define element: %s\n", t);
      types.deftname(TYPEDEF, NULL, true, NULL, NULL, *j);	// already pointer
    }
  }
  // produce built-in primitive attributes, limited to the ones that are used only
  for (SetOfString::const_iterator k = definitions.builtinAttributes().begin(); k != definitions.builtinAttributes().end(); ++k)
  { const char *s, *t;
    t = types.cname("_", NULL, *k);
    s = types.deftypemap[t];
    if (s)
    { if (*s)
      { if (**k == '"')
	  fprintf(stream, "\n/// Imported attribute %s from typemap %s.\n", *k, mapfile?mapfile:"");
        else
	  fprintf(stream, "\n/// Built-in attribute \"%s\".\n", *k);
	if (mflag)
          fprintf(stream, "//  (declaration removed by option -m) ");
        types.format(s);
      }
      s = types.usetypemap[t];
      if (s && *s)
      { if (mflag && **k != '"')
          fprintf(stream, "\n//  xsd.h must define attribute: %s\n", s);
        if (types.knames.find(s) == types.knames.end())
          types.knames.insert(s);
      }
    }
    else
    { s = types.tname(NULL, NULL, "xsd:string");
      if (!mflag)
      { if (**k == '"')
          fprintf(stream, "\n// Imported attribute %s declared as %s\n", *k, t);
        else
        { fprintf(stream, "\n/// Built-in attribute \"%s\".\n", *k);
          fprintf(stream, "typedef %s %s;\n", s, t);
        }
      }
      else if (**k == '"')
        fprintf(stream, "//  Imported attribute %s declared as %s\n", *k, t);
      else
        fprintf(stream, "//  xsd.h must define attribute: %s\n", t);
      types.deftname(TYPEDEF, NULL, strchr(s, '*') != NULL, NULL, NULL, *k);
    }
  }
  // produce types
  // define class/struct types first
  if (definitions.types)
  { comment("Definitions", defs, "types", definitions.types->documentation);
    fprintf(stream, "\n");
    for (vector<xs__schema*>::const_iterator schema4 = definitions.types->xs__schema_.begin(); schema4 != definitions.types->xs__schema_.end(); ++schema4)
    { for (vector<xs__complexType>::const_iterator complexType = (*schema4)->complexType.begin(); complexType != (*schema4)->complexType.end(); ++complexType)
        types.define((*schema4)->targetNamespace, NULL, *complexType);
      for (vector<xs__element>::const_iterator element = (*schema4)->element.begin(); element != (*schema4)->element.end(); ++element)
      { if (!(*element).type)
        { if ((*element).complexTypePtr())
            types.define((*schema4)->targetNamespace, (*element).name, *(*element).complexTypePtr());
	  else
          { fprintf(stream, "\n/// Element \"%s\":%s.\n", (*schema4)->targetNamespace, (*element).name);
            if (gflag)
	    { const char *t = types.deftname(TYPEDEF, NULL, false, "_", (*schema4)->targetNamespace, (*element).name);
  	      fprintf(stream, "typedef _XML %s;\n", t);
	    }
	    else
	    { const char *s = types.cname("_", (*schema4)->targetNamespace, (*element).name);
              types.ptrtypemap[s] = types.usetypemap[s] = "_XML";
	      fprintf(stream, "/// Note: use wsdl2h option -g to generate this global element declaration.\n");
	    }
	  }
        }
      }
    }  
    // visit types with lowest base level first
    int baseLevel = 1;
    bool found;
    do
    { found = (baseLevel == 1);
      for (vector<xs__schema*>::iterator schema = definitions.types->xs__schema_.begin(); schema != definitions.types->xs__schema_.end(); ++schema)
      { for (vector<xs__simpleType>::iterator simpleType = (*schema)->simpleType.begin(); simpleType != (*schema)->simpleType.end(); ++simpleType)
        { if ((*simpleType).baseLevel() == baseLevel)
          { found = true;
            types.gen((*schema)->targetNamespace, NULL, *simpleType, false);
          }
        }
        for (vector<xs__element>::iterator element = (*schema)->element.begin(); element != (*schema)->element.end(); ++element)
        { if (!(*element).type && (*element).simpleTypePtr() && (*element).simpleTypePtr()->baseLevel() == baseLevel)
          { found = true;
	    if ((*element).type)
	      fprintf(stream, "/// Element \"%s\":%s of simpleType %s.\n", (*schema)->targetNamespace, (*element).name, (*element).type);
	    types.document((*element).annotation);
            types.gen((*schema)->targetNamespace, (*element).name, *(*element).simpleTypePtr(), false);
          }
          if (!(*element).type && (*element).complexTypePtr() && (*element).complexTypePtr()->baseLevel() == baseLevel)
            found = true;
        }
        for (vector<xs__attribute>::const_iterator attribute = (*schema)->attribute.begin(); attribute != (*schema)->attribute.end(); ++attribute)
        { if (!(*attribute).type && (*attribute).simpleTypePtr() && (*attribute).simpleTypePtr()->baseLevel() == baseLevel)
          { found = true;
	    if ((*attribute).type)
	      fprintf(stream, "/// Attribute \"%s\":%s of simpleType %s.\n", (*schema)->targetNamespace, (*attribute).name, (*attribute).type);
	    types.document((*attribute).annotation);
            types.gen((*schema)->targetNamespace, (*attribute).name, *(*attribute).simpleTypePtr(), false); // URI = NULL won't generate type in schema (type without namespace qualifier)
          }
        }
        for (vector<xs__complexType>::iterator complexType = (*schema)->complexType.begin(); complexType != (*schema)->complexType.end(); ++complexType)
        { if ((*complexType).baseLevel() == baseLevel)
            found = true;
        }
      }
      ++baseLevel;
    } while (found);
    // generate complex type defs. Problem: what if a simpleType restriction/extension depends on a complexType simpleContent restriction/extension?
    int maxLevel = baseLevel;
    for (baseLevel = 1; baseLevel < maxLevel; ++baseLevel)
    { for (vector<xs__schema*>::iterator schema = definitions.types->xs__schema_.begin(); schema != definitions.types->xs__schema_.end(); ++schema)
      { for (vector<xs__complexType>::iterator complexType = (*schema)->complexType.begin(); complexType != (*schema)->complexType.end(); ++complexType)
        { if ((*complexType).baseLevel() == baseLevel)
            types.gen((*schema)->targetNamespace, NULL, *complexType, false);
        }
        for (vector<xs__element>::iterator element = (*schema)->element.begin(); element != (*schema)->element.end(); ++element)
        { if (!(*element).type && (*element).complexTypePtr() && (*element).complexTypePtr()->baseLevel() == baseLevel)
	  { fprintf(stream, "\n\n/// Element \"%s\":%s of complexType.\n", (*schema)->targetNamespace, (*element).name);
	    types.document((*element).annotation);
            types.gen((*schema)->targetNamespace, (*element).name, *(*element).complexTypePtr(), false);
	  }
        }
      }
    }
    // option to consider: generate local complexTypes iteratively
    /*
    for (MapOfStringToType::const_iterator local = types.locals.begin(); local != types.locals.end(); ++local)
    { types.gen(NULL, (*local).first, *(*local).second);
    }
    */
    for (vector<xs__schema*>::iterator schema = definitions.types->xs__schema_.begin(); schema != definitions.types->xs__schema_.end(); ++schema)
    { for (vector<xs__element>::iterator element = (*schema)->element.begin(); element != (*schema)->element.end(); ++element)
      { if ((*element).name && (*element).type)
        { fprintf(stream, "\n/// Element \"%s\":%s of type %s.\n", (*schema)->targetNamespace, (*element).name, (*element).type);
          types.document((*element).annotation);
          if (!types.is_defined("_", (*schema)->targetNamespace, (*element).name))
          { const char *s = types.tname(NULL, NULL, (*element).type);
            const char *t = types.deftname(TYPEDEF, NULL, false, "_", (*schema)->targetNamespace, (*element).name);
  	    if (gflag)
  	    { if (strncmp(s, "char", 4) && strchr(s, '*')) // don't want pointer typedef, unless char*
  	      { size_t n = strlen(s);
  	        char *r = (char*)malloc(n);
  	        strncpy(r, s, n - 1);
  	        r[n - 1] = '\0';
  	        fprintf(stream, "typedef %s %s;\n", r, t);
  	        free(r);
  	      }
  	      else
  	        fprintf(stream, "typedef %s %s;\n", s, t);
  	    }
  	    else
              fprintf(stream, "/// Note: use wsdl2h option -g to generate this global element declaration.\n");
          }
	  else
	  { const char *s = types.cname("_", (*schema)->targetNamespace, (*element).name);
            const char *t = types.deftypemap[s];
	    if (t && *t)
	    { fprintf(stream, "/// Imported element %s from typemap %s.\n", s, mapfile?mapfile:"");
	      types.format(t);
	    }
	    else
              fprintf(stream, "// '%s' element definition intentionally left blank.\n", types.cname("_", (*schema)->targetNamespace, (*element).name));
          }
        }
      }
      for (vector<xs__attribute>::iterator attribute = (*schema)->attribute.begin(); attribute != (*schema)->attribute.end(); ++attribute)
      { if ((*attribute).name && (*attribute).type)
        { fprintf(stream, "\n/// Attribute \"%s\":%s of simpleType %s.\n", (*schema)->targetNamespace, (*attribute).name, (*attribute).type);
          types.document((*attribute).annotation);
          if (!types.is_defined("_", (*schema)->targetNamespace, (*attribute).name))
          { const char *s = types.tname(NULL, NULL, (*attribute).type);
            const char *t = types.deftname(TYPEDEF, NULL, false, "_", (*schema)->targetNamespace, (*attribute).name);
  	    if (gflag)
  	    { if (strncmp(s, "char", 4) && strchr(s, '*')) // don't want pointer typedef, unless char*
  	      { size_t n = strlen(s);
  	        char *r = (char*)malloc(n);
  	        strncpy(r, s, n - 1);
  	        r[n - 1] = '\0';
  	        fprintf(stream, "typedef %s %s;\n", r, t);
  	        free(r);
  	      }
  	      else
  	        fprintf(stream, "typedef %s %s;\n", s, t);
  	    }
  	    else
              fprintf(stream, "/// Note: use wsdl2h option -g to generate this global attribute declaration.\n");
          }
	  else
	  { const char *s = types.cname("_", (*schema)->targetNamespace, (*attribute).name);
            const char *t = types.deftypemap[s];
	    if (t && *t)
	    { fprintf(stream, "/// Imported attribute %s from typemap %s.\n", s, mapfile?mapfile:"");
	      types.format(t);
	    }
	    else
              fprintf(stream, "// '%s' attribute definition intentionally left blank.\n", types.cname("_", (*schema)->targetNamespace, (*attribute).name));
	  }
        }
      }
    }
  }
  collect(definitions);
  if (!services.empty())
  { banner("Services");
    for (MapOfStringToService::const_iterator service1 = services.begin(); service1 != services.end(); ++service1)
    { Service *sv = (*service1).second;
      if (sv && sv->prefix)
      { fprintf(stream, "\n");
        if (sv->name)
          fprintf(stream, serviceformat, sv->prefix, "name", sv->name, "");
        if (sv->type)
          fprintf(stream, serviceformat, sv->prefix, "type", sv->type, "");
        for (SetOfString::const_iterator port = sv->location.begin(); port != sv->location.end(); ++port)
          fprintf(stream, serviceformat, sv->prefix, "port", (*port), "");
        if (sv->URI)
          fprintf(stream, serviceformat, sv->prefix, "namespace", sv->URI, "");
        if (sv->transport)
          fprintf(stream, serviceformat, sv->prefix, "transport", sv->transport, "");
      }
    }
    fprintf(stream, "\n/** @mainpage %s Definitions\n", definitions.name?definitions.name:"Service");
    if (definitions.documentation)
    { section(defs, "_documentation Documentation", NULL);
      text(definitions.documentation);
    }
    if (definitions.types && definitions.types->documentation)
    { section(defs, "_types Types", NULL);
      text(definitions.types->documentation);
    }
    section(defs, "_bindings Bindings", NULL);
    for (MapOfStringToService::const_iterator service2 = services.begin(); service2 != services.end(); ++service2)
    { Service *sv = (*service2).second;
      if (sv && sv->name)
        fprintf(stream, "  - @ref %s\n", sv->name);
    }
    fprintf(stream, "\n*/\n");
    for (MapOfStringToService::const_iterator service3 = services.begin(); service3 != services.end(); ++service3)
    { Service *sv = (*service3).second;
      if (sv && sv->name)
      { fprintf(stream, "\n/**\n");
        page(sv->name, " Binding", sv->name);
        for (MapOfStringToString::const_iterator service_doc = sv->service_documentation.begin(); service_doc != sv->service_documentation.end(); ++service_doc)
        { const char *name = types.aname(NULL, NULL, (*service_doc).first);
	  section(name, "_service Service Documentation", (*service_doc).first);
          text((*service_doc).second);
        }
        for (MapOfStringToString::const_iterator port_doc = sv->port_documentation.begin(); port_doc != sv->port_documentation.end(); ++port_doc)
        { const char *name = types.aname(NULL, NULL, (*port_doc).first);
          section(name, "_port Port Documentation", (*port_doc).first);
          text((*port_doc).second);
        }
        for (MapOfStringToString::const_iterator binding_doc = sv->binding_documentation.begin(); binding_doc != sv->binding_documentation.end(); ++binding_doc)
        { const char *name = types.aname(NULL, NULL, (*binding_doc).first);
          section(name, "_binding Binding Documentation", (*binding_doc).first);
          text((*binding_doc).second);
        }
        section(sv->name, "_operations Operations of Binding ", sv->name);
        for (vector<Operation*>::const_iterator op = sv->operation.begin(); op != sv->operation.end(); ++op)
        { if (*op && (*op)->input_name)
            fprintf(stream, "  - @ref %s\n", (*op)->input_name);
        }
        section((*sv).name, "_ports Endpoints of Binding ", sv->name);
        for (SetOfString::const_iterator port = sv->location.begin(); port != sv->location.end(); ++port)
          fprintf(stream, "  - %s\n", *port);
        fprintf(stream, "\n*/\n");
      }
    }
  }
  generate();
  fprintf(stream, "\n/* End of %s */\n", outfile?outfile:"file");
}

void Definitions::generate()
{ MapOfStringToMessage headers;
  MapOfStringToMessage faults;
  for (MapOfStringToService::const_iterator service1 = services.begin(); service1 != services.end(); ++service1)
  { if ((*service1).second)
    { for (MapOfStringToMessage::const_iterator header = (*service1).second->header.begin(); header != (*service1).second->header.end(); ++header)
        headers[(*header).first] = (*header).second;
      for (MapOfStringToMessage::const_iterator fault = (*service1).second->fault.begin(); fault != (*service1).second->fault.end(); ++fault)
        faults[(*fault).first] = (*fault).second;
    }
  }
  // Generate SOAP Header definition
  if (!headers.empty())
  { banner("SOAP Header");
    fprintf(stream, "/**\n\nThe SOAP Header is part of the gSOAP context and its content is accessed\nthrough the soap.header variable. You may have to set the soap.actor variable\nto serialize SOAP Headers with SOAP-ENV:actor or SOAP-ENV:role attributes.\n\n*/\n");
    fprintf(stream, "struct SOAP_ENV__Header\n{\n");
    for (MapOfStringToMessage::const_iterator header = headers.begin(); header != headers.end(); ++header)
    { if ((*header).second->URI && !types.uris[(*header).second->URI])
        fprintf(stream, schemaformat, types.nsprefix(NULL, (*header).second->URI), "namespace", (*header).second->URI);
      comment("Header", (*header).first, "WSDL", (*header).second->ext_documentation);
      comment("Header", (*header).first, "SOAP", (*header).second->documentation);
      if ((*header).second->part && (*header).second->part->elementPtr())
      { fprintf(stream, "/// \"%s\" SOAP Header part element\n", (*header).second->part->name);
        types.gen(NULL, *(*header).second->part->elementPtr());
      }
      else if ((*header).second->part && (*header).second->part->type)
      { fprintf(stream, elementformat, "mustUnderstand", "// must be understood by receiver");
        fprintf(stream, "\n");
        fprintf(stream, elementformat, types.pname(true, NULL, NULL, (*header).second->part->type), (*header).first);
        fprintf(stream, ";\n");
      }
      else
      { fprintf(stream, elementformat, "mustUnderstand", "// must be understood by receiver");
        fprintf(stream, "\n");
        if ((*header).second->part && (*header).second->part->element)
	  fprintf(stream, pointerformat, types.pname(true, NULL, NULL, (*header).second->part->element), (*header).first);
        else
	  fprintf(stream, pointerformat, (*header).first, (*header).first);
        fprintf(stream, ";\t///< TODO: Check element type (imported type)\n");
      }
    }
    fprintf(stream, "\n};\n");
  }
  // Generate Fault detail element definitions
  for (MapOfStringToMessage::const_iterator fault = faults.begin(); fault != faults.end(); ++fault)
  { banner("SOAP Fault Detail");
    fprintf(stream, "/// The SOAP Fault Detail element contains one of the following types serialized\n// in the __type and fault fields of the SOAP_ENV__Detail struct (see docs)\n");
    if ((*fault).second->URI && !types.uris[(*fault).second->URI])
      fprintf(stream, schemaformat, types.nsprefix(NULL, (*fault).second->URI), "namespace", (*fault).second->URI);
    comment("Fault", (*fault).first, "WSDL", (*fault).second->ext_documentation);
    comment("Fault", (*fault).first, "SOAP", (*fault).second->documentation);
    if (cflag)
      fprintf(stream, "struct %s\n{\n", (*fault).first);
    else
      fprintf(stream, "class %s\n{ public:", (*fault).first);
    (*fault).second->generate(types, ";", false, true, false);
    if (!cflag)
    { fprintf(stream, "\n");
      fprintf(stream, pointerformat, "struct soap", "soap");
      fprintf(stream, ";");
    }
    fprintf(stream, "\n};\n");
  }
  /* The SOAP Fault struct below is autogenerated by soapcpp2 (kept here for future mods)
  if (!mflag && !faults.empty())
  { fprintf(stream, "struct SOAP_ENV__Code\n{\n"); 
    fprintf(stream, elementformat, "_QName", "SOAP_ENV__Value");
    fprintf(stream, ";\n");
    fprintf(stream, pointerformat, "char", "SOAP_ENV__Node");
    fprintf(stream, ";\n");
    fprintf(stream, pointerformat, "char", "SOAP_ENV__Role");
    fprintf(stream, ";\n};\n");
    fprintf(stream, "struct SOAP_ENV__Detail\n{\n"); 
    fprintf(stream, elementformat, "int", "__type");
    fprintf(stream, ";\n");
    fprintf(stream, pointerformat, "void", "fault");
    fprintf(stream, ";\n");
    fprintf(stream, elementformat, "_XML", "__any");
    fprintf(stream, ";\n};\n");
    fprintf(stream, "struct SOAP_ENV__Fault\n{\n"); 
    fprintf(stream, elementformat, "_QName", "faultcode");
    fprintf(stream, ";\n");
    fprintf(stream, pointerformat, "char", "faultstring");
    fprintf(stream, ";\n");
    fprintf(stream, pointerformat, "char", "faultactor");
    fprintf(stream, ";\n");
    fprintf(stream, pointerformat, "struct SOAP_ENV__Detail", "detail");
    fprintf(stream, ";\n");
    fprintf(stream, pointerformat, "struct SOAP_ENV__Code", "SOAP_ENV__Code");
    fprintf(stream, ";\n");
    fprintf(stream, pointerformat, "char", "SOAP_ENV__Reason");
    fprintf(stream, ";\n");
    fprintf(stream, pointerformat, "struct SOAP_ENV__Detail", "SOAP_ENV__Detail");
    fprintf(stream, ";\n};\n");
  }
  */
  for (MapOfStringToService::const_iterator service2 = services.begin(); service2 != services.end(); ++service2)
    if ((*service2).second)
      (*service2).second->generate(types);
} 

////////////////////////////////////////////////////////////////////////////////
//
//	Service methods
//
////////////////////////////////////////////////////////////////////////////////

Service::Service()
{ prefix = NULL;
  URI = NULL;
  name = NULL;
  type = NULL;
  transport = NULL;
}

void Service::generate(Types& types)
{ if (name)
    banner(name);
  for (vector<Operation*>::const_iterator op2 = operation.begin(); op2 != operation.end(); ++op2)
  { if (*op2 && (*op2)->input)
    { bool flag = false, anonymous = (*op2)->parameterOrder != NULL;
      banner((*op2)->input_name);
      if ((*op2)->output && (*op2)->output_name)
      { if ((*op2)->style == document)
          flag = (*op2)->output->message && (*op2)->output->message->part.size() == 1;
        else if (!wflag)
          flag = (*op2)->output->message && (*op2)->output->use == encoded && (*op2)->output->message->part.size() == 1 && !(*(*op2)->output->message->part.begin()).simpleTypePtr() && !(*(*op2)->output->message->part.begin()).complexTypePtr();
        if (flag && (*op2)->input->message && (*(*op2)->output->message->part.begin()).element)
          for (vector<wsdl__part>::const_iterator part = (*op2)->input->message->part.begin(); part != (*op2)->input->message->part.end(); ++part)
            if ((*part).element && !strcmp((*part).element, (*(*op2)->output->message->part.begin()).element))
              flag = false;
	if (!flag)
        { fprintf(stream, "/// Operation response struct \"%s\" of service binding \"%s\" operation \"%s\"\n", (*op2)->output_name, name, (*op2)->input_name);
          fprintf(stream, "struct %s\n{", (*op2)->output_name);
          (*op2)->output->generate(types, ";", anonymous, true, false);
          fprintf(stream, "\n};\n");
        }
      }
      fprintf(stream, "\n/// Operation \"%s\" of service binding \"%s\"\n\n/**\n\nOperation details:\n\n", (*op2)->input_name, name);
      if ((*op2)->documentation)
        text((*op2)->documentation);
      if ((*op2)->operation_documentation)
        text((*op2)->operation_documentation);
      if ((*op2)->input->documentation)
      { fprintf(stream, "Input request:\n");
	text((*op2)->input->documentation);
      }
      if ((*op2)->input->ext_documentation)
      { fprintf(stream, "Input request:\n");
        text((*op2)->input->ext_documentation);
      }
      if ((*op2)->output)
      { if ((*op2)->output->documentation)
        { fprintf(stream, "Output response:\n");
	  text((*op2)->output->documentation);
	}
        if ((*op2)->output->ext_documentation)
        { fprintf(stream, "Output response:\n");
	  text((*op2)->output->ext_documentation);
        }
      }
      if ((*op2)->output)
      { if ((*op2)->output->content)
	{ fprintf(stream, "  - Response has MIME content '%s'\n", ((*op2)->output->content->type?(*op2)->output->content->type:"?"));
	  fprintf(stream, "    TODO: this form of MIME content response is not automatically handled.\n    Use one-way request and implement code to parse response.\n");
        }
      }
      else
	fprintf(stream, "  - One-way message\n");
      if ((*op2)->style == document)
        fprintf(stream, "  - SOAP document/literal style\n");
      else
      { if ((*op2)->input->use == literal)
          fprintf(stream, "  - SOAP RPC literal style\n");
        else if ((*op2)->input->encodingStyle)
          fprintf(stream, "  - SOAP RPC encodingStyle=\"%s\"\n", (*op2)->input->encodingStyle);
        else
          fprintf(stream, "  - SOAP RPC encoded\n");
      }
      if ((*op2)->output)
      { if ((*op2)->input->use != (*op2)->output->use)
        { if ((*op2)->output->use == literal)
            fprintf(stream, "  - SOAP RPC literal response\n");
          else if ((*op2)->output->encodingStyle)
            fprintf(stream, "  - SOAP RPC response encodingStyle=\"%s\"\n", (*op2)->output->encodingStyle);
          else
            fprintf(stream, "  - SOAP RPC encoded response\n");
        }
      }
      if ((*op2)->soapAction)
      { if (*(*op2)->soapAction)
          fprintf(stream, "  - SOAP action=\"%s\"\n", (*op2)->soapAction);
      }
      for (vector<Message*>::const_iterator message = (*op2)->fault.begin(); message != (*op2)->fault.end(); ++message)
      { if ((*message)->message && (*message)->message->name)
          fprintf(stream, "  - SOAP Fault: %s\n", (*message)->name);
      }
      if (!(*op2)->input->header.empty())
        fprintf(stream, "  - Request message has mandatory header part(s):\n");
      for (vector<soap__header>::const_iterator inputheader = (*op2)->input->header.begin(); inputheader != (*op2)->input->header.end(); ++inputheader)
      { if ((*inputheader).part)
        { if ((*inputheader).use == encoded && (*inputheader).namespace_)
            fprintf(stream, "    - %s\n", types.aname(NULL, (*inputheader).namespace_, (*inputheader).part));
          else if ((*inputheader).partPtr() && (*inputheader).partPtr()->element)
            fprintf(stream, "    - %s\n", types.aname(NULL, NULL, (*inputheader).partPtr()->element));
        }
      }
      if ((*op2)->input->multipartRelated)
      { int k = 2;
        fprintf(stream, "  - Request message has MIME multipart/related attachments:\n");
        for (vector<mime__part>::const_iterator part = (*op2)->input->multipartRelated->part.begin(); part != (*op2)->input->multipartRelated->part.end(); ++part)
	{ if ((*part).soap__body_)
          { fprintf(stream, "    -# MIME attachment with SOAP Body and mandatory header part(s):\n");
            for (vector<soap__header>::const_iterator header = (*part).soap__header_.begin(); header != (*part).soap__header_.end(); ++header)
            { if ((*header).part)
              { if ((*header).use == encoded && (*header).namespace_)
                  fprintf(stream, "       - %s\n", types.aname(NULL, (*header).namespace_, (*header).part));
                else if ((*header).partPtr() && (*header).partPtr()->element)
                  fprintf(stream, "       - %s\n", types.aname(NULL, NULL, (*header).partPtr()->element));
              }
	    }
	  }
          else
          { fprintf(stream, "    -# MIME attachment %d:\n", k++);
	    for (vector<mime__content>::const_iterator content = (*part).content.begin(); content != (*part).content.end(); ++content)
	      fprintf(stream, "       - part=\"%s\" type=\"%s\"\n", (*content).part?(*content).part:"", (*content).type?(*content).type:"");
	  }
        }
      }
      if ((*op2)->input->layout)
        fprintf(stream, "  - Request message has DIME attachments in compliance with %s\n", (*op2)->input->layout);
      if ((*op2)->output)
      { if (!(*op2)->output->header.empty())
          fprintf(stream, "  - Response message has mandatory header part(s):\n");
        for (vector<soap__header>::const_iterator outputheader = (*op2)->output->header.begin(); outputheader != (*op2)->output->header.end(); ++outputheader)
        { if ((*outputheader).part)
          { if ((*outputheader).use == encoded && (*outputheader).namespace_)
              fprintf(stream, "    - %s\n", types.aname(NULL, (*outputheader).namespace_, (*outputheader).part));
            else if ((*outputheader).partPtr() && (*outputheader).partPtr()->element)
              fprintf(stream, "    - %s\n", types.aname(NULL, NULL, (*outputheader).partPtr()->element));
          }
        }
      }
      if ((*op2)->output && (*op2)->output_name && (*op2)->output->multipartRelated)
      { int k = 2;
        fprintf(stream, "  - Response message has MIME multipart/related attachments\n");
        for (vector<mime__part>::const_iterator part = (*op2)->output->multipartRelated->part.begin(); part != (*op2)->output->multipartRelated->part.end(); ++part)
	{ if ((*part).soap__body_)
          { fprintf(stream, "    -# MIME attachment with SOAP Body and mandatory header part(s):\n");
            for (vector<soap__header>::const_iterator header = (*part).soap__header_.begin(); header != (*part).soap__header_.end(); ++header)
            { if ((*header).part)
              { if ((*header).use == encoded && (*header).namespace_)
                  fprintf(stream, "       - %s\n", types.aname(NULL, (*header).namespace_, (*header).part));
                else if ((*header).partPtr() && (*header).partPtr()->element)
                  fprintf(stream, "       - %s\n", types.aname(NULL, NULL, (*header).partPtr()->element));
              }
	    }
	  }
          else
          { fprintf(stream, "    -# MIME attachment %d:\n", k++);
            for (vector<mime__content>::const_iterator content = (*part).content.begin(); content != (*part).content.end(); ++content)
	      fprintf(stream, "       - part=\"%s\" type=\"%s\"\n", (*content).part?(*content).part:"", (*content).type?(*content).type:"");
	  }
        }
      }
      if ((*op2)->output && (*op2)->output_name && (*op2)->output->layout)
        fprintf(stream, "  - Response message has DIME attachments in compliance with %s\n", (*op2)->output->layout);
      fprintf(stream, "\nC stub function (defined in soapClient.c[pp] after running soapcpp2):\n@code\n  int soap_call_%s(struct soap *soap,\n    NULL, // char *endpoint = NULL selects default endpoint for this operation\n    NULL, // char *action = NULL selects default action for this operation\n    // request parameters:", (*op2)->input_name);
      (*op2)->input->generate(types, ",", false, false, false);
      fprintf(stream, "\n    // response parameters:");
      if ((*op2)->output && (*op2)->output_name)
      { if (flag)
        { if ((*op2)->style == document)
	  { // Shortcut: do not generate wrapper struct
            (*op2)->output->generate(types, "", false, false, true);
          }
          else if ((*(*op2)->output->message->part.begin()).name)
	  { fprintf(stream, "\n");
            fprintf(stream, anonymous ? anonformat : paraformat, types.tname(NULL, NULL, (*(*op2)->output->message->part.begin()).type), cflag ? "*" : "&", types.aname(NULL, NULL, (*(*op2)->output->message->part.begin()).name), "");
	  }
	}
        else
          fprintf(stream, "\n    struct %s%s", (*op2)->output_name, cflag ? "*" : "&");
      }
      fprintf(stream, "\n  );\n@endcode\n\n");
      if (!cflag)
      { fprintf(stream, "C++ proxy class (defined in soap%sProxy.h):\n", name);
        fprintf(stream, "  class %s;\n\n", name);
      }
      fprintf(stream, "*/\n\n");
      (*op2)->generate(types);
    }
  }
}

////////////////////////////////////////////////////////////////////////////////
//
//	Operation methods
//
////////////////////////////////////////////////////////////////////////////////

void Operation::generate(Types &types)
{ bool flag = false, anonymous = parameterOrder != NULL;
  const char *method_name = strstr(input_name + 1, "__") + 2;
  if (!method_name)
    method_name = input_name;
  if (style == document)
    fprintf(stream, serviceformat, prefix, "method-style", method_name, "document");
  else
    fprintf(stream, serviceformat, prefix, "method-style", method_name, "rpc");
  if (input->use == literal)
    fprintf(stream, serviceformat, prefix, "method-encoding", method_name, "literal");
  else if (input->encodingStyle)
    fprintf(stream, serviceformat, prefix, "method-encoding", method_name, input->encodingStyle);
  else
    fprintf(stream, serviceformat, prefix, "method-encoding", method_name, "encoded");
  if (output)
  { if (input->use != output->use)
    { if (output->use == literal)
        fprintf(stream, serviceformat, prefix, "method-response-encoding", method_name, "literal");
      else if (output->encodingStyle)
        fprintf(stream, serviceformat, prefix, "method-response-encoding", method_name, output->encodingStyle);
      else
        fprintf(stream, serviceformat, prefix, "method-response-encoding", method_name, "encoded");
    }
    if (style == rpc && input->URI && output->URI && strcmp(input->URI, output->URI))
      fprintf(stream, schemaformat, types.nsprefix(NULL, output->URI), "namespace", output->URI);
  }
  if (soapAction)
  { if (*soapAction)
      fprintf(stream, serviceformat, prefix, "method-action", method_name, soapAction);
    else
      fprintf(stream, serviceformat, prefix, "method-action", method_name, "\"\"");
  }
  for (vector<Message*>::const_iterator message = fault.begin(); message != fault.end(); ++message)
  { if ((*message)->message && (*message)->message->name)
      fprintf(stream, serviceformat, prefix, "method-fault", method_name, (*message)->name);
  }
  if (input->multipartRelated)
  { for (vector<mime__part>::const_iterator inputmime = input->multipartRelated->part.begin(); inputmime != input->multipartRelated->part.end(); ++inputmime)
    { for (vector<soap__header>::const_iterator inputheader = (*inputmime).soap__header_.begin(); inputheader != (*inputmime).soap__header_.end(); ++inputheader)
      { if ((*inputheader).part)
        { if ((*inputheader).use == encoded && (*inputheader).namespace_)
            fprintf(stream, serviceformat, prefix, "method-input-header-part", method_name, types.aname(NULL, (*inputheader).namespace_, (*inputheader).part));
          else if ((*inputheader).partPtr() && (*inputheader).partPtr()->element)
            fprintf(stream, serviceformat, prefix, "method-input-header-part", method_name, types.aname(NULL, NULL, (*inputheader).partPtr()->element));
        }
      }
      for (vector<mime__content>::const_iterator content = (*inputmime).content.begin(); content != (*inputmime).content.end(); ++content)
        if ((*content).type)
          fprintf(stream, serviceformat, prefix, "method-input-mime-type", method_name, (*content).type);
    }
  }
  // TODO: add headerfault directives
  for (vector<soap__header>::const_iterator inputheader = input->header.begin(); inputheader != input->header.end(); ++inputheader)
  { if ((*inputheader).part)
    { if ((*inputheader).use == encoded && (*inputheader).namespace_)
        fprintf(stream, serviceformat, prefix, "method-input-header-part", method_name, types.aname(NULL, (*inputheader).namespace_, (*inputheader).part));
      else if ((*inputheader).partPtr() && (*inputheader).partPtr()->element)
        fprintf(stream, serviceformat, prefix, "method-input-header-part", method_name, types.aname(NULL, NULL, (*inputheader).partPtr()->element));
    }
  }
  if (output)
  { if (output->multipartRelated)
    { for (vector<mime__part>::const_iterator outputmime = output->multipartRelated->part.begin(); outputmime != output->multipartRelated->part.end(); ++outputmime)
      { for (vector<soap__header>::const_iterator outputheader = (*outputmime).soap__header_.begin(); outputheader != (*outputmime).soap__header_.end(); ++outputheader)
        { if ((*outputheader).part)
          { if ((*outputheader).use == encoded && (*outputheader).namespace_)
              fprintf(stream, serviceformat, prefix, "method-output-header-part", method_name, types.aname(NULL, (*outputheader).namespace_, (*outputheader).part));
            else if ((*outputheader).partPtr() && (*outputheader).partPtr()->element)
              fprintf(stream, serviceformat, prefix, "method-output-header-part", method_name, types.aname(NULL, NULL, (*outputheader).partPtr()->element));
          }
        }
        for (vector<mime__content>::const_iterator content = (*outputmime).content.begin(); content != (*outputmime).content.end(); ++content)
          if ((*content).type)
            fprintf(stream, serviceformat, prefix, "method-output-mime-type", method_name, (*content).type);
      }
    }
    for (vector<soap__header>::const_iterator outputheader = output->header.begin(); outputheader != output->header.end(); ++outputheader)
    { if ((*outputheader).part)
      { if ((*outputheader).use == encoded && (*outputheader).namespace_)
          fprintf(stream, serviceformat, prefix, "method-output-header-part", method_name, types.aname(NULL, (*outputheader).namespace_, (*outputheader).part));
        else if ((*outputheader).partPtr() && (*outputheader).partPtr()->element)
          fprintf(stream, serviceformat, prefix, "method-output-header-part", method_name, types.aname(NULL, NULL, (*outputheader).partPtr()->element));
      }
    }
  }
  if (output_name)
  { if (style == document)
      flag = output->message && output->message->part.size() == 1;
    else if (!wflag)
      flag = output->message && output->use == encoded && output->message->part.size() == 1 && !(*output->message->part.begin()).simpleTypePtr() && !(*output->message->part.begin()).complexTypePtr();
    if (flag && input->message && (*output->message->part.begin()).element)
      for (vector<wsdl__part>::const_iterator part = input->message->part.begin(); part != input->message->part.end(); ++part)
        if ((*part).element && !strcmp((*part).element, (*output->message->part.begin()).element))
          flag = false;
  }
  fprintf(stream, "int %s(", input_name);
  input->generate(types, ",", anonymous, true, false);
  if (output_name)
  { if (flag)
    { if (style == document)
      { // Shortcut: do not generate wrapper struct
        output->generate(types, "", anonymous, true, true);
      }
      else if ((*output->message->part.begin()).name)
      { fprintf(stream, "\n");
        fprintf(stream, anonymous ? anonformat : paraformat, types.tname(NULL, NULL, (*output->message->part.begin()).type), cflag ? "*" : "&", types.aname(NULL, NULL, (*output->message->part.begin()).name), "");
        fprintf(stream, "\t///< Response parameter");
      }
    }
    else
    { fprintf(stream, "\n    struct %-28s%s", output_name, cflag ? "*" : "&");
      fprintf(stream, "\t///< Response struct parameter");
    }
    fprintf(stream, "\n);\n");
  }
  else
    fprintf(stream, "\n    void\t///< One-way message: no response parameter\n);\n");
}

////////////////////////////////////////////////////////////////////////////////
//
//	Message methods
//
////////////////////////////////////////////////////////////////////////////////

void Message::generate(Types &types, const char *sep, bool anonymous, bool remark, bool response)
{ if (message)
  { for (vector<wsdl__part>::const_iterator part = message->part.begin(); part != message->part.end(); ++part)
    { if (!(*part).name)
        fprintf(stderr, "Error: no part name in message '%s'\n", message->name?message->name:"");
      else if (!body_parts || soap_strsearch(body_parts, (*part).name))
      { if (remark && (*part).documentation)
          comment("", (*part).name, "parameter", (*part).documentation);
        else
          fprintf(stream, "\n");
	if ((*part).element)
        { if ((*part).elementPtr())
          { const char *name, *type, *URI;
            name = (*part).elementPtr()->name;
            /* comment out to use a type that refers to an element defined with typedef */
            if ((*part).elementPtr()->type)
              type = (*part).elementPtr()->type;
            else
            /* */
              type = name;
            if ((*part).elementPtr()->schemaPtr())
              URI = (*part).elementPtr()->schemaPtr()->targetNamespace;
            else
              URI = NULL;
	    if (response)
            { const char *t = types.tname(NULL, URI, type);
	      fprintf(stream, anonymous ? anonformat : paraformat, t, strchr(t, '*') != NULL ? " " : cflag ? "*" : "&", types.aname(NULL, URI, name), sep);
	      if (remark)
	        fprintf(stream, "\t///< Response parameter");
	    }
	    else
            { fprintf(stream, anonymous ? anonformat : paraformat, types.pname(false, NULL, URI, type), " ", types.aname(NULL, URI, name), sep);
	      if (remark && *sep == ',')
	        fprintf(stream, "\t///< Request parameter");
	    }
          }
	  else
          { fprintf(stream, anonymous ? anonformat : paraformat, types.pname(false, NULL, NULL, (*part).element), " ", types.aname(NULL, NULL, (*part).element), sep);
	    if (remark)
              fprintf(stream, "\t///< TODO: Check element type (imported type)");
	  }
	}
        else if ((*part).type)
        { if (use == literal)
            fprintf(stderr, "Warning: part '%s' uses literal style and must refer to an element rather than a type\n", (*part).name);
	  if (response)
          { const char *t = types.tname(NULL, NULL, (*part).type);
	    fprintf(stream, anonymous ? anonformat : paraformat, t, strchr(t, '*') != NULL ? " " : cflag ? "*" : "&", types.aname(NULL, NULL, (*part).name), sep);
	    if (remark)
              fprintf(stream, "\t///< Response parameter");
	  }
          else
	  { fprintf(stream, anonymous ? anonformat : paraformat, types.pname(false, NULL, NULL, (*part).type), " ", types.aname(NULL, NULL, (*part).name), sep);
	    if (remark && *sep == ',')
              fprintf(stream, "\t///< Request parameter");
	  }
        }
        else
          fprintf(stderr, "Error: no wsdl:definitions/message/part/@type in part '%s'\n", (*part).name);
      }
    }
  }
  else
    fprintf(stderr, "Error: no wsdl:definitions/message\n");
}

////////////////////////////////////////////////////////////////////////////////
//
//	Miscellaneous
//
////////////////////////////////////////////////////////////////////////////////

static void comment(const char *start, const char *middle, const char *end, const char *text)
{ if (text)
  { if (strchr(text, '\r') || strchr(text, '\n'))
      fprintf(stream, "\n/** %s %s %s documentation:\n%s\n*/\n\n", start, middle, end, text);
    else
      fprintf(stream, "\n/// %s %s %s: %s\n", start, middle, end, text);
  }
}

static void page(const char *page, const char *title, const char *text)
{ if (text)
    fprintf(stream, "\n@page %s%s \"%s\"\n", page, title, text);
  else
    fprintf(stream, "\n@page %s%s\n", page, title);
}

static void section(const char *section, const char *title, const char *text)
{ if (text)
    fprintf(stream, "\n@section %s%s \"%s\"\n", section, title, text);
  else
    fprintf(stream, "\n@section %s%s\n", section, title);
}

static void banner(const char *text)
{ int i;
  fprintf(stream, "\n/");
  for (i = 0; i < 78; i++)
    fputc('*', stream);
  fprintf(stream, "\\\n *%76s*\n * %-75s*\n *%76s*\n\\", "", text, "");
  for (i = 0; i < 78; i++)
    fputc('*', stream);
  fprintf(stream, "/\n\n");
}

static void ident()
{ time_t t = time(NULL), *p = &t;
  char tmp[256];
  int i;
  strftime(tmp, 256, "%Y-%m-%d %H:%M:%S GMT", gmtime(p));
  fprintf(stream, "/* %s\n   Generated by wsdl2h "VERSION" from ", outfile?outfile:"");
  if (infiles)
  { for (i = 0; i < infiles; i++)
      fprintf(stream, "%s ", infile[i]);
  }
  else
    fprintf(stream, "(stdin) ");
  fprintf(stream, "and %s\n   %s\n   Copyright (C) 2001-2005 Robert van Engelen, Genivia Inc. All Rights Reserved.\n   This part of the software is released under one of the following licenses:\n   GPL or Genivia's license for commercial use.\n*/\n\n", mapfile, tmp);
}

static void text(const char *text)
{ const char *s = text;
  if (!s)
    return;
  while (*s)
  { switch (*s)
    { case '\n':
      case '\t':
      case ' ':
	fputc(*s, stream);
        break;
      case '/':
	fputc(*s, stream);
        if (s[1] == '*')
	  fputc(' ', stream);
        break;
      case '*':
	fputc(*s, stream);
        if (s[1] == '/')
	  fputc(' ', stream);
        break;
      default:
        if (*s > 32)
	  fputc(*s, stream);
    }
    s++;
  }
  fputc('\n', stream);
}
