/**************************************************************
 *
 * 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 namespace
    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 namespace
    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 namespace
            *pofs << "} // closing anonymous implementation namespace\n\n";

            generateCompHelperDefinition(*pofs, options.implname,
                                         classname, services);
            generateCompFunctions(*pofs, nmspace);
        } else {
            // close namespace
            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
    // supported service list, the necessary interfaces are mapped to the add-in
    // configuration. Since OO.org 2.0.4 this is obsolete and the add-in is
    // taken from 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 namespace
        *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);
        }
    }
}

} }
