Hi All:

I am trying to build SVN 2.2.x (I just updated from SVN) to test a patch (I do 
not have a test yet) just to see what happens if SAAJOutInterceptor uses a 
W3CDOMStreamWriter even if the local variable is null. Since that caused a test 
to hang I thought I'd try to build an unchanged 2.2.6 as a baseline. I get the 
errors below when I run:

mvn clean install -Peverything

Does 2.2.x build ok for anyone out there?

Results :

Failed tests:
  testExcludeNSWithPackageName(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  
testBug305924ForNestedBinding(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  
testParameterOrderNoOutputMessage(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  
testParameterOrderDifferentNS(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)

Tests in error:
  
testHelloWorldExternalBindingFile(org.apache.cxf.tools.wsdlto.jaxws.CodeGenOptionTest)
  testFlagForGenStandAlone(org.apache.cxf.tools.wsdlto.jaxws.CodeGenOptionTest)
  testFlagForGenAdditional(org.apache.cxf.tools.wsdlto.jaxws.CodeGenOptionTest)
  testHeaderFromAnotherMessage1(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testHeaderFromAnotherMessage2(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testHeaderFromAnotherMessage3(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testHeaderFromAnotherMessage4(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testHeaderFromAnotherMessage5(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testRPCLit(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testAsyncMethod(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testAsyncMethodNoService(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testHelloWorldSoap12(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testHelloWorld(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testHelloWorldWithDummyPlugin(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testDocLitHolder(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testSchemaImport(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testExceptionNameCollision(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testAllNameCollision(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testImportNameCollision(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testSoapHeader(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testHolderHeader(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testWSAddress(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testVoidInOutMethod(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testWsdlImport(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testWebFault(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testMultiSchemaParsing(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testDefaultParameterOrder(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testSupportXMLBindingBare(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testSupportXMLBindingWrapped(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testRouterWSDL(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testWSDLContainsJavaKeywords(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testWSDLWithEnumType(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testSWAMime(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testRPCHeader(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testRefTNS(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testWebFaultAnnotaion(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testGlobalBinding(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testXmlSeeAlso(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testWSAction(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testHandlerAnnotation(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testGenerateXmlListAnno(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testWrapperWithWildcard(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testCXF1950(org.apache.cxf.tools.wsdlto.jaxws.CodeGenTest)
  testLogicalOnlyWSDL(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testBug305729(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testBug305773(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testBug305700(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testNamespacePackageMapping1(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testNamespacePackageMapping2(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testNamespacePackageMapping3(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testBug305772(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testCommandLine(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testLocatorWithJaxbBinding(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testWsdlNoService(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testNoServiceImport(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testServiceNS(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testNoServiceNOPortType(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testDefatultNsMap(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testDefatultNsMapExclude(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  
testHelloWorldExternalBindingFile(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testWebResult(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testCXF627(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testRecursiveImport(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testCXF804(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testDefinieServiceName(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testAntFile(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testAsyncImplAndClient(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testZeroInputOutOfBandHeader(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testBindingForImportWSDL(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testReuseJaxwsBindingFile(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testBindingXPath(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testJaxbCatalog(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testCatalog2(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testCatalog3(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testServer(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testTwoJaxwsBindingFile(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testJaxwsBindingJavaDoc(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testWSAActionAnno(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testCXF964(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testCXF1620(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testCXF1048(org.apache.cxf.tools.wsdlto.jaxws.CodeGenBugTest)
  testJaxbNpa(org.apache.cxf.tools.wsdlto.jaxb.JAXBCodeGenOptionTest)

Tests run: 124, Failures: 4, Errors: 82, Skipped: 1

> -----Original Message-----
> From: Daniel Kulp [mailto:[email protected]]
> Sent: Tuesday, December 22, 2009 10:06
> To: [email protected]
> Cc: Gary Gregory
> Subject: Re: Inflexible fault interceptor chain?
>
>
> Can you create a small test case and attach to a jira?
>
> This definitely sounds like bug of some sort.   When I redid the
> Provider
> based services, I noticed that strange code in the StaxOutInterceptor
> as well
> and tried to remove it.   However, that broke some of the JAX-WS tck
> tests.
> I don't remember the exact reason.   I think it has something to do
> with
> faults thrown from the logical or soap handlers on the outgoing chain
> needed
> some strange and wacky processing.     Don't really remember.
>
> If we can get your test case, we may be able to get it to work better.
>
> That said, you could probably write your own interceptor (you seem to
> be good
> at that :-)  that would run on the fault chain prior to the SAAJOut and
> have
> it remove the SAAJ model from the message.   You may need to trace
> through a
> couple other interceptors (like SoapOutInterceptor) to see if other
> properties
> need to be removed/reset.
>
> Dan
>
>
> On Mon December 21 2009 8:12:50 pm Gary Gregory wrote:
> > Hello Dan and all,
> >
> > Ok, the SAAJOutInterceptor solution almost worked. The behavior I
> describe
> >  below is the same in CXF 2.2.4 and 2.2.6-SNAPSHOT (as of Saturday's
> >  build). I am not on 2.2.5 due to some bugs that are fixed in 2.2.6.
> The
> >  debugging information I gathered for this message is with 2.2.4.
> >
> > I have two scenarios, one works and one does not with the
> >  SAAJOutInterceptor solution.
> >
> > If a Fault is thrown by a custom interceptor at a certain point in
> the
> >  output chain, the wrong SOAP XML is generated, specifically no SOAP
> fault
> >  XML elements are generated. Let me start by showing what works and
> why
> >  before showing what does not and why.
> >
> > In the first scenario, which works, a SoapFault is thrown by our
> provider's
> >  invoke(SOAPMessage) method under certain conditions, basically if
> our
> >  server detects certain errors. Our provider looks like this:
> >
> > @WebServiceProvider
> > @ServiceMode(value = Service.Mode.MESSAGE)
> > public static class LdeWebServiceProvider implements
> Provider<SOAPMessage>
> >  { @Override
> >    public SOAPMessage invoke(SOAPMessage soapRequest) {
> >       ...
> >       throw new SoapFault("Our message",
> >  Soap11.getInstance().getReceiver()); }
> > }
> >
> > In SAAJOutInterceptor.handleMessage, the local variable saaj is null,
> so
> >  the code path taken builds a SOAP message from scratch and plugs in
> a
> >  W3CDOMStreamWriter. All of the interceptors then write to
> >  W3CDOMStreamWriter instead of the default XMLStreamWriter which
> normally
> >  caches and writes to the HTTP wire. The W3CDOMStreamWriter allows me
> to
> >  transform the DOM before it gets on the wire. Great stuff, it works.
> >
> > In the second scenario, I test our output feature where in addition
> to an
> >  optional transformation, we have custom interceptors to do optional
> XML
> >  validation before and after the XML transformation. After our
> provider
> >  successfully processed a message, the output chain processing kicks
> in and
> >  looks like this:
> >
> > Chain org.apache.cxf.phase.phaseinterceptorch...@c375934. Current
> flow:
> >   setup [PolicyOutInterceptor]
> >   pre-logical [SwAOutInterceptor, SoapHeaderOutFilterInterceptor]
> >   post-logical [SoapPreProtocolOutInterceptor]
> >   prepare-send [MessageSenderInterceptor, MessageModeOutInterceptor]
> >   pre-stream [LoggingOutInterceptor, XmlDeclOutInterceptor*,
> >  AttachmentOutInterceptor, StaxOutInterceptor] pre-protocol
> >  [MessageModeOutInterceptorInternal, SAAJOutInterceptor,
> >  SOAPHandlerInterceptor, OurWSS4JOutInterceptor] write
> [SoapOutInterceptor]
> >   pre-marshal [LogicalHandlerOutInterceptor,
> ValidatingOutInterceptor*,
> >  TransformOutInterceptor*, ValidatingOutInterceptor*] marshal
> >  [BareOutInterceptor]
> >   write-ending [SoapOutEndingInterceptor]
> >   pre-protocol-ending [SAAJOutEndingInterceptor]
> >   pre-stream-ending [StaxOutEndingInterceptor]
> >   prepare-send-ending [MessageSenderEndingInterceptor]
> >
> > The interceptors marked with * are mine:
> > - XmlDeclOutInterceptor forces the XML declaration to be written.
> > - ValidatingOutInterceptor validates XML
> > - TransformOutInterceptor transforms XML
> > - ValidatingOutInterceptor validates XML
> >
> > The problem occurs if XML validation fails (the first validation in
> this
> >  test).
> >
> > When the XML validation fails, an exception thrown, caught, and re-
> thrown
> >  as a fault.
> >
> > At the start of fault processing, the chain when SAAJOutInterceptor
> is
> >  called looks like this:
> >
> >   Chain org.apache.cxf.phase.phaseinterceptorch...@77c16c5f. Current
> flow:
> >   setup [ServerPolicyOutFaultInterceptor]
> >   prepare-send [MessageSenderInterceptor, Soap11FaultOutInterceptor]
> >   pre-stream [LoggingOutInterceptor, XmlDeclOutInterceptor*,
> >  StaxOutInterceptor] pre-protocol [WebFaultOutInterceptor,
> >  SAAJOutInterceptor, SOAPHandlerFaultOutInterceptor] write
> >  [SoapOutInterceptor]
> >   pre-marshal [LogicalHandlerFaultOutInterceptor]
> >   marshal [Soap11FaultOutInterceptorInternal]
> >   pre-protocol-ending [TransformOutFaultInterceptor*]
> >   prepare-send-ending [MessageSenderEndingInterceptor]
> >
> > The interceptors marked with * are mine:
> > - XmlDeclOutInterceptor forces the XML declaration to be written.
> > - TransformOutFaultInterceptor validates XML
> >
> > When I step through this SAAJOutInterceptor invocation, the saaj
> variable
> >  is NOT null, so the code path taken is different from what I
> described
> >  above. Instead of a W3CDOMStreamWriter, a dummy XMLStreamWriter is
> created
> >  that throws away whatever is written to it:
> >
> >             //as the SOAPMessage already has everything in place, we
> do not
> >  need XMLStreamWriter to write //anything for us, so we just set
> >  XMLStreamWriter's output to a dummy output stream. XMLStreamWriter
> >  origWriter = message.getContent(XMLStreamWriter.class);
> >  message.put(ORIGINAL_XML_WRITER, origWriter);
> >
> >             XMLStreamWriter dummyWriter =
> >  StaxUtils.createXMLStreamWriter(new OutputStream() { public void
> write(int
> >  b) throws IOException {
> >                     }
> >                     public void write(byte b[], int off, int len)
> throws
> >  IOException { }
> >                 });
> >             message.setContent(XMLStreamWriter.class, dummyWriter);
> >
> > No wonder I get no SOAP fault information back, I get:
> >
> > <?xml version='1.0' encoding='ISO-8859-1'?>
> > <SOAP-ENV:Envelope
> >  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
> >  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/";> <SOAP-
> ENV:Header
> >  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";>
> <ais:requestID
> >
> xmlns:ais="http://com.seagullsw.appinterface/AppInterfaceServer";>{c0a80
> 102
> > -00ce16ad0000010e75da25398002}</ais:requestID> </SOAP-ENV:Header>
> >     <SOAP-ENV:Body xmlns:SOAP-
> ENV="http://schemas.xmlsoap.org/soap/envelope/";
> >  /> </SOAP-ENV:Envelope>
> >
> > Is this a bug? Why would there be a dummy writer put in place? Is
> there
> >  another CXF way to do this?
> >
> > Thank you,
> > Gary
> >
> > > -----Original Message-----
> > > From: Gary Gregory
> > > Sent: Friday, December 18, 2009 18:11
> > > To: 'Daniel Kulp'; [email protected]
> > > Subject: RE: Inflexible fault interceptor chain?
> > >
> > > Ok, that worked!
> > >
> > > Thank you Dan,
> > > Gary
> > >
> > > > -----Original Message-----
> > > > From: Daniel Kulp [mailto:[email protected]]
> > > > Sent: Friday, December 18, 2009 07:33
> > > > To: [email protected]
> > > > Cc: Gary Gregory; Lee Breisacher; Nikolay Glazyrin
> > > > Subject: Re: Inflexible fault interceptor chain?
> > > >
> > > >
> > > > Honestly, the EASIEST way to accomplish this, since you are using
> > >
> > > soap,
> > >
> > > > is to
> > > > add the SAAJOutInterceptor to the fault chain.  Then, your
> > >
> > > interceptor
> > >
> > > > would
> > > > live right before it's "ending" interceptor and do:
> > > >
> > > > message.getContext(SOAPMessage.class)
> > > >
> > > > to get the SAAJ model out.   Since the SAAJ model implements the
> DOM
> > > > interfaces, you can then feed that into an XSLT processor or
> similar
> > >
> > > to
> > >
> > > > transform it and then set a new version back with the setContent
> > >
> > > call.
> > >
> > > > Dan
> > > >
> > > > On Fri December 18 2009 4:13:29 am Gary Gregory wrote:
> > > > > Hi All:
> > > > >
> > > > > I need to apply an XSL transformation to messages coming out of
> CXF
> > > >
> > > > (our
> > > >
> > > > >  users configure what the XSL looks like.) For a normal
> > >
> > > (successful)
> > >
> > > > >  message, I have an interceptor (during Phase.PRE_MARSHAL) that
> > >
> > > uses
> > >
> > > > the
> > > >
> > > > >  DOM aspect of a message. That works great. BTW, I get to the
> DOM
> > > >
> > > > like
> > > >
> > > > >  this:
> > > > >
> > > > > Node node = (Node) message.getContent(List.class).get(0);
> > > > >
> > > > > That seems brittle, is there a safer way to get to an aspect of
> the
> > > >
> > > > message
> > > >
> > > > >  I can feed to javax.xml.transform?
> > > > >
> > > > > The real issue comes with fault messages because the fault
> chain
> > >
> > > uses
> > >
> > > > an
> > >
> > >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > >
> > > > XML
> > > >
> > > > > StreamWriter.html>. The fault chain looks like this:
> > > > >
> > > > > Chain org.apache.cxf.phase.phaseinterceptorch...@3015b303.
> Current
> > > >
> > > > flow:
> > > > >   setup [ServerPolicyOutFaultInterceptor]
> > > > >   prepare-send [MessageSenderInterceptor,
> > >
> > > Soap11FaultOutInterceptor]
> > >
> > > > >   pre-stream [LoggingOutInterceptor, XmlDeclOutInterceptor*,
> > > > >  StaxOutInterceptor] pre-protocol [WebFaultOutInterceptor,
> > > > >  SOAPHandlerFaultOutInterceptor] write [SoapOutInterceptor]
> > > > >   pre-marshal [LogicalHandlerFaultOutInterceptor]
> > > > >   marshal [Soap11FaultOutInterceptorInternal]
> > > > >   pre-stream-ending [StaxOutEndingInterceptor,
> > > > >  TransformOutFaultInterceptor*] prepare-send-ending
> > > > >  [MessageSenderEndingInterceptor]
> > > > >
> > > > > FYI, the interceptors marked with * are our own:
> > > > >
> > > > > *         XmlDeclOutInterceptor forces an XML declaration to be
> > > >
> > > > written.
> > > >
> > > > > *         TransformOutFaultInterceptor is where I thought I
> could
> > > >
> > > > transform
> > > >
> > > > >  the fault XML message.
> > > > >
> > > > > The
> > >
> > >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > >
> > > > XML
> > > >
> > > > > StreamWriter.html> looks like this:
> > > > >
> > > > > [StreamWriter: class com.ctc.wstx.sw.SimpleNsStreamWriter,
> > >
> > > underlying
> > >
> > > > >  outputter:
> > >
> > >
> com.ctc.wstx.sw.isolatin1xmlwri...@1125cf44<mailto:com.ctc.wstx.sw.ISOL
> > >
> > > > ati
> > > >
> > > > > n1xmlwri...@1125cf44>
> > > > >
> > > > > The com.ctc.wstx.sw.ISOLatin1XmlWriter wraps a
> > > > >  org.apache.cxf.io.CachedOutputStream, which in turns wraps:
> > > > >
> > > > > *         currentStream - LoadingByteArrayOutputStream
> > > > >
> > > > > *         flowThroughStream -
> > > >
> > > > AbstractHTTPDestination$WrappedOutputStream
> > > >
> > > > > All of this to say that when the chain's interceptors are
> working
> > > >
> > > > with the
> > > >
> > > > >  message's
> > >
> > >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > >
> > > > XML
> > > >
> > > > > StreamWriter.html>, the bytes are cached and written to the
> wire.
> > >
> > > It
> > >
> > > > is not
> > > >
> > > > >  possible to catch the fault XML message and change it.
> > > > >
> > > > > The only thing I've come up with but not implemented yet would
> be
> > >
> > > to
> > >
> > > > insert
> > > >
> > > > >  an interceptor before the XML declaration is written and put
> the
> > >
> > >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > >
> > > > XML
> > > >
> > > > > StreamWriter.html> into a temp spot in the message content map,
> > >
> > > then
> > >
> > > > put a
> > > >
> > > > >  new
> > >
> > >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > >
> > > > XML
> > > >
> > > > > StreamWriter.html> on a byte array in its place. A pre-stream-
> > >
> > > ending
> > >
> > > > >  interceptor can take those bytes, apply XSL to them and then
> write
> > > >
> > > > them to
> > > >
> > > > >  the original
> > >
> > >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > >
> > > > XML
> > > >
> > > > > StreamWriter.html>, before putting the original
> > >
> > >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > >
> > > > XML
> > > >
> > > > > StreamWriter.html> back in it original slot in the message
> content
> > > >
> > > > map.
> > > >
> > > > > That seems like big old hack.
> > > > >
> > > > > Any ideas on a cleaner solution?
> > > > >
> > > > > Thank you,
> > > > > Gary Gregory
> > > > > Seagull Software
> > > > > [email protected]
> > > > > www.seagullsoftware.com
> > > >
> > > > --
> > > > Daniel Kulp
> > > > [email protected]
> > > > http://www.dankulp.com/blog
> >
>
> --
> Daniel Kulp
> [email protected]
> http://www.dankulp.com/blog

Reply via email to