/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_forms.hxx"

#include "model.hxx"
#include "model_helper.hxx"
#include "mip.hxx"
#include "evaluationcontext.hxx"
#include "unohelper.hxx"
#include "submission/serialization_app_xml.hxx"
#include "resourcehelper.hxx"
#include "xmlhelper.hxx"
#include "convert.hxx"

#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include <tools/debug.hxx>

// UNO classes
#include <com/sun/star/xml/dom/XNode.hpp>
#include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
#include <com/sun/star/xml/dom/XDocumentFragment.hpp>
#include <com/sun/star/xml/dom/XNamedNodeMap.hpp>
#include <com/sun/star/xml/xpath/XXPathObject.hpp>
#include <com/sun/star/xml/xpath/XPathObjectType.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XTextInputStream.hpp>
#include <com/sun/star/container/XEnumeration.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/xforms/XFormsSupplier.hpp>
#include <com/sun/star/xforms/XDataTypeRepository.hpp>
#include <com/sun/star/xsd/XDataType.hpp>
#include <com/sun/star/xsd/DataTypeClass.hpp>


using rtl::OUString;
using rtl::OUStringBuffer;
using com::sun::star::beans::PropertyValue;
using com::sun::star::io::XInputStream;
using com::sun::star::io::XActiveDataSink;
using com::sun::star::io::XTextInputStream;
using com::sun::star::container::XEnumeration;
using com::sun::star::container::XNameContainer;
using com::sun::star::xforms::XFormsSupplier;

using namespace xforms;
using namespace com::sun::star::uno;
using namespace com::sun::star::xml::dom;
using namespace com::sun::star::xml::xpath;



//
// implement XFormsUIHelper1
//

OUString Model::getDefaultServiceNameForNode( const XNode_t& xNode )
    throw( RuntimeException )
{
    // determine service for control. string/text field is default.
    OUString sService = OUSTRING("com.sun.star.form.component.TextField");

    // query repository for suitable type
    OSL_ENSURE( mxDataTypes.is(), "no type repository?" );
    OUString sTypeName = queryMIP( xNode ).getTypeName();
    if( mxDataTypes->hasByName( sTypeName ) )
    {
        OSL_ENSURE( mxDataTypes->getDataType( sTypeName ).is(),
                    "has or has not?" );

        switch( mxDataTypes->getDataType( sTypeName )->getTypeClass() )
        {
        case com::sun::star::xsd::DataTypeClass::BOOLEAN:
            sService = OUSTRING("com.sun.star.form.component.CheckBox");
            break;
        case com::sun::star::xsd::DataTypeClass::DOUBLE:
        case com::sun::star::xsd::DataTypeClass::DECIMAL:
        case com::sun::star::xsd::DataTypeClass::FLOAT:
            sService = OUSTRING("com.sun.star.form.component.NumericField");
            break;

        case com::sun::star::xsd::DataTypeClass::STRING:
        case com::sun::star::xsd::DataTypeClass::DURATION:
        case com::sun::star::xsd::DataTypeClass::DATETIME:
        case com::sun::star::xsd::DataTypeClass::TIME:
        case com::sun::star::xsd::DataTypeClass::DATE:
        case com::sun::star::xsd::DataTypeClass::gYearMonth:
        case com::sun::star::xsd::DataTypeClass::gYear:
        case com::sun::star::xsd::DataTypeClass::gMonthDay:
        case com::sun::star::xsd::DataTypeClass::gDay:
        case com::sun::star::xsd::DataTypeClass::gMonth:
        case com::sun::star::xsd::DataTypeClass::hexBinary:
        case com::sun::star::xsd::DataTypeClass::base64Binary:
        case com::sun::star::xsd::DataTypeClass::anyURI:
        case com::sun::star::xsd::DataTypeClass::QName:
        case com::sun::star::xsd::DataTypeClass::NOTATION:
        default:
            // keep default
            break;
        }
    }

    return sService;
}


void lcl_OutPosition( OUStringBuffer& rBuffer,
                      const Reference<XNode>& xNode )
{
    OSL_ENSURE( xNode->getParentNode().is(), "need parent" );

    // count # of occurences of this node
    sal_Int32 nFound = 0;
    sal_Int32 nPosition = -1;
    if( xNode->getParentNode().is() )
    {
        for( Reference<XNode> xIter = xNode->getParentNode()->getFirstChild();
             xIter != NULL;
             xIter = xIter->getNextSibling() )
        {
            if( xIter->getNodeType() == xNode->getNodeType() &&
                xIter->getNodeName() == xNode->getNodeName() &&
                xIter->getNamespaceURI() == xNode->getNamespaceURI() )
            {
                nFound++;
                if( xIter == xNode )
                    nPosition = nFound;
            }
        }
    }
    OSL_ENSURE( nFound > 0  &&  nPosition > 0, "node not found???" );

    // output position (if necessary)
    if( nFound > 1 )
    {
        rBuffer.insert( 0, sal_Unicode(']') );
        rBuffer.insert( 0, nPosition );
        rBuffer.insert( 0, sal_Unicode('[') );
    }
}

void lcl_OutName( OUStringBuffer& rBuffer,
                  const Reference<XNode>& xNode )
{
    rBuffer.insert( 0, xNode->getNodeName() );
    OUString sPrefix = xNode->getPrefix();
    if( sPrefix.getLength() > 0 )
    {
        rBuffer.insert( 0, sal_Unicode(':') );
        rBuffer.insert( 0, sPrefix );
    }
}

void lcl_OutInstance( OUStringBuffer& rBuffer,
                      const Reference<XNode>& xNode,
                      Model* pModel )
{
    Reference<XDocument> xDoc = xNode->getOwnerDocument();
    
    if( xDoc != pModel->getDefaultInstance() )
    {
        rBuffer.insert( 0, OUSTRING("')") );

        // iterate over instances, and find the right one
        OUString sInstanceName;
        Reference<XEnumeration> xEnum = 
            pModel->getInstances()->createEnumeration();
        while( ( sInstanceName.getLength() == 0 ) && xEnum->hasMoreElements() )
        {
            Sequence<PropertyValue> aValues;
            xEnum->nextElement() >>= aValues;

            // get ID and instance
            OUString sId;
            Reference<XDocument> xInstance;
            getInstanceData( aValues, &sId, &xInstance, NULL, NULL );

            // now check whether this was our instance:
            if( xInstance == xDoc )
                sInstanceName = sId;
        }

        rBuffer.insert( 0, sInstanceName );
        rBuffer.insert( 0, OUSTRING("instance('") );
    }
}

OUString Model::getDefaultBindingExpressionForNode(
    const XNode_t& xNode,
    const EvaluationContext& rContext)
{
    OSL_ENSURE( xNode.is(), "need node" );

    // iterate upwards and put sections into the expression buffer.
    // Stop iteration either at context node (relative expression) or
    // at document root, whichever occurs first.
    OUStringBuffer aBuffer;
    for( Reference<XNode> xCurrent = xNode;
         xCurrent.is()  &&  xCurrent != rContext.mxContextNode;
         xCurrent = xCurrent->getParentNode() )
    {
        // insert a '/' for every step except the first
        if( aBuffer.getLength() > 0 )
            aBuffer.insert( 0, sal_Unicode('/') );

        switch( xCurrent->getNodeType() )
        {
        case NodeType_ELEMENT_NODE:
            lcl_OutPosition( aBuffer, xCurrent );
            lcl_OutName( aBuffer, xCurrent );
            break;

        case NodeType_TEXT_NODE:
            lcl_OutPosition( aBuffer, xCurrent );
            aBuffer.insert( 0, OUSTRING("text()") );
            break;

        case NodeType_ATTRIBUTE_NODE:
            lcl_OutName( aBuffer, xCurrent );
            aBuffer.insert( 0, sal_Unicode('@') );
            break;

        case NodeType_DOCUMENT_NODE:
            // check for which instance we have
            lcl_OutInstance( aBuffer, xCurrent, this );
            break;

        default:
            // unknown type? fail!
            OSL_ENSURE( false, "unknown node type!" );
            xCurrent.set( NULL );
            aBuffer.makeStringAndClear();
            // we'll remove the slash below
            aBuffer.insert( 0, sal_Unicode('/') );
            break;
        }
    }

    return aBuffer.makeStringAndClear();
}



OUString Model::getDefaultBindingExpressionForNode( const XNode_t& xNode )
    throw( RuntimeException )
{
    return getDefaultBindingExpressionForNode( xNode, getEvaluationContext() );
}

bool lcl_isWhitespace( const OUString& rString )
{
    sal_Int32 nLength = rString.getLength();
    const sal_Unicode* pStr = rString.getStr();

    bool bWhitespace = true;
    for( sal_Int32 i = 0; bWhitespace && ( i < nLength ); i++ )
    {
        sal_Unicode c = pStr[i];
        bWhitespace = ( c == sal_Unicode(0x09) ||
                        c == sal_Unicode(0x0A) ||
                        c == sal_Unicode(0x0D) ||
                        c == sal_Unicode(0x20) );
    }
    return bWhitespace;
}

OUString Model::getNodeDisplayName( const XNode_t& xNode,
                                    sal_Bool bDetail )
    throw( RuntimeException )
{
    OUStringBuffer aBuffer;

    switch( xNode->getNodeType() )
    {
    case NodeType_ELEMENT_NODE:
        lcl_OutName( aBuffer, xNode );
        break;

    case NodeType_TEXT_NODE:
        {
            OUString sContent = xNode->getNodeValue();
            if( bDetail || ! lcl_isWhitespace( sContent ) )
            {
                aBuffer.append( sal_Unicode('"') );
                aBuffer.append( Convert::collapseWhitespace( sContent ) );
                aBuffer.append( sal_Unicode('"') );
            }
        }
        break;

    case NodeType_ATTRIBUTE_NODE:
        lcl_OutName( aBuffer, xNode );
        aBuffer.insert( 0, sal_Unicode('@') );
        break;

    case NodeType_DOCUMENT_NODE:
        if( xNode == getDefaultInstance() )
            aBuffer.append( sal_Unicode('/') );
        else
            lcl_OutInstance( aBuffer, xNode, this );
        break;

    default:
        // unknown type? fail!
        OSL_ENSURE( false, "unknown node type!" );
        break;
    }

    return aBuffer.makeStringAndClear();
}

OUString Model::getNodeName( const XNode_t& xNode )
    throw( RuntimeException )
{
    OUStringBuffer aBuffer;

    switch( xNode->getNodeType() )
    {
    case NodeType_ELEMENT_NODE:
    case NodeType_ATTRIBUTE_NODE:
        lcl_OutName( aBuffer, xNode );
        break;

    case NodeType_TEXT_NODE:
    case NodeType_DOCUMENT_NODE:
    default:
        // unknown type? fail!
        OSL_ENSURE( false, "no name for this node type!" );
        break;
    }

    return aBuffer.makeStringAndClear();
}

OUString Model::getBindingName( const XPropertySet_t& xBinding,
                                sal_Bool /*bDetail*/ )
    throw( RuntimeException )
{
    OUString sID;
    xBinding->getPropertyValue( OUSTRING("BindingID" ) ) >>= sID;
    OUString sExpression;
    xBinding->getPropertyValue( OUSTRING("BindingExpression" ) ) >>= sExpression;
    
    OUStringBuffer aBuffer;
    if( sID.getLength() > 0 )
    {
        aBuffer.append( sID );
        aBuffer.append( OUSTRING(" (" ));
        aBuffer.append( sExpression );
        aBuffer.append( OUSTRING(")" ));
    }
    else
        aBuffer.append( sExpression );

    return aBuffer.makeStringAndClear();
}

OUString Model::getSubmissionName( const XPropertySet_t& xSubmission,
                                   sal_Bool /*bDetail*/ )
    throw( RuntimeException )
{
    OUString sID;
    xSubmission->getPropertyValue( OUSTRING("ID") ) >>= sID;
    return sID;
}

Model::XPropertySet_t Model::cloneBindingAsGhost( const XPropertySet_t &xBinding )
	throw( RuntimeException )
{
	// Create a new binding instance first...
	Binding *pBinding = new Binding();

	// ...and bump up the "defered notification counter"
	// to prevent this binding from contributing to the
	// MIPs table...
	pBinding->deferNotifications(true);

	// Copy the propertyset and return result...
    XPropertySet_t xNewBinding(pBinding);
    copy( xBinding, xNewBinding );
    return xNewBinding;
}

void Model::removeBindingIfUseless( const XPropertySet_t& xBinding )
    throw( RuntimeException )
{
    Binding* pBinding = Binding::getBinding( xBinding );
    if( pBinding != NULL )
    {
        if( ! pBinding->isUseful() )
            mpBindings->removeItem( pBinding );
    }
}

Model::XDocument_t Model::newInstance( const rtl::OUString& sName,
                         const rtl::OUString& sURL,
                         sal_Bool bURLOnce )
    throw( RuntimeException )
{
    // create a default instance with <instanceData> element
    XDocument_t xInstance = getDocumentBuilder()->newDocument();
    DBG_ASSERT( xInstance.is(), "failed to create DOM instance" );

    Reference<XNode>( xInstance, UNO_QUERY_THROW )->appendChild( 
        Reference<XNode>( xInstance->createElement( OUSTRING("instanceData") ),
                          UNO_QUERY_THROW ) );

    Sequence<PropertyValue> aSequence;
    bool bOnce = bURLOnce; // bool, so we can take address in setInstanceData
    setInstanceData( aSequence, &sName, &xInstance, &sURL, &bOnce );
    sal_Int32 nInstance = mpInstances->addItem( aSequence );
    loadInstance( nInstance );

    return xInstance;
}

sal_Int32 lcl_findProp( const PropertyValue* pValues,
                        sal_Int32 nLength,
                        const rtl::OUString& rName )
{
    bool bFound = false;
    sal_Int32 n = 0;
    for( ; !bFound && n < nLength; n++ )
    {
        bFound = ( pValues[n].Name == rName );
    }
    return bFound ? ( n - 1) : -1;
}

sal_Int32 xforms::lcl_findInstance( const InstanceCollection* pInstances,
                                    const rtl::OUString& rName )
{
    sal_Int32 nLength = pInstances->countItems();
    sal_Int32 n = 0;
    bool bFound = false;
    for( ; !bFound  &&  n < nLength; n++ )
    {
        OUString sName;
        getInstanceData( pInstances->getItem( n ), &sName, NULL, NULL, NULL );
        bFound = ( sName == rName );
    }
    return bFound ? ( n - 1 ) : -1;
}

void Model::renameInstance( const rtl::OUString& sFrom,
                            const rtl::OUString& sTo,
                            const rtl::OUString& sURL,
                            sal_Bool bURLOnce )
    throw( RuntimeException )
{
    sal_Int32 nPos = lcl_findInstance( mpInstances, sFrom );
    if( nPos != -1 )
    {
        Sequence<PropertyValue> aSeq = mpInstances->getItem( nPos );
        PropertyValue* pSeq = aSeq.getArray();
        sal_Int32 nLength = aSeq.getLength();

        sal_Int32 nProp = lcl_findProp( pSeq, nLength, OUSTRING("ID") );
        if( nProp == -1 )
        {
            // add name property
            aSeq.realloc( nLength + 1 );
            pSeq = aSeq.getArray();
            pSeq[ nLength ].Name = OUSTRING("ID");
            nProp = nLength;
        }

        // change name
        pSeq[ nProp ].Value <<= sTo;

		// change url
        nProp = lcl_findProp( pSeq, nLength, OUSTRING("URL") );
		if(nProp != -1)
	        pSeq[ nProp ].Value <<= sURL;

		// change urlonce
        nProp = lcl_findProp( pSeq, nLength, OUSTRING("URLOnce") );
		if(nProp != -1)
	        pSeq[ nProp ].Value <<= bURLOnce;

        // set instance
        mpInstances->setItem( nPos, aSeq );
    }
}

void Model::removeInstance( const rtl::OUString& sName )
    throw( RuntimeException )
{
    sal_Int32 nPos = lcl_findInstance( mpInstances, sName );
    if( nPos != -1 )
        mpInstances->removeItem( mpInstances->getItem( nPos ) );
}

Reference<XNameContainer> lcl_getModels( 
    const Reference<com::sun::star::frame::XModel>& xComponent )
{
    Reference<XNameContainer> xRet;
    Reference<XFormsSupplier> xSupplier( xComponent, UNO_QUERY );
    if( xSupplier.is() )
    {
        xRet = xSupplier->getXForms();
    }
    return xRet;
}

Model::XModel_t Model::newModel( const Reference<com::sun::star::frame::XModel>& xCmp,
                                 const OUString& sName )
    throw( RuntimeException )
{
    Model::XModel_t xModel;
    Reference<XNameContainer> xModels = lcl_getModels( xCmp );
    if( xModels.is()
        && ! xModels->hasByName( sName ) )
    {
        Model* pModel = new Model();
        xModel.set( pModel );

        pModel->setID( sName );
        pModel->newInstance( OUString(), OUString(), sal_False );
        pModel->initialize();
        xModels->insertByName( sName, makeAny( xModel ) );
    }

    return xModel;
}

void Model::renameModel( const Reference<com::sun::star::frame::XModel>& xCmp,
                         const OUString& sFrom,
                         const OUString& sTo )
    throw( RuntimeException )
{
    Reference<XNameContainer> xModels = lcl_getModels( xCmp );
    if( xModels.is() 
        && xModels->hasByName( sFrom )
        && ! xModels->hasByName( sTo ) )
    {
        Reference<XModel> xModel( xModels->getByName( sFrom ), UNO_QUERY );
        xModel->setID( sTo );
        xModels->insertByName( sTo, makeAny( xModel ) );
        xModels->removeByName( sFrom );
    }
}

void Model::removeModel( const Reference<com::sun::star::frame::XModel>& xCmp,
                         const OUString& sName )
    throw( RuntimeException )
{
    Reference<XNameContainer> xModels = lcl_getModels( xCmp );
    if( xModels.is() 
        && xModels->hasByName( sName ) )
    {
        xModels->removeByName( sName );
    }
}

Model::XNode_t Model::createElement( const XNode_t& xParent,
                                     const OUString& sName )
    throw( RuntimeException )
{
    Reference<XNode> xNode;
    if( xParent.is() 
        && isValidXMLName( sName ) )
    {
        // TODO: implement proper namespace handling
        xNode.set( xParent->getOwnerDocument()->createElement( sName ), 
                   UNO_QUERY );
    }
    return xNode;
}

Model::XNode_t Model::createAttribute( const XNode_t& xParent,
                                       const OUString& sName )
    throw( RuntimeException )
{
    Reference<XNode> xNode;
    Reference<XElement> xElement( xParent, UNO_QUERY );
    if( xParent.is() 
        && xElement.is()
        && isValidXMLName( sName ) )
    {
        // handle case where attribute already exists
        sal_Int32 nCount = 0;
        OUString sUniqueName = sName;
        while( xElement->hasAttribute( sUniqueName ) )
        {
            nCount++;
            sUniqueName = sName + OUString::valueOf( nCount );
        }

        // TODO: implement proper namespace handling
        xNode.set( xParent->getOwnerDocument()->createAttribute( sUniqueName ),
                   UNO_QUERY );
    }
    return xNode;
}

Model::XNode_t Model::renameNode( const XNode_t& xNode,
                                  const rtl::OUString& sName )
    throw( RuntimeException )
{
    // early out if we don't have to change the name
    if( xNode->getNodeName() == sName )
        return xNode;

    // refuse to change name if its an attribute, and the name is already used
    if( xNode->getNodeType() == NodeType_ATTRIBUTE_NODE
        && xNode->getParentNode().is()
        && Reference<XElement>(xNode->getParentNode(), UNO_QUERY_THROW)->hasAttribute( sName ) )
        return xNode;

    // note old binding expression so we can adjust bindings below
    OUString sOldDefaultBindingExpression = 
        getDefaultBindingExpressionForNode( xNode );

    Reference<XDocument> xDoc = xNode->getOwnerDocument();
    Reference<XNode> xNew;
    if( xNode->getNodeType() == NodeType_ELEMENT_NODE )
    {
        Reference<XElement> xElem = xDoc->createElement( sName );
        xNew.set( xElem, UNO_QUERY );

        // iterate over all attributes and append them to the new element
        Reference<XElement> xOldElem( xNode, UNO_QUERY );
        OSL_ENSURE( xNode.is(), "no element?" );

        Reference<XNamedNodeMap> xMap = xNode->getAttributes();
        sal_Int32 nLength = xMap.is() ? xMap->getLength() : 0;
        for( sal_Int32 n = 0; n < nLength; n++ )
        {
            Reference<XAttr> xAttr( xMap->item(n), UNO_QUERY );
            xElem->setAttributeNode( xOldElem->removeAttributeNode( xAttr ) );
        }

        // iterate over all children and append them to the new element
        for( Reference<XNode> xCurrent = xNode->getFirstChild();
             xCurrent.is();
             xCurrent = xNode->getFirstChild() )
        {
            xNew->appendChild( xNode->removeChild( xCurrent ) );
        }

        xNode->getParentNode()->replaceChild( xNew, xNode );
    }
    else if( xNode->getNodeType() == NodeType_ATTRIBUTE_NODE )
    {
        // create new attribute
        Reference<XAttr> xAttr = xDoc->createAttribute( sName );
        xAttr->setValue( xNode->getNodeValue() );

        // replace node
        Reference<XNode> xParent = xNode->getParentNode();
        xParent->removeChild( xNode );
        xNew = xParent->appendChild( Reference<XNode>( xAttr, UNO_QUERY ) );
    }
    else
    {
        OSL_ENSURE( false, "can't rename this node type" );
    }

    // adjust bindings (if necessary):
    if( xNew.is() )
    {
        // iterate over bindings and replace default expressions
        OUString sNewDefaultBindingExpression = 
            getDefaultBindingExpressionForNode( xNew );
        for( sal_Int32 n = 0; n < mpBindings->countItems(); n++ )
        {
            Binding* pBinding = Binding::getBinding(
                mpBindings->Collection<XPropertySet_t>::getItem( n ) );

            if( pBinding->getBindingExpression() 
                    == sOldDefaultBindingExpression )
                pBinding->setBindingExpression( sNewDefaultBindingExpression );
        }
    }

    // return node; return old node if renaming failed
    return xNew.is() ? xNew : xNode;
}

Model::XPropertySet_t Model::getBindingForNode( const XNode_t& xNode,
                                                sal_Bool bCreate )
    throw( RuntimeException )
{
    OSL_ENSURE( xNode.is(), "no node?" );

    // We will iterate over all bindings and determine the
    // appropriateness of the respective binding for this node. The
    // best one will be used. If we don't find any and bCreate is set,
    // then we will create a suitable binding.
    Binding* pBestBinding = NULL;
    sal_Int32 nBestScore = 0;

    for( sal_Int32 n = 0; n < mpBindings->countItems(); n++ )
    {
        Binding* pBinding = Binding::getBinding(
            mpBindings->Collection<XPropertySet_t>::getItem( n ) );

        OSL_ENSURE( pBinding != NULL, "no binding?" );
        Reference<XNodeList> xNodeList = pBinding->getXNodeList();

        sal_Int32 nNodes = xNodeList.is() ? xNodeList->getLength() : 0;
        if( nNodes > 0  &&  xNodeList->item( 0 ) == xNode )
        {
            // allright, we found a suitable node. Let's determine how
            // well it fits. Score:
            // - bind to exactly this node is better than whole nodeset
            // - simple binding expressions is better than complex ones
            sal_Int32 nScore = 0;
            if( nNodes == 1 )
                nScore ++;
            if( pBinding->isSimpleBindingExpression() )
                nScore ++;

            // if we found a better binding, remember it
            if( nScore > nBestScore )
            {
                pBestBinding = pBinding;
                nBestScore = nScore;
            }
        }
    }

    // create binding, if none was found and bCreate is set
    OSL_ENSURE( ( nBestScore == 0 ) == ( pBestBinding == NULL ),
                "score != binding?" );
    if( bCreate  &&  pBestBinding == NULL )
    {
        pBestBinding = new Binding();
        pBestBinding->setBindingExpression( 
            getDefaultBindingExpressionForNode( xNode ) );
        mpBindings->addItem( pBestBinding );
    }

    return pBestBinding;
}

void Model::removeBindingForNode( const XNode_t& )
    throw( RuntimeException )
{
    // determine whether suitable binding is still used
}

OUString lcl_serializeForDisplay( const Reference< XAttr >& _rxAttrNode )
{
    ::rtl::OUString sResult;
    OSL_ENSURE( _rxAttrNode.is(), "lcl_serializeForDisplay( attr ): invalid argument!" );
    if ( _rxAttrNode.is() )
    {
        ::rtl::OUStringBuffer aBuffer;
        aBuffer.append( _rxAttrNode->getName() );
        aBuffer.appendAscii( "=" );
        ::rtl::OUString sValue = _rxAttrNode->getValue();
        sal_Unicode nQuote = '"';
        if ( sValue.indexOf( nQuote ) >= 0 )
            nQuote = '\'';
        aBuffer.append( nQuote );
        aBuffer.append( sValue );
        aBuffer.append( nQuote );
        aBuffer.append( (sal_Unicode)' ' );
        sResult = aBuffer.makeStringAndClear();
    }
    return sResult;
}

OUString lcl_serializeForDisplay( const Reference<XNodeList>& xNodes )
{
    ::rtl::OUString sResult;

    // create document fragment
    Reference<XDocument> xDocument( getDocumentBuilder()->newDocument() );
    Reference<XDocumentFragment> xFragment(
        xDocument->createDocumentFragment() );
    Reference<XNode> xNode( xFragment, UNO_QUERY );
    OSL_ENSURE( xFragment.is(), "xFragment" );
    OSL_ENSURE( xNode.is(), "xNode" );

    sal_Int32 nAttributeNodes = 0;

    // attach nodelist to fragment
    sal_Int32 nLength = xNodes->getLength();
    for( sal_Int32 i = 0; i < nLength; i++ )
    {
        Reference<XNode> xCurrent = xNodes->item( i );
        
        switch ( xCurrent->getNodeType() )
        {
        case NodeType_DOCUMENT_NODE:
            // special-case documents: use top-level element instead
            xCurrent = xCurrent->getFirstChild();
            break;
        case NodeType_ATTRIBUTE_NODE:
        {
            Reference< XAttr > xAttr( xCurrent, UNO_QUERY );
            if ( xAttr.is() )
            {
                sResult += lcl_serializeForDisplay( xAttr );
                ++nAttributeNodes;
            }
        }
        continue;

        default:
            break;
        }

        // append node
        xNode->appendChild( xDocument->importNode( xCurrent, sal_True ) );
    }
    OSL_ENSURE( ( nAttributeNodes == 0 ) || ( nAttributeNodes == nLength ),
        "lcl_serializeForDisplay: mixed attribute and non-attribute nodes?" );
    if ( nAttributeNodes )
        // had only attribute nodes
        return sResult;
    
    // serialize fragment
    CSerializationAppXML aSerialization;
    aSerialization.setSource( xFragment );
    aSerialization.serialize();

    // copy stream into buffer
    Reference<XTextInputStream> xTextInputStream( 
        createInstance( OUSTRING("com.sun.star.io.TextInputStream") ),
        UNO_QUERY );
    Reference<XActiveDataSink>( xTextInputStream, UNO_QUERY_THROW )
        ->setInputStream( aSerialization.getInputStream() );

    /* WORK AROUND for problem in serialization: currently, multiple
      XML delarations (<?xml...?>) are being written out and we don't
      want them. When this is fixed, the code below is nice and
      simple. The current code filters out the declarations.
    OUString sResult = xTextInputStream->readString( Sequence<sal_Unicode>(),
                                                     sal_True );
    */

    // well, the serialization prepends XML header(s) that we need to
    // remove first.
    OUStringBuffer aBuffer;
    while( ! xTextInputStream->isEOF() )
    {
        OUString sLine = xTextInputStream->readLine();
        if( sLine.getLength() > 0
            && sLine.compareToAscii( "<?xml", 5 ) != 0 )
        {
            aBuffer.append( sLine );
            aBuffer.append( sal_Unicode('\n') );
        }
    }
    sResult = aBuffer.makeStringAndClear();

    return sResult;
}

OUString lcl_serializeForDisplay( const Reference<XXPathObject>& xResult )
{
    // error handling first
    if( ! xResult.is() )
        return getResource( RID_STR_XFORMS_CANT_EVALUATE );


    // TODO: localize
    OUStringBuffer aBuffer;

    switch( xResult->getObjectType() )
    {
    case XPathObjectType_XPATH_BOOLEAN:
        aBuffer.append( xResult->getBoolean()
                        ? OUSTRING("true")
                        : OUSTRING("false") );
        break;

    case XPathObjectType_XPATH_STRING:
        aBuffer.append( sal_Unicode('"') );
        aBuffer.append( xResult->getString() );
        aBuffer.append( sal_Unicode('"') );
        break;

    case XPathObjectType_XPATH_NODESET:
        aBuffer.append( lcl_serializeForDisplay( xResult->getNodeList() ) );
        break;

    case XPathObjectType_XPATH_NUMBER:
        aBuffer.append( xResult->getDouble() );
        break;

    case XPathObjectType_XPATH_UNDEFINED:
    case XPathObjectType_XPATH_POINT:
    case XPathObjectType_XPATH_RANGE:
    case XPathObjectType_XPATH_LOCATIONSET:
    case XPathObjectType_XPATH_USERS:
    case XPathObjectType_XPATH_XSLT_TREE:
    default:
        // TODO: localized error message?
        break;
    }

    return aBuffer.makeStringAndClear();
}

OUString Model::getResultForExpression( 
    const XPropertySet_t& xBinding,
    sal_Bool bIsBindingExpression,
    const OUString& sExpression )
    throw( RuntimeException )
{
    Binding* pBinding = Binding::getBinding( xBinding );
    if( pBinding == NULL )
        throw RuntimeException();

    // prepare & evaluate expression
    OUStringBuffer aBuffer;
    ComputedExpression aExpression;
    aExpression.setExpression( sExpression );
    if( bIsBindingExpression )
    {
        // binding: use binding context and evaluation
        aExpression.evaluate( pBinding->getEvaluationContext() );
        aBuffer.append( lcl_serializeForDisplay( aExpression.getXPath() ) );
    }
    else
    {
        // MIP (not binding): iterate over bindings contexts
        std::vector<EvaluationContext> aContext = 
            pBinding->getMIPEvaluationContexts();
        for( std::vector<EvaluationContext>::iterator aIter = aContext.begin();
             aIter != aContext.end();
             aIter ++ )
        {
            aExpression.evaluate( *aIter );
            aBuffer.append( lcl_serializeForDisplay(aExpression.getXPath()) );
            aBuffer.append( sal_Unicode('\n') );
        }
    }
    return aBuffer.makeStringAndClear();
}

sal_Bool Model::isValidXMLName( const OUString& sName )
    throw( RuntimeException )
{
    return isValidQName( sName, NULL );
}

sal_Bool Model::isValidPrefixName( const OUString& sName )
    throw( RuntimeException )
{
    return ::isValidPrefixName( sName, NULL );
}

void Model::setNodeValue( 
    const XNode_t& xNode,
    const rtl::OUString& sValue )
    throw( RuntimeException )
{
    setSimpleContent( xNode, sValue );
}


//
// helper functions from model_helper.hxx
//

void xforms::getInstanceData( 
    const Sequence<PropertyValue>& aValues,
    OUString* pID,
    Reference<XDocument>* pInstance,
    OUString* pURL,
    bool* pURLOnce )
{
    sal_Int32 nValues = aValues.getLength();
    const PropertyValue* pValues = aValues.getConstArray();
    for( sal_Int32 n = 0; n < nValues; n++ )
    {
        const PropertyValue& rValue = pValues[n];
#define PROP(NAME) \
        if( p##NAME != NULL && \
            rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(#NAME)) ) \
            rValue.Value >>= (*p##NAME)
        PROP(ID);
        PROP(Instance);
        PROP(URL);
        PROP(URLOnce);
#undef PROP
    }
}

void xforms::setInstanceData( 
    Sequence<PropertyValue>& aSequence,
    const OUString* _pID,
    const Reference<XDocument>* _pInstance,
    const OUString* _pURL,
    const bool* _pURLOnce )
{
    // get old instance data
    OUString sID;
    Reference<XDocument> xInstance;
    OUString sURL;
    bool bURLOnce = false;
    getInstanceData( aSequence, &sID, &xInstance, &sURL, &bURLOnce );
    const OUString* pID = ( sID.getLength() > 0 ) ? &sID : NULL;
    const Reference<XDocument>* pInstance = xInstance.is() ? &xInstance : NULL;
    const OUString* pURL = ( sURL.getLength() > 0 ) ? &sURL : NULL;
    const bool* pURLOnce = ( bURLOnce && pURL != NULL ) ? &bURLOnce : NULL;

    // determine new instance data
#define PROP(NAME) if( _p##NAME != NULL ) p##NAME = _p##NAME
    PROP(ID);
    PROP(Instance);
    PROP(URL);
    PROP(URLOnce);
#undef PROP

    // count # of values we want to set
    sal_Int32 nCount = 0;
#define PROP(NAME) if( p##NAME != NULL ) nCount++
    PROP(ID);
    PROP(Instance);
    PROP(URL);
    PROP(URLOnce);
#undef PROP

    // realloc sequence and enter values;
    aSequence.realloc( nCount );
    PropertyValue* pSequence = aSequence.getArray();
    sal_Int32 nIndex = 0;
#define PROP(NAME) \
    if( p##NAME != NULL ) \
    { \
        pSequence[ nIndex ].Name = OUSTRING(#NAME); \
        pSequence[ nIndex ].Value <<= *p##NAME; \
        nIndex++; \
    }
    PROP(ID);
    PROP(Instance);
    PROP(URL);
    PROP(URLOnce);
#undef PROP
}
