/*
 * eXist-db Open Source Native XML Database
 * Copyright (C) 2001 The eXist-db Authors
 *
 * info@exist-db.org
 * http://www.exist-db.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package org.exist.xquery.functions.fn;

import org.apache.commons.lang3.StringUtils;
import org.exist.dom.QName;
import org.exist.util.serializer.XQuerySerializer;
import org.exist.xquery.*;
import org.exist.xquery.value.*;
import org.xml.sax.SAXException;

import javax.xml.transform.OutputKeys;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Properties;

/**
 * @author Dannes Wessels
 * @author <a href="mailto:wolfgang@exist-db.org">Wolfgang Meier</a>
 */
public class FunTrace extends BasicFunction {
    
    public final static FunctionSignature[] signatures = {
            new FunctionSignature(
                    new QName("trace", Function.BUILTIN_FUNCTION_NS),
                    "This function is intended to be used in debugging queries by "
                            + "providing a trace of their execution. The input $value is "
                            + "returned, unchanged, as the result of the function. "
                            + "In addition, the input $value, converted to an xs:string, "
                            + "is directed to a trace data set in the eXist log files.",
                    new SequenceType[]{
                            new FunctionParameterSequenceType("value", Type.ITEM, Cardinality.ZERO_OR_MORE, "The value"),
                    },
                    new FunctionReturnSequenceType(Type.ITEM, Cardinality.ZERO_OR_MORE, "the labelled $value in the log")
            ),
        new FunctionSignature(
                new QName("trace", Function.BUILTIN_FUNCTION_NS),
                "This function is intended to be used in debugging queries by "
                        + "providing a trace of their execution. The input $value is "
                        + "returned, unchanged, as the result of the function. "
                        + "In addition, the inputs $value, converted to an xs:string, "
                        + "and $label is directed to a trace data set in the eXist log files.",
                new SequenceType[]{
                        new FunctionParameterSequenceType("value", Type.ITEM, Cardinality.ZERO_OR_MORE, "The value"),
                        new FunctionParameterSequenceType("label", Type.STRING, Cardinality.EXACTLY_ONE, "The label in the log file")
                },
                new FunctionReturnSequenceType(Type.ITEM, Cardinality.ZERO_OR_MORE, "the labelled $value in the log")
        )
    };
    
    public FunTrace(final XQueryContext context, final FunctionSignature signature) {
        super(context, signature);
    }
    
/*
 * (non-Javadoc)
 * @see org.exist.xquery.BasicFunction#eval(Sequence[], Sequence)
 */
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {

    // Get value for label, default to "-"
    String label = (args.length == 2) ? StringUtils.defaultIfBlank(args[1].getStringValue(), "-") : "-";

    Sequence result;

    if (args[0].isEmpty()) {
        // Write to log
        LOG.debug("{} [{}] [{}]: {}", label, "-", Type.getTypeName(Type.EMPTY), "-");
        result = Sequence.EMPTY_SEQUENCE;
            
        } else {
            // Copy all Items from input to output sequence
            result = new ValueSequence();
            
            int position = 0;

            // Force adaptive serialization
            final Properties props = new Properties();
            props.setProperty(OutputKeys.METHOD, "adaptive");

            for (final SequenceIterator i = args[0].iterate(); i.hasNext();) {

                // Get item
                final Item next = i.nextItem();

                // Only write if logger is set to debug mode
                if (LOG.isDebugEnabled()) {

                    position++;

                    try (StringWriter writer = new StringWriter()) {
                        XQuerySerializer xqs = new XQuerySerializer(context.getBroker(), props, writer);
                        xqs.serialize(next.toSequence());

                        // Write to log
                        LOG.debug("{} [{}] [{}]: {}", label, position, Type.getTypeName(next.getType()), writer.toString());

                    } catch (IOException | SAXException e) {
                        throw new XPathException(this, e.getMessage());
                    }

                }

                // Add to result
                result.add(next);
            }
        }

        return result;
    }
}

@@ -3561,24 +3561,30 @@
 quence eval(
+final 
 Sequence%5B%5D a
@@ -3587,16 +3587,22 @@
 %5B%5D args,
+ final
  Sequenc
@@ -3692,16 +3692,22 @@
 %22-%22%0A    
+final 
 String l
@@ -3804,16 +3804,22 @@
 %22;%0A%0A    
+final 
 Sequence
@@ -4668,16 +4668,22 @@
    try (
+final 
 StringWr
@@ -4742,16 +4742,22 @@
         
+final 
 XQuerySe
@@ -5083,16 +5083,22 @@
  catch (
+final 
 IOExcept

Add finals