/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



#include "codemaker/commoncpp.hxx"

#include "skeletoncommon.hxx"
#include "skeletoncpp.hxx"

#include <iostream>

using namespace ::rtl;
using namespace ::codemaker::cpp;

namespace skeletonmaker { namespace cpp {

void generateIncludes(std::ostream & o,
         const std::hash_set< OString, OStringHash >& interfaces,
         const AttributeInfo& /*properties*/,
         OString propertyhelper, bool serviceobject,
         bool supportxcomponent)
{
    o << "#include \"sal/config.h\"\n";
    if (serviceobject) {
        o << "#include \"cppuhelper/factory.hxx\"\n"
          << "#include \"cppuhelper/implementationentry.hxx\"\n";
    } else {
        o << "#include \"com/sun/star/uno/XComponentContext.hpp\"\n";
    }
    if (supportxcomponent) {
        o << "#include \"cppuhelper/compbase" << interfaces.size() << ".hxx\"\n";
        o << "#include \"cppuhelper/basemutex.hxx\"\n";
    } else {
        o << "#include \"cppuhelper/implbase" << interfaces.size() << ".hxx\"\n";
    }   

    if (propertyhelper.getLength() > 1) {
        if (propertyhelper.equals("_"))
            o << "#include \"cppuhelper/rpopshlp.hxx\"\n";
        else
            o << "#include \"cppuhelper/propertysetmixin.hxx\"\n";            
    }

    std::hash_set< OString, OStringHash >::const_iterator iter = interfaces.begin();
    while (iter != interfaces.end())
    {
        o << "#include \""
          << ((*iter).replace('.', '/').getStr())
          << ".hpp\"\n";
        iter++;
    }        
}

short generateNamespace(std::ostream & o,
                        const OString & implname,
                        bool serviceobject,
                        OString & nm)
{
    short count=0;
    sal_Int32 index = implname.lastIndexOf('.');
    if (serviceobject) {
        o << "\n\n// component helper namespace\n";
    } else {
        o << "\n";
    }
    OStringBuffer buf;
    if (index == -1) {
        if (serviceobject) {
            buf.append("comp_");
            buf.append(implname);
            nm = buf.makeStringAndClear();
            o << "namespace comp_" << implname << " {\n\n";
            count=1;
        } else {
            nm = OString();
        }
    } else {
        sal_Int32 nPos=0;
        do {
            OString token(implname.getToken(0, '.', nPos));
            if (nPos < 0 && serviceobject) {
                buf.append("::comp_");
                buf.append(token);
                o << "namespace comp_" << token << " { ";
                count++;
            } else {
                buf.append("::");
                buf.append(token);
                o << "namespace " << token << " { ";
                count++;
            }
        } while( nPos <= index );
        nm = buf.makeStringAndClear();
        o << "\n\n";
    }
    return count;
}

OString generateCompHelperDeclaration(std::ostream & o,
                                      const OString & implname)
{
    OString nm;
    short nbrackets = generateNamespace(o, implname, true, nm);

    o << "namespace css = ::com::sun::star;\n\n";
    
    // generate component/service helper functions
    o << "// component and service helper functions:\n"
        "::rtl::OUString SAL_CALL _getImplementationName();\n"
        "css::uno::Sequence< ::rtl::OUString > SAL_CALL "
        "_getSupportedServiceNames();\n"
        "css::uno::Reference< css::uno::XInterface > SAL_CALL _create("
        " css::uno::Reference< css::uno::XComponentContext > const & "
        "context );\n\n";

    // close namepsace
    for (short i=0; i < nbrackets; i++)
        o << "} ";
    o << "// closing component helper namespace\n\n";
    
    return nm;
}

void generateCompHelperDefinition(std::ostream & o,
         const OString & implname,
         const OString & classname,                       
         const std::hash_set< OString, OStringHash >& services)
{
    OString nm;
    short nbrackets = generateNamespace(o, implname, true, nm);
    
    o << "::rtl::OUString SAL_CALL _getImplementationName() {\n"
      << "    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\n"
      << "        \"" << implname << "\"));\n}\n\n";

    o << "css::uno::Sequence< ::rtl::OUString > SAL_CALL "
        "_getSupportedServiceNames()\n{\n    css::uno::Sequence< "
      << "::rtl::OUString >" << " s(" << services.size() << ");\n";

    std::hash_set< OString, OStringHash >::const_iterator iter = services.begin();
    short i=0;
    while (iter != services.end())
    {
        o << "    s[" << i++ << "] = ::rtl::OUString("
          << "RTL_CONSTASCII_USTRINGPARAM(\n        \""
          << (*iter).replace('/','.') << "\"));\n";
        iter++;
    }  
    o << "    return s;\n}\n\n";

    o << "css::uno::Reference< css::uno::XInterface > SAL_CALL _create("
      << "\n    const css::uno::Reference< css::uno::XComponentContext > & "
      << "context)\n        SAL_THROW((css::uno::Exception))\n{\n"
      << "    return static_cast< ::cppu::OWeakObject * >(new "
      << classname <<  "(context));\n}\n\n";

    // close namepsace
    for (short j=0; j < nbrackets; j++)
        o << "} ";
    o << "// closing component helper namespace\n\n";
    
}

void generateCompFunctions(std::ostream & o, const OString & nmspace)
{
    o << "static ::cppu::ImplementationEntry const entries[] = {\n"
      << "    { &" << nmspace << "::_create,\n      &"
      << nmspace << "::_getImplementationName,\n      &"
      << nmspace << "::_getSupportedServiceNames,\n"
      << "      &::cppu::createSingleComponentFactory, 0, 0 },\n"
      << "    { 0, 0, 0, 0, 0, 0 }\n};\n\n";

    o << "extern \"C\" void SAL_CALL component_getImplementationEnvironment(\n"
      << "    const char ** envTypeName, uno_Environment **)\n{\n"
      << "    *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;\n}\n\n";

    o << "extern \"C\" void * SAL_CALL component_getFactory(\n"
      << "    const char * implName, void * serviceManager, void * registryKey)\n{\n"
      << "    return ::cppu::component_getFactoryHelper(\n"
      << "        implName, serviceManager, registryKey, entries);\n}\n\n";

    o << "extern \"C\" sal_Bool SAL_CALL component_writeInfo(\n"
      << "    void * serviceManager, void * registryKey)\n{\n"
      << "    return ::cppu::component_writeInfoHelper("
      << "serviceManager, registryKey, entries);\n}\n";
}

void generateXPropertySetBodies(std::ostream& o,
                                const OString & classname,
                                const OString & propertyhelper)
{
    o << "// com.sun.star.beans.XPropertySet:\n";
    
    o << "css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL "
      << classname << "getPropertySetInfo() throw ("
        "css::uno::RuntimeException)\n{\n    return ::cppu::PropertySetMixin< "
      << propertyhelper
      << " >::getPropertySetInfo();\n}\n\n";

    o << "void SAL_CALL " << classname << "setPropertyValue(const ::rtl::OUString"
        " & aPropertyName, const css::uno::Any & aValue) throw ("
        "css::uno::RuntimeException, css::beans::UnknownPropertyException, "
        "css::beans::PropertyVetoException, css::lang::IllegalArgumentException, "
        "css::lang::WrappedTargetException)\n{\n    ::cppu::PropertySetMixin< "
      << propertyhelper << " >::setPropertyValue(aPropertyName, aValue);\n}\n\n";


    o << "css::uno::Any SAL_CALL " << classname << "getPropertyValue(const "
        "::rtl::OUString & aPropertyName) throw (css::uno::RuntimeException, "
        "css::beans::UnknownPropertyException, css::lang::WrappedTargetException)"
        "\n{\n    return ::cppu::PropertySetMixin< "
      << propertyhelper << " >::getPropertyValue(aPropertyName);\n}\n\n";

    o << "void SAL_CALL " << classname << "addPropertyChangeListener(const "
        "::rtl::OUString & aPropertyName, const css::uno::Reference< "
        "css::beans::XPropertyChangeListener > & xListener) throw ("
        "css::uno::RuntimeException, css::beans::UnknownPropertyException, "
        "css::lang::WrappedTargetException)\n{\n    ::cppu::PropertySetMixin< "
      << propertyhelper
      << " >::addPropertyChangeListener(aPropertyName, xListener);\n}\n\n";

    o << "void SAL_CALL " << classname << "removePropertyChangeListener(const "
        "::rtl::OUString & aPropertyName, const css::uno::Reference< "
        "css::beans::XPropertyChangeListener > & xListener) throw ("
        "css::uno::RuntimeException, css::beans::UnknownPropertyException, "
        "css::lang::WrappedTargetException)\n{\n    ::cppu::PropertySetMixin< "
      << propertyhelper
      << " >::removePropertyChangeListener(aPropertyName, xListener);\n}\n\n";

    o << "void SAL_CALL " << classname << "addVetoableChangeListener(const "
        "::rtl::OUString & aPropertyName, const css::uno::Reference< "
        "css::beans::XVetoableChangeListener > & xListener) throw ("
        "css::uno::RuntimeException, css::beans::UnknownPropertyException, "
        "css::lang::WrappedTargetException)\n{\n    ::cppu::PropertySetMixin< "
      << propertyhelper
      << " >::addVetoableChangeListener(aPropertyName, xListener);\n}\n\n";

    o << "void SAL_CALL " << classname << "removeVetoableChangeListener(const "
        "::rtl::OUString & aPropertyName, const css::uno::Reference< "
        "css::beans::XVetoableChangeListener > & xListener) throw ("
        "css::uno::RuntimeException, css::beans::UnknownPropertyException, "
        "css::lang::WrappedTargetException)\n{\n    ::cppu::PropertySetMixin< "
      << propertyhelper
      << " >::removeVetoableChangeListener(aPropertyName, xListener);\n}\n\n";    
}

void generateXFastPropertySetBodies(std::ostream& o,
                                    const OString & classname,
                                    const OString & propertyhelper)
{
    o << "// com.sun.star.beans.XFastPropertySet:\n";

    o << "void SAL_CALL " << classname << "setFastPropertyValue( ::sal_Int32 "
        "nHandle, const css::uno::Any& aValue ) throw ("
        "css::beans::UnknownPropertyException, css::beans::PropertyVetoException, "
        "css::lang::IllegalArgumentException, css::lang::WrappedTargetException, "
        "css::uno::RuntimeException)\n{\n    ::cppu::PropertySetMixin< "
      << propertyhelper << " >::setFastPropertyValue(nHandle, aValue);\n}\n\n";    

    
    o << "css::uno::Any SAL_CALL " << classname << "getFastPropertyValue( "
        "::sal_Int32 nHandle ) throw (css::beans::UnknownPropertyException, "
        "css::lang::WrappedTargetException, css::uno::RuntimeException)\n{\n"
        "    return ::cppu::PropertySetMixin< "
      << propertyhelper << " >::getFastPropertyValue(nHandle);\n}\n\n";    
}

void generateXPropertyAccessBodies(std::ostream& o,
                                   const OString & classname,
                                   const OString & propertyhelper)
{
    o << "    // com.sun.star.beans.XPropertyAccess:\n";

    o << "css::uno::Sequence< css::beans::PropertyValue > SAL_CALL "
      << classname << "getPropertyValues(  ) throw ("
        "::com::sun::star::uno::RuntimeException)\n{\n"
        "    return ::cppu::PropertySetMixin< "
      << propertyhelper << " >::getPropertyValues();\n}\n\n";    
        
    o << "void SAL_CALL " << classname << "setPropertyValues( const "
        "css::uno::Sequence< css::beans::PropertyValue >& aProps ) throw ("
        "css::beans::UnknownPropertyException, css::beans::PropertyVetoException, "
        "css::lang::IllegalArgumentException, css::lang::WrappedTargetException, "
        "css::uno::RuntimeException)\n{\n"
        "    ::cppu::PropertySetMixin< "
      << propertyhelper << " >::setPropertyValues(aProps);\n}\n\n";    
}

void generateXLocalizable(std::ostream& o, const OString & classname)
{
    o << "// ::com::sun::star::lang::XLocalizable:\n"
        "void SAL_CALL " << classname << "setLocale(const css::lang::"
        "Locale & eLocale) throw (css::uno::RuntimeException)\n{\n"
        "     m_locale = eLocale;\n}\n\n"
        "css::lang::Locale SAL_CALL " << classname << "getLocale() "
        "throw (css::uno::RuntimeException)\n{\n    return m_locale;\n}\n\n";
}

void generateXAddInBodies(std::ostream& o, const OString & classname)
{
    o << "// ::com::sun::star::sheet::XAddIn:\n";

    o << "::rtl::OUString SAL_CALL " << classname << "getProgrammaticFuntionName("
        "const ::rtl::OUString & aDisplayName) throw (css::uno::RuntimeException)"
        "\n{\n    ::rtl::OUString ret;\n    try {\n        css::uno::Reference< "
        "css::container::XNameAccess > xNAccess(m_xHAccess, css::uno::UNO_QUERY);\n"
        "        css::uno::Sequence< ::rtl::OUString > functions = "
        "xNAccess->getElementNames();\n        sal_Int32 len = functions."
        "getLength();\n        ::rtl::OUString sDisplayName;\n"
        "        for (sal_Int32 i=0; i < len; ++i) {\n"
        "            sDisplayName = getAddinProperty(functions[i], "
        "::rtl::OUString(),\n                                           "
        "sDISPLAYNAME);\n            if (sDisplayName.equals(aDisplayName))\n"
        "                return functions[i];\n        }\n    }\n"
        "     catch ( css::uno::RuntimeException & e ) {\n        throw e;\n    }\n"
        "     catch ( css::uno::Exception & ) {\n    }\n    return ret;\n}\n\n";

    o << "::rtl::OUString SAL_CALL " << classname << "getDisplayFunctionName(const "
        "::rtl::OUString & aProgrammaticName) throw (css::uno::RuntimeException)\n"
        "{\n    return getAddinProperty(aProgrammaticName, ::rtl::OUString(), "
        "sDISPLAYNAME);\n}\n\n";

    o << "::rtl::OUString SAL_CALL " << classname << "getFunctionDescription(const "
        "::rtl::OUString & aProgrammaticName) throw (css::uno::RuntimeException)\n"
        "{\n    return getAddinProperty(aProgrammaticName, ::rtl::OUString(), "
        "sDESCRIPTION);\n}\n\n";

    o << "::rtl::OUString SAL_CALL " << classname << "getDisplayArgumentName(const "
        "::rtl::OUString & aProgrammaticFunctionName, ::sal_Int32 nArgument) throw "
        "(css::uno::RuntimeException)\n{\n    return getAddinProperty("
        "aProgrammaticFunctionName,\n                            m_functionMap["
        "aProgrammaticFunctionName][nArgument],\n"
        "                            sDISPLAYNAME);\n}\n\n";

    o << "::rtl::OUString SAL_CALL " << classname << "getArgumentDescription(const "
        "::rtl::OUString & aProgrammaticFunctionName, ::sal_Int32 nArgument) throw "
        "(css::uno::RuntimeException)\n{\n    return getAddinProperty("
        "aProgrammaticFunctionName,\n                            "
        "m_functionMap[aProgrammaticFunctionName][nArgument],\n"
        "                            sDESCRIPTION);\n}\n\n";

    o << "::rtl::OUString SAL_CALL " << classname << "getProgrammaticCategoryName("
        "const ::rtl::OUString & aProgrammaticFunctionName) throw ("
        "css::uno::RuntimeException)\n{\n    return getAddinProperty("
        "aProgrammaticFunctionName, ::rtl::OUString(), sCATEGORY);\n}\n\n";

    o << "::rtl::OUString SAL_CALL " << classname << "getDisplayCategoryName(const "
        "::rtl::OUString & aProgrammaticFunctionName) throw ("
        "css::uno::RuntimeException)\n{\n    return getAddinProperty("
        "aProgrammaticFunctionName, ::rtl::OUString(), "
        "sCATEGORYDISPLAYNAME);\n}\n\n";
}

void generateXCompatibilityNamesBodies(std::ostream& o, const OString & classname)
{
    o << "// ::com::sun::star::sheet::XCompatibilityNames:\n"
        "css::uno::Sequence< css::sheet::LocalizedName > SAL_CALL " << classname
      << "getCompatibilityNames(const ::rtl::OUString & aProgrammaticName) throw "
        "(css::uno::RuntimeException)\n{\n    css::uno::Sequence< "
        "css::sheet::LocalizedName > seqLocalizedNames;\n    try {\n        "
        "::rtl::OUStringBuffer buf("
        "aProgrammaticName);\n        buf.appendAscii(\"/CompatibilityName\");\n"
        "        ::rtl::OUString hname(buf.makeStringAndClear());\n\n        "
        "if ( m_xCompAccess->hasByHierarchicalName(hname) ) {\n"
        "            css::uno::Reference< css::container::XNameAccess > "
        "xNameAccess(\n"
        "                m_xCompAccess->getByHierarchicalName(hname), "
        "css::uno::UNO_QUERY);\n\n            css::uno::Sequence< ::rtl::OUString"
        " > elems = \n            xNameAccess->getElementNames();"
        "\n            ::sal_Int32 len = elems.getLength();\n\n            "
        "seqLocalizedNames.realloc(len);\n\n            ::rtl::OUString "
        "sCompatibilityName;\n            for (::sal_Int32 i=0; i < len; ++i) {\n"
        "                ::rtl::OUString sLocale(elems[i]);\n                "
        "xNameAccess->getByName(sLocale) >>= sCompatibilityName;\n\n"
        "                css::lang::Locale aLocale;\n                "
        "::sal_Int32 nIndex = 0, nToken = 0;\n                "
        "do {\n                    ::rtl::OUString aToken = sLocale.getToken(0, '-', "
        "nIndex);\n                    switch (nToken++) {\n                    "
        "case 0:\n                        aLocale.Language = aToken;\n"
        "                        break;\n                    case 1:\n"
        "                        aLocale.Country = aToken;\n                    "
        "    break;\n                    default:\n                        "
        "aLocale.Variant = sLocale.copy(nIndex-aToken.getLength()-1);\n"
        "                        nIndex = -1;\n                    }\n"
        "                } while ( nIndex >= 0 );\n\n                "
        "seqLocalizedNames[i].Locale = aLocale;\n                "
        "seqLocalizedNames[i].Name = sCompatibilityName;\n            }"
        "\n        }\n    }\n    catch ( css::uno::RuntimeException & e ) {\n        "
        "throw e;\n    }\n    catch ( css::uno::Exception & ) {\n    }\n\n"
        "    return seqLocalizedNames;\n}\n\n";
}

void generateXInitialization(std::ostream& o, const OString & classname)
{
    o << "// ::com::sun::star::lang::XInitialization:\n"
        "void SAL_CALL " << classname << "initialize( const css::uno::Sequence< "
        "css::uno::Any >& aArguments ) "
        "throw (css::uno::Exception, css::uno::RuntimeException)\n{\n"
        "    css::uno::Reference < css::frame::XFrame > xFrame;\n"
        "    if ( aArguments.getLength() ) {\n        aArguments[0] >>= xFrame;\n"
        "        m_xFrame = xFrame;\n    }\n}\n\n";
}

void generateXDispatch(std::ostream& o,
                       const OString & classname,
                       const ProtocolCmdMap & protocolCmdMap)
{
    // com.sun.star.frame.XDispatch
    // dispatch
    o << "// ::com::sun::star::frame::XDispatch:\n"
        "void SAL_CALL " << classname << "dispatch( const css::util::URL& aURL, const "
        "css::uno::Sequence< css::beans::PropertyValue >& aArguments ) throw"
        "(css::uno::RuntimeException)\n{\n";
    
    ProtocolCmdMap::const_iterator iter = protocolCmdMap.begin();
    while (iter != protocolCmdMap.end()) {
        o << "    if ( aURL.Protocol.equalsAscii(\"" << (*iter).first
          << "\") == 0 )\n    {\n";
        
        for (std::vector< OString >::const_iterator i = (*iter).second.begin();
             i != (*iter).second.end(); ++i) {
            o << "        if ( aURL.Path.equalsAscii(\"" << (*i) << "\") )\n"
                "        {\n                // add your own code here\n"
                "                return;\n        }\n";
        }

        o << "    }\n";
        iter++;
    }
    o << "}\n\n";
    
    // addStatusListener
    o << "void SAL_CALL " << classname << "addStatusListener( const css::uno::Reference< "
        "css::frame::XStatusListener >& xControl, const css::util::URL& aURL ) "
        "throw (css::uno::RuntimeException)\n{\n"
        "    // add your own code here\n}\n\n";
        
    // removeStatusListener
    o << "void SAL_CALL " << classname << "removeStatusListener( const css::uno::Reference"
        "< css::frame::XStatusListener >& xControl, const css::util::URL& aURL ) "
        "throw (css::uno::RuntimeException)\n{\n"
        "    // add your own code here\n}\n\n";
}

void generateXDispatchProvider(std::ostream& o,
                               const OString & classname,
                               const ProtocolCmdMap & protocolCmdMap)
{

    // com.sun.star.frame.XDispatchProvider
    // queryDispatch
    o << "// ::com::sun::star::frame::XDispatchProvider:\n"
        "css::uno::Reference< css::frame::XDispatch > SAL_CALL " << classname
      << "queryDispatch( const css::util::URL& aURL,"
        " const ::rtl::OUString& sTargetFrameName, sal_Int32 nSearchFlags ) "
        "throw(css::uno::RuntimeException)\n{\n    css::uno::Reference< "
        "css::frame::XDispatch > xRet;\n"
        "    if ( !m_xFrame.is() )\n        return 0;\n\n";

    ProtocolCmdMap::const_iterator iter = protocolCmdMap.begin();
    while (iter != protocolCmdMap.end()) {
        o << "    if ( aURL.Protocol.equalsAscii(\"" << (*iter).first
          << "\") == 0 )\n    {\n";
        
        for (std::vector< OString >::const_iterator i = (*iter).second.begin();
             i != (*iter).second.end(); ++i) {
            o << "        if ( aURL.Path.equalsAscii(\"" << (*i) << "\") == 0 )\n"
                "            xRet = this;\n";
        }

        o << "    }\n";
        iter++;
    }
    o << "    return xRet;\n}\n\n";

    // queryDispatches
    o << "css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL "
      << classname << "queryDispatches( const css::uno::Sequence< "
        "css::frame::DispatchDescriptor >& seqDescripts ) throw("
        "css::uno::RuntimeException)\n{\n"
        "    sal_Int32 nCount = seqDescripts.getLength();\n"
        "    css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > "
        "lDispatcher(nCount);\n\n"
        "    for( sal_Int32 i=0; i<nCount; ++i ) {\n"
        "        lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL,\n"
        "                                        seqDescripts[i].FrameName,\n"
        "                                        seqDescripts[i].SearchFlags );\n"
        "    }\n\n    return lDispatcher;\n}\n\n";
}
 
void generateAddinConstructorAndHelper(std::ostream& o,
         ProgramOptions const & options,
         TypeManager const & manager, const OString & classname,
         const std::hash_set< OString, OStringHash >& interfaces)
{
    o << classname << "::" << classname
      << "(css::uno::Reference< css::uno::XComponentContext > const & context) :\n"
      << "    m_xContext(context),    m_locale()\n{\n";

    if (options.backwardcompatible) {
        o << "     try {\n";

        generateFunctionParameterMap(o, options, manager, interfaces);
    
        o << "        css::uno::Reference< css::lang::XMultiServiceFactory > xProvider"
            "(\n             m_xContext->getServiceManager()->createInstanceWithContext"
            "(\n                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\n    "
            "                 \"com.sun.star.configuration.ConfigurationProvider\")),"
            "\n                 m_xContext ), css::uno::UNO_QUERY );\n\n";
        
        o << "        ::rtl::OUString sReadOnlyView(\n"
            "            RTL_CONSTASCII_USTRINGPARAM(\n"
            "                \"com.sun.star.configuration.ConfigurationAccess\"));\n\n";
        
        o << "        ::rtl::OUStringBuffer sPath(::rtl::OUString::createFromAscii(\n"
            "             \"/org.openoffice.Office.CalcAddIns/AddInInfo/\"));\n"
            "        sPath.appendAscii(sADDIN_SERVICENAME);\n"
            "        sPath.appendAscii(\"/AddInFunctions\");\n\n"
            "        // create arguments: nodepath\n"
            "        css::beans::PropertyValue aArgument;\n"
            "        aArgument.Name = ::rtl::OUString::createFromAscii(\"nodepath\");\n"
            "        aArgument.Value <<= sPath.makeStringAndClear();\n\n"
            "        css::uno::Sequence< css::uno::Any > aArguments(1);\n"
            "        aArguments[0] <<= aArgument;\n\n";
        
        o << "        // create the default view using default UI locale\n"
            "        css::uno::Reference< css::uno::XInterface > xIface =\n"
            "            xProvider->createInstanceWithArguments(sReadOnlyView, "
            "aArguments);\n\n"
            "         m_xHAccess = css::uno::Reference<\n            "
            "css::container::XHierarchicalNameAccess >(xIface, css::uno::UNO_QUERY);"
            "\n\n";
        
        o << "        // extend arguments to create a view for all locales to get "
            "simple\n        // access to the compatibilityname property\n"
            "        aArgument.Name = ::rtl::OUString::createFromAscii(\"locale\");\n"
            "        aArgument.Value <<= ::rtl::OUString::createFromAscii(\"*\");\n"
            "        aArguments.realloc(2);\n"
            "        aArguments[1] <<= aArgument;\n\n"
            "        // create view for all locales\n"
            "        xIface = xProvider->createInstanceWithArguments(sReadOnlyView, "
            "aArguments);\n\n"
            "        m_xCompAccess = css::uno::Reference<\n            "
            "css::container::XHierarchicalNameAccess >(xIface, css::uno::UNO_QUERY);\n";
        
        o << "    }\n    catch ( css::uno::Exception & ) {\n    }\n}\n\n";
        
        o << "// addin configuration property helper function:\n::rtl::OUString "
            "SAL_CALL " << classname << "::getAddinProperty(const ::rtl::OUString &"
            " funcName, const ::rtl::OUString & paramName, const char * propName) "
            "throw (css::uno::RuntimeException)\n{\n"
            "    ::rtl::OUString ret;\n    try {\n        "
            "::rtl::OUStringBuffer buf(funcName);\n"
            "        if (paramName.getLength() > 0) {\n"
            "            buf.appendAscii(\"/Parameters/\");\n"
            "            buf.append(paramName);\n        }\n\n"
            "        css::uno::Reference< css::beans::XPropertySet > xPropSet(\n"
            "            m_xHAccess->getByHierarchicalName(\n"
            "                buf.makeStringAndClear()), css::uno::UNO_QUERY);\n"
            "        xPropSet->getPropertyValue(\n            "
            "::rtl::OUString::createFromAscii(propName)) >>= ret;\n    }\n"
            "     catch ( css::uno::RuntimeException & e ) {\n        throw e;\n    }\n"
            "     catch ( css::uno::Exception & ) {\n    }\n    return ret;\n";
    }
    o <<"}\n\n";
}

void generateMemberInitialization(std::ostream& o,
                                  ProgramOptions const & options,
                                  TypeManager const & manager,
                                  AttributeInfo const & members)
{
    if (!members.empty()) {
        for (AttributeInfo::const_iterator i(members.begin());
             i != members.end(); ++i)
        {
            RTTypeClass typeClass;
            OString type(i->second.first.replace('.','/'));
            OString name;
            sal_Int32 rank;
            std::vector< OString > arguments;
            codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
                manager, type, true, true, true, &typeClass, &name, &rank,
                &arguments);

            if (sort <= codemaker::UnoType::SORT_CHAR && rank == 0) {
                o << ",\n    m_" << i->first << "(";
                printType(o, options, manager, type, 16, true);
                o << ")";
            }
        }
    }
}

void generateMemberDeclaration(std::ostream& o,
                               ProgramOptions const & options,
                               TypeManager const & manager,
                               AttributeInfo const & members)
{
    for (AttributeInfo::const_iterator i(members.begin());
         i != members.end(); ++i)
    {
        o << "    ";
        printType(o, options, manager, i->second.first.replace('.','/'),
                  1, false);
        o << " m_" << i->first << ";\n";  
    }
}

OString generateClassDefinition(std::ostream& o,
         ProgramOptions const & options,
         TypeManager const & manager,
         OString const & classname,
         std::hash_set< OString, OStringHash > const & interfaces,
         AttributeInfo const & properties,
         AttributeInfo const & attributes,
         std::hash_set< OString, OStringHash > const & propinterfaces,
         OString const & propertyhelper, bool supportxcomponent)
{
    OStringBuffer parentname(64);
    o << "class " << classname << ":\n";
    
    if (!interfaces.empty()) {
        if (supportxcomponent) {
            parentname.append("::cppu::WeakComponentImplHelper");
            parentname.append(static_cast<sal_Int32>(interfaces.size()));
            o << "    private ::cppu::BaseMutex,\n"
              << "    public ::cppu::WeakComponentImplHelper"
              << interfaces.size() << "<";
        } else {
            parentname.append("::cppu::WeakImplHelper");
            parentname.append(static_cast<sal_Int32>(interfaces.size()));
            o << "    public ::cppu::WeakImplHelper" << interfaces.size() << "<";
        }
      
        std::hash_set< OString, OStringHash >::const_iterator iter =
            interfaces.begin();
        while (iter != interfaces.end())
        {
            o << "\n        " << scopedCppName(*iter, false, true);
            iter++;
            if (iter != interfaces.end())
                o << ",";
            else
                o << ">";
        }
    }
    
    if (propertyhelper.getLength() > 1) {
        o << ",\n    public ::cppu::PropertySetMixin< "
          << scopedCppName(propertyhelper, false, true) << " >";
    }
    
    o << "\n{\npublic:\n"
      << "    explicit " << classname << "("
      << "css::uno::Reference< css::uno::XComponentContext > const & context);\n\n";

    // generate component/service helper functions
//     o << "    // component and service helper functions:\n"
//       << "    static ::rtl::OUString SAL_CALL _getImplementationName();\n"
//       << "    static css::uno::Sequence< ::rtl::OUString > SAL_CALL "
//       << "_getSupportedServiceNames();\n"
//       << "    static css::uno::Reference< css::uno::XInterface > SAL_CALL _create("
//       << "\n        css::uno::Reference< css::uno::XComponentContext > const & "
//       << "context);\n\n";
    
    // overload queryInterface
    if (propertyhelper.getLength() > 1) {
        o << "    // ::com::sun::star::uno::XInterface:\n"
            "    virtual css::uno::Any SAL_CALL queryInterface("
            "css::uno::Type const & type) throw ("
            "css::uno::RuntimeException);\n";

        OStringBuffer buffer(256);
        buffer.append(parentname);
        buffer.append("< ");
        std::hash_set< OString, OStringHash >::const_iterator iter =
            interfaces.begin();
        while (iter != interfaces.end())
        {
            buffer.append(scopedCppName(*iter, false, true));            
            iter++;
            if (iter != interfaces.end())
                buffer.append(", ");
            else
                buffer.append(" >");
        }
        OString parent(buffer.makeStringAndClear());
        o << "    virtual void SAL_CALL acquire() throw ()\n        { "
          << parent << "::acquire(); }\n";
        o << "    virtual void SAL_CALL release() throw ()\n        { "
          << parent << "::release(); }\n\n";
    }
    
    std::hash_set< OString, OStringHash >::const_iterator it =
        interfaces.begin();
    codemaker::GeneratedTypeSet generated;
    while (it != interfaces.end())
    {
        typereg::Reader reader(manager.getTypeReader((*it).replace('.','/')));
        printMethods(o, options, manager, reader, generated, "", "", "    ",
                     true, propertyhelper);
        it++;
    }
    
    o << "private:\n    " << classname << "(const " << classname << " &); // not defined\n"
      << "    " << classname << "& operator=(const " << classname << " &); // not defined\n\n"
      << "    // destructor is private and will be called indirectly by the release call"
      << "    virtual ~" << classname << "() {}\n\n";

    if (options.componenttype == 2) {
        o << "    typedef std::hash_map< ::sal_Int32, rtl::OUString, "
            "std::hash<::sal_Int32> > ParamMap;\n"
            "    typedef std::hash_map< rtl::OUString, ParamMap, "
            "rtl::OUStringHash > FunctionMap;\n\n"
            "    ::rtl::OUString SAL_CALL getAddinProperty(const ::rtl::OUString & "
            "funcName, const ::rtl::OUString & paramName, const char * propName) "
            "throw (css::uno::RuntimeException);\n\n";        
    }    

    if (supportxcomponent) {
        o << "    // overload WeakComponentImplHelperBase::disposing()\n"
            "    // This function is called upon disposing the component,\n"
            "    // if your component needs special work when it becomes\n"
            "    // disposed, do it here.\n"
            "    virtual void SAL_CALL disposing();\n\n";
    }
    
    // members
    o << "    css::uno::Reference< css::uno::XComponentContext > m_xContext;\n";
    if (!supportxcomponent && !attributes.empty())
        o << "   mutable ::osl::Mutex m_aMutex;\n";

    // additional member for add-ons
    if (options.componenttype == 3) {
        o << "    css::uno::Reference< css::frame::XFrame > m_xFrame;\n";
    }

    if (options.componenttype == 2) {
        if (options.backwardcompatible) {
            o <<"    css::uno::Reference< css::container::XHierarchicalNameAccess > "
                "m_xHAccess;\n"
                "    css::uno::Reference< css::container::XHierarchicalNameAccess > "
                "m_xCompAccess;\n"
                "    FunctionMap m_functionMap;\n";
        }
        o << "    css::lang::Locale m_locale;\n";
    }

    generateMemberDeclaration(o, options, manager, properties);
    generateMemberDeclaration(o, options, manager, attributes);
    
//     if (!properties.empty())
//     {
//         AttributeInfo::const_iterator iter = properties.begin();
//         while (iter != properties.end())
//         {
//             o << "    ";
//             printType(o, options, manager, iter->second.first.replace('.','/'),
//                       1, false);
//             o << " m_" << iter->first << ";\n";  
//             iter++;
//         }
//     }
//     if (!attributes.empty())
//     {
//         AttributeInfo::const_iterator iter = attributes.begin();
//         while (iter != attributes.end())
//         {
//             o << "    ";
//             printType(o, options, manager, iter->second.first.replace('.','/'),
//                       1, false);
//             o << " m_" << iter->first << ";\n";  
//             iter++;
//         }
//     }
    
    o << "};\n\n";
    
    // generate constructor
    if (options.componenttype == 2) {
        generateAddinConstructorAndHelper(o, options, manager,
                                          classname, interfaces);
    } else {    
        o << classname << "::" << classname
          << "(css::uno::Reference< css::uno::XComponentContext > const & context) :\n";
        if (supportxcomponent) {
            o << "    ::cppu::WeakComponentImplHelper" << interfaces.size() << "<";
            std::hash_set< OString, OStringHash >::const_iterator iter =
                interfaces.begin();
            while (iter != interfaces.end()) {
                o << "\n        " << scopedCppName(*iter, false, true);
                iter++;
                if (iter != interfaces.end())
                    o << ",";
                else
                    o << ">(m_aMutex),\n";
            }        
        }
        if (propertyhelper.getLength() > 1) {
            o << "    ::cppu::PropertySetMixin< "
              << scopedCppName(propertyhelper, false, true) << " >(\n"
              << "        context, static_cast< Implements >(\n            ";
            OStringBuffer buffer(128);
            if (propinterfaces.find("com/sun/star/beans/XPropertySet")
                != propinterfaces.end()) {                
                buffer.append("IMPLEMENTS_PROPERTY_SET");
            }
            if (propinterfaces.find("com/sun/star/beans/XFastPropertySet")
                != propinterfaces.end()) {
                if (buffer.getLength() > 0)
                    buffer.append(" | IMPLEMENTS_FAST_PROPERTY_SET");
                else
                    buffer.append("IMPLEMENTS_FAST_PROPERTY_SET");
            }
            if (propinterfaces.find("com/sun/star/beans/XPropertyAccess")
                != propinterfaces.end()) {
                if (buffer.getLength() > 0)
                    buffer.append(" | IMPLEMENTS_PROPERTY_ACCESS");
                else
                    buffer.append("IMPLEMENTS_PROPERTY_ACCESS");
            }
            o << buffer.makeStringAndClear()
              << "), css::uno::Sequence< ::rtl::OUString >()),\n";
        }
        o << "    m_xContext(context)";

        generateMemberInitialization(o, options, manager, properties);
        generateMemberInitialization(o, options, manager, attributes);
        
        o << "\n{}\n\n";
    }

    // generate service/component helper function implementations
//     generateServiceHelper(o, options.implname, classname, services);

    if (supportxcomponent) {
        o << "// overload WeakComponentImplHelperBase::disposing()\n"
            "// This function is called upon disposing the component,\n"
            "// if your component needs special work when it becomes\n"
            "// disposed, do it here.\n"
            "void SAL_CALL " << classname << "::disposing()\n{\n\n}\n\n";
    }
    
    return parentname.makeStringAndClear();
}

void generateXServiceInfoBodies(std::ostream& o,
                                OString const & classname,
                                OString const & comphelpernamespace)
{
    o << "// com.sun.star.uno.XServiceInfo:\n"
      << "::rtl::OUString SAL_CALL " << classname << "getImplementationName() "
      << "throw (css::uno::RuntimeException)\n{\n    "
      << "return " << comphelpernamespace << "::_getImplementationName();\n}\n\n";

    o << "::sal_Bool SAL_CALL " << classname
      << "supportsService(::rtl::OUString const & "
      << "serviceName) throw (css::uno::RuntimeException)\n{\n    "
      << "css::uno::Sequence< ::rtl::OUString > serviceNames = "
      << comphelpernamespace << "::_getSupportedServiceNames();\n    " 
      << "for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {\n    "
      << "    if (serviceNames[i] == serviceName)\n            return sal_True;\n"
      << "    }\n    return sal_False;\n}\n\n";

    o << "css::uno::Sequence< ::rtl::OUString > SAL_CALL " << classname
      << "getSupportedServiceNames() throw (css::uno::RuntimeException)\n{\n    "
      << "return " << comphelpernamespace
      << "::_getSupportedServiceNames();\n}\n\n";    
}


void generateMethodBodies(std::ostream& o,
        ProgramOptions const & options,                    
        TypeManager const & manager,
        std::hash_set< OString, OStringHash > const & interfaces,
        OString const & classname,
        OString const & comphelpernamespace,
        OString const & propertyhelper)
{
    OString name(classname.concat("::"));
    std::hash_set< OString, OStringHash >::const_iterator iter =
        interfaces.begin();
    codemaker::GeneratedTypeSet generated;
    while (iter != interfaces.end()) {
        if ( (*iter).equals("com.sun.star.lang.XServiceInfo") ) {
            generateXServiceInfoBodies(o, name, comphelpernamespace);
            generated.add(*iter);
        } else {
            typereg::Reader reader(manager.getTypeReader((*iter).replace('.','/')));
            printMethods(o, options, manager, reader, generated, "_",
                         name, "", true, propertyhelper);
        }
        iter++;
    }
}

void generateQueryInterface(std::ostream& o,
                            ProgramOptions const & options,                    
                            TypeManager const & manager,
                            const std::hash_set< OString, OStringHash >& interfaces,
                            OString const & parentname,
                            OString const & classname,
                            OString const & propertyhelper)
{
    if (propertyhelper.getLength() == 0)
        return;
    
    o << "css::uno::Any " << classname
      << "::queryInterface(css::uno::Type const & type) throw ("
        "css::uno::RuntimeException)\n{\n    ";

    if (propertyhelper.getLength() >= 1)
        o << "return ";
    else
        o << "css::uno::Any a(";

    o   << parentname << "<";
    std::hash_set< OString, OStringHash >::const_iterator iter =
        interfaces.begin();
    while (iter != interfaces.end())
    {
        o << "\n        " << scopedCppName(*iter, false, true);
        iter++;
        if (iter != interfaces.end())
            o << ",";
        else
            o << ">";
    }

    if (propertyhelper.getLength() >= 1) {
        o << "::queryInterface(type);\n";
    } else {
        o << "::queryInterface(type));\n";
        o << "    return a.hasValue() ? a\n        : (";
        if (propertyhelper.equals("_")) {
            o << "::cppu::OPropertySetHelper::queryInterface(type));\n";
        } else {
            o << "::cppu::PropertySetMixin<\n            ";
            printType(o, options, manager, propertyhelper.replace('.', '/'),
                      0, false);            
            o << " >::queryInterface(\n               type));\n";
        }        
    }
    o << "}\n\n";
}

void generateSkeleton(ProgramOptions const & options,
                      TypeManager const & manager,
                      std::vector< OString > const & types,
                      OString const & /*delegate*/)
{
    // special handling of calc add-ins
    if (options.componenttype == 2) {
        generateCalcAddin(options, manager, types);
        return;
    }
    
    std::hash_set< OString, OStringHash > interfaces;
    std::hash_set< OString, OStringHash > services;
    AttributeInfo properties;
    AttributeInfo attributes;
    std::hash_set< OString, OStringHash > propinterfaces;
    bool serviceobject = false;
    bool supportxcomponent = false;

    std::vector< OString >::const_iterator iter = types.begin();
    while (iter != types.end()) {
        checkType(manager, *iter, interfaces, services, properties);
        iter++;
    }

    if (options.componenttype == 3) {
        // the Protocolhandler service is mandatory for an protocol handler add-on,
        // so it is defaulted. The XDispatchProvider provides Dispatch objects for
        // certain functions and the generated impl object implements XDispatch
        // directly for simplicity reasons.
        checkType(manager, "com.sun.star.frame.ProtocolHandler",
                  interfaces, services, properties);
        checkType(manager, "com.sun.star.frame.XDispatch",
                  interfaces, services, properties);        
    }
    
    // check if service object or simple UNO object
    if (!services.empty())
        serviceobject = true;
    
    OString propertyhelper = checkPropertyHelper(
        options, manager, services, interfaces, attributes, propinterfaces);

    checkDefaultInterfaces(interfaces, services, propertyhelper);
    
    if (interfaces.size() > 12)
        throw CannotDumpException(
            "the skeletonmaker supports components with 12 interfaces "
            "only (limitation of the UNO implementation helpers)!");
    

    supportxcomponent = checkXComponentSupport(manager, interfaces);

    OString compFileName;
    OString tmpFileName;
    std::ostream* pofs = NULL;
    bool standardout = getOutputStream(options, ".cxx",
                                       &pofs, compFileName, tmpFileName);

    try {
        if (!standardout && options.license) {
            printLicenseHeader(*pofs, compFileName);
        }
        
        generateIncludes(*pofs, interfaces, properties, propertyhelper,
                         serviceobject, supportxcomponent);

        if (options.componenttype == 3) {
            *pofs << "#include \"com/sun/star/frame/XFrame.hpp\"\n";
        }

        // namespace
        OString nmspace;
        short nm = 0;

        if (serviceobject) {
            nmspace = generateCompHelperDeclaration(*pofs, options.implname);

            *pofs <<
                "\n\n/// anonymous implementation namespace\nnamespace {\n\n"
                "namespace css = ::com::sun::star;\n\n";
        } else {
            nm = generateNamespace(*pofs, options.implname, false, nmspace);
            *pofs << "namespace css = ::com::sun::star;\n\n";
        }
        
        sal_Int32 index = 0;
        OString classname(options.implname);
        if ((index = classname.lastIndexOf('.')) > 0)
            classname = classname.copy(index+1);

        OString parentname(
            generateClassDefinition(*pofs,
                options, manager, classname, interfaces, properties,
                attributes, propinterfaces, propertyhelper, supportxcomponent));

        generateQueryInterface(*pofs, options, manager, interfaces, parentname,
                               classname, propertyhelper);
        
		generateMethodBodies(*pofs, options, manager, interfaces, classname,
                             nmspace, propertyhelper);

        if (serviceobject) {
            // close namepsace
            *pofs << "} // closing anonymous implementation namespace\n\n";
            
            generateCompHelperDefinition(*pofs, options.implname,
                                         classname, services);
            generateCompFunctions(*pofs, nmspace);
        } else {
            // close namepsace
            for (short i=0; i < nm; i++)
                *pofs << "} ";
            *pofs << (nm > 0 ? "// closing namespace\n\n" : "\n");
        }

        if ( !standardout && pofs && ((std::ofstream*)pofs)->is_open()) {
            ((std::ofstream*)pofs)->close();
            delete pofs;
            OSL_VERIFY(makeValidTypeFile(compFileName, tmpFileName, sal_False));
        }
    } catch(CannotDumpException& e) {

        std::cerr << "ERROR: " << e.m_message.getStr() << "\n";        
        if ( !standardout ) {
            if (pofs && ((std::ofstream*)pofs)->is_open()) {
                ((std::ofstream*)pofs)->close();       
                delete pofs;
            }
            // remove existing type file if something goes wrong to ensure
            // consistency
            if (fileExists(compFileName))
                removeTypeFile(compFileName);
            
            // remove tmp file if something goes wrong
            removeTypeFile(tmpFileName);
        }
    }
}

void generateCalcAddin(ProgramOptions const & options,
                       TypeManager const & manager,
                       std::vector< OString > const & types)
{
    std::hash_set< OString, OStringHash > interfaces;
    std::hash_set< OString, OStringHash > services;
    AttributeInfo properties;
    AttributeInfo attributes;
    std::hash_set< OString, OStringHash > propinterfaces;
    bool serviceobject = false;
    bool supportxcomponent = false;

    
    std::vector< OString >::const_iterator iter = types.begin();
    while (iter != types.end()) {
        checkType(manager, *iter, interfaces, services, properties);
        iter++;
    }
    
    OString sAddinService;
    if (services.size() != 1) {
        throw CannotDumpException(
            "for calc add-in components one and only one service type is necessary!"
            " Please reference a valid type with the '-t' option.");
    }
    
    
    // get the one and only add-in service for later use
    std::hash_set< OString, OStringHash >::const_iterator iter2 = services.begin();
    sAddinService = (*iter2).replace('/', '.');
    if (sAddinService.equals("com.sun.star.sheet.AddIn")) {
        sAddinService = (*(++iter2)).replace('/', '.');
    }
    
    // if backwardcompatible==true the AddIn service needs to be added to the
    // suported service list, the necessary intefaces are mapped to the add-in
    // configuration. Since OO.org 2.0.4 this is obsolete and the add-in is
    // take form the configuration from Calc directly, this simplifies the
    // add-in code
    if (options.backwardcompatible) {
        checkType(manager, "com.sun.star.sheet.AddIn",
                  interfaces, services, properties);
    } else {
        // special case for the optional XLocalization interface. It should be
        // implemented always. But it is parent of the XAddIn and we need it only
        // if backwardcompatible is false.
        if (interfaces.find("com.sun.star.lang.XLocalizable") == interfaces.end()) {
            interfaces.insert("com.sun.star.lang.XLocalizable");
        }
    }    
    
    OString propertyhelper = checkPropertyHelper(
        options, manager, services, interfaces, attributes, propinterfaces);

    if (propertyhelper.getLength() > 0)
        std::cerr << "WARNING: interfaces specifying calc add-in functions "
            "shouldn't support attributes!\n";
    
    checkDefaultInterfaces(interfaces, services, propertyhelper);
    
    if (interfaces.size() > 12) {
        throw CannotDumpException(
            "the skeletonmaker supports components with 12 interfaces "
            "only (limitation of the UNO implementation helpers)!");
    }

    // check if service object or simple UNO object
    if (!services.empty())
        serviceobject = true;

    supportxcomponent = checkXComponentSupport(manager, interfaces);
    if (supportxcomponent)
        std::cerr << "WARNING: add-ins shouldn't support "
            "com.sun.star.uno.XComponent!\n";

    OString compFileName;
    OString tmpFileName;
    std::ostream* pofs = NULL;
    bool standardout = getOutputStream(options, ".cxx",
                                       &pofs, compFileName, tmpFileName);
    
    try {
        if (!standardout && options.license) {
            printLicenseHeader(*pofs, compFileName);
        }
                
        generateIncludes(*pofs, interfaces, properties, propertyhelper,
                         serviceobject, supportxcomponent);

        *pofs <<
            "#include \"com/sun/star/beans/PropertyValue.hpp\"\n"
            "#include \"com/sun/star/beans/XPropertySet.hpp\"\n"
            "#include \"com/sun/star/container/XNameAccess.hpp\"\n"
            "#include \"com/sun/star/container/XHierarchicalNameAccess.hpp\"\n\n"
            "#include \"rtl/ustrbuf.hxx\"\n\n"
            "#include <hash_map>\n"
            "#include <set>\n";
        
        // namespace
        OString nmspace(generateCompHelperDeclaration(*pofs, options.implname));

        *pofs <<
            "\n\n// anonymous implementation namespace\nnamespace {\n\n"
            "namespace css = ::com::sun::star;\n\n";

        sal_Int32 index = 0;
        OString classname(options.implname);
        if ((index = classname.lastIndexOf('.')) > 0) {
            classname = classname.copy(index+1);
        }

        if (options.backwardcompatible) {
            *pofs << "static const char * sADDIN_SERVICENAME = \""
                  << sAddinService << "\";\n\n";
            *pofs << "static const char * sDISPLAYNAME = \"DisplayName\";\n"
                "static const char * sDESCRIPTION = \"Description\";\n"
                "static const char * sCATEGORY = \"Category\";\n"
                "static const char * sCATEGORYDISPLAYNAME = \"CategoryDisplayName\";"
                "\n\n";
        }
        
        OString parentname(
            generateClassDefinition(*pofs,
                options, manager, classname, interfaces, properties,
                attributes, propinterfaces, propertyhelper, supportxcomponent));

        generateQueryInterface(*pofs, options, manager, interfaces, parentname,
                               classname, propertyhelper);
        
		generateMethodBodies(*pofs, options, manager, interfaces, classname,
                             nmspace, propertyhelper);
        
        // close namepsace
        *pofs << "} // closing anonymous implementation namespace\n\n";

        generateCompHelperDefinition(*pofs, options.implname, classname,
                                     services);
        
        generateCompFunctions(*pofs, nmspace);
        
        if ( !standardout && pofs && ((std::ofstream*)pofs)->is_open()) {
            ((std::ofstream*)pofs)->close();
            delete pofs;
            OSL_VERIFY(makeValidTypeFile(compFileName, tmpFileName, sal_False));
        }
    } catch(CannotDumpException& e) {

        std::cerr << "ERROR: " << e.m_message.getStr() << "\n";
        if ( !standardout ) {
            if (pofs && ((std::ofstream*)pofs)->is_open()) {
                ((std::ofstream*)pofs)->close();       
                delete pofs;
            }
            // remove existing type file if something goes wrong to ensure
            // consistency
            if (fileExists(compFileName))
                removeTypeFile(compFileName);
            
            // remove tmp file if something goes wrong
            removeTypeFile(tmpFileName);
        }
    }
}

} }


