Our SOAP publishes wsdl's so people are to generate stubs off those. Standard soap data types and (only standard soap types) are used and WS-Security is used for security.
The web service end points are stateless so you need to set the WS-Security for each request made.
The soap web services are intended for server to server communications, not server to browser.
These soap services are intended to be compatible with all programming languages (so don't try and send java.util.Collections objects like List or Map, they will not unmarshall properly in different frameworks).
For versioning of methods and transfer objects we're just appending a version number to the method/object name, i.e. login(), login2(), login3() etc. In general you should use the latest / largest version number of any method or object that you can find. The older methods and objects are deprecated and will be removed in the future.
In general no method nor transfer object should ever be changed after it is created. You must make a new object/method with an incremented number as per above. This helps ensure backwards compatibility. The logic of how you generate the transfer objects or how you achieve the method results may change (and most likely will have to change) but the signature itself must not.
We're using CXF for our SOAP implementation.