[Libreoffice-commits] core.git: 4 commits - postprocess/Rdb_services.mk RepositoryExternal.mk Repository.mk sccomp/CppunitTest_sccomp_lpsolver.mk sccomp/Library_coinmpsolver.mk sccomp/Library_solver.mk sccomp/Module_sccomp.mk sccomp/source solenv/gbuild

Matúš Kukan matus.kukan at collabora.com
Thu Apr 3 02:43:51 PDT 2014


 Repository.mk                                |    3 
 RepositoryExternal.mk                        |    8 
 postprocess/Rdb_services.mk                  |    2 
 sccomp/CppunitTest_sccomp_lpsolver.mk        |    1 
 sccomp/Library_coinmpsolver.mk               |   34 -
 sccomp/Library_solver.mk                     |    8 
 sccomp/Module_sccomp.mk                      |    3 
 sccomp/source/solver/CoinMPSolver.cxx        |  344 ++++++++++++++
 sccomp/source/solver/LpsolveSolver.cxx       |  336 ++++++++++++++
 sccomp/source/solver/SolverComponent.cxx     |  270 +++++++++++
 sccomp/source/solver/SolverComponent.hxx     |  158 ++++++
 sccomp/source/solver/coinmpsolver.component  |    5 
 sccomp/source/solver/lpsolvesolver.component |   26 +
 sccomp/source/solver/solver-lpsolve.cxx      |  631 --------------------------
 sccomp/source/solver/solver.component        |   25 -
 sccomp/source/solver/solver.cxx              |  639 ---------------------------
 sccomp/source/solver/solver.hxx              |  120 -----
 solenv/gbuild/Library.mk                     |    5 
 18 files changed, 1155 insertions(+), 1463 deletions(-)

New commits:
commit 077bdc73f2bcd625be1030fa8ff630c3dbd83657
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Thu Mar 27 14:51:46 2014 +0100

    sccomp: Share common code and have only one library.
    
    And use constructor feature for UNO implementations.
    
    Change-Id: I42b6a6f417049cc8e2d44b74c7adc552680b1f2d

diff --git a/Repository.mk b/Repository.mk
index b0a9193..e18ecc2 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -150,7 +150,6 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,base, \
 $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,calc, \
 	analysis \
 	calc \
-	$(if $(ENABLE_COINMP),coinmpsolver) \
 	date \
 	pricing \
 	sc \
@@ -158,7 +157,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,calc, \
 	scfilt \
 	scui \
 	$(if $(ENABLE_OPENCL),scopencl) \
-	$(if $(ENABLE_LPSOLVE),solver) \
+	$(if $(ENABLE_COINMP)$(ENABLE_LPSOLVE),solver) \
 	$(if $(DISABLE_SCRIPTING),,vbaobj) \
 	$(if $(ENABLE_TELEPATHY),tubes) \
 ))
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 150e289..f6a4e2b 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -2020,6 +2020,10 @@ $(eval $(call gb_Helper_register_packages_for_install,ooo,\
 
 endif # SYSTEM_LPSOLVE
 
+else
+
+gb_LinkTarget__use_lpsolve :=
+
 endif # ENABLE_LPSOLVE
 
 ifneq ($(ENABLE_COINMP),)
@@ -2052,6 +2056,10 @@ $(eval $(call gb_Helper_register_packages_for_install,ooo,\
 	coinmp \
 ))
 
+else
+
+gb_LinkTarget__use_coinmp :=
+
 endif # ENABLE_COINMP
 
 ifeq ($(ENABLE_GIO),TRUE)
diff --git a/postprocess/Rdb_services.mk b/postprocess/Rdb_services.mk
index 83ce7dc..cffd75b 100755
--- a/postprocess/Rdb_services.mk
+++ b/postprocess/Rdb_services.mk
@@ -113,7 +113,7 @@ $(eval $(call gb_Rdb_add_components,services,\
 		sccomp/source/solver/coinmpsolver \
 	) \
 	$(if $(ENABLE_LPSOLVE), \
-		sccomp/source/solver/solver \
+		sccomp/source/solver/lpsolvesolver \
 	) \
 	writerfilter/util/writerfilter \
 	writerperfect/source/draw/wpftdraw \
diff --git a/sccomp/Library_coinmpsolver.mk b/sccomp/Library_coinmpsolver.mk
deleted file mode 100644
index 849ce0f..0000000
--- a/sccomp/Library_coinmpsolver.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-#
-# This file is part of the LibreOffice project.
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-$(eval $(call gb_Library_Library,coinmpsolver))
-
-$(eval $(call gb_Library_set_componentfile,coinmpsolver,sccomp/source/solver/coinmpsolver))
-
-$(eval $(call gb_Library_use_sdk_api,coinmpsolver))
-
-$(eval $(call gb_Library_use_libraries,coinmpsolver,\
-	comphelper \
-	cppu \
-	cppuhelper \
-	sal \
-	tl \
-	i18nlangtag \
-	$(gb_UWINAPI) \
-))
-
-$(eval $(call gb_Library_use_externals,coinmpsolver,\
-	boost_headers \
-	coinmp \
-))
-
-$(eval $(call gb_Library_add_exception_objects,coinmpsolver,\
-	sccomp/source/solver/solver \
-))
-
-# vim: set noet sw=4 ts=4:
diff --git a/sccomp/Library_solver.mk b/sccomp/Library_solver.mk
index e1b2ca3..4507288 100644
--- a/sccomp/Library_solver.mk
+++ b/sccomp/Library_solver.mk
@@ -19,7 +19,8 @@
 
 $(eval $(call gb_Library_Library,solver))
 
-$(eval $(call gb_Library_set_componentfile,solver,sccomp/source/solver/solver))
+$(if $(ENABLE_COINMP),$(eval $(call gb_Library_set_componentfile,solver,sccomp/source/solver/coinmpsolver)))
+$(if $(ENABLE_LPSOLVE),$(eval $(call gb_Library_set_componentfile,solver,sccomp/source/solver/lpsolvesolver)))
 
 $(eval $(call gb_Library_use_sdk_api,solver))
 
@@ -35,11 +36,14 @@ $(eval $(call gb_Library_use_libraries,solver,\
 
 $(eval $(call gb_Library_use_externals,solver,\
 	boost_headers \
+	coinmp \
 	lpsolve \
 ))
 
 $(eval $(call gb_Library_add_exception_objects,solver,\
-	sccomp/source/solver/solver-lpsolve \
+	sccomp/source/solver/SolverComponent \
+	$(if $(ENABLE_COINMP), sccomp/source/solver/CoinMPSolver) \
+	$(if $(ENABLE_LPSOLVE), sccomp/source/solver/LpsolveSolver) \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/sccomp/Module_sccomp.mk b/sccomp/Module_sccomp.mk
index 40ecd29..6960f57 100644
--- a/sccomp/Module_sccomp.mk
+++ b/sccomp/Module_sccomp.mk
@@ -20,8 +20,7 @@
 $(eval $(call gb_Module_Module,sccomp))
 
 $(eval $(call gb_Module_add_targets,sccomp,\
-	$(if $(ENABLE_COINMP), Library_coinmpsolver) \
-	$(if $(ENABLE_LPSOLVE), Library_solver) \
+	$(if $(ENABLE_COINMP)$(ENABLE_LPSOLVE), Library_solver) \
 ))
 
 $(eval $(call gb_Module_add_l10n_targets,sccomp,\
diff --git a/sccomp/source/solver/solver.cxx b/sccomp/source/solver/CoinMPSolver.cxx
similarity index 50%
rename from sccomp/source/solver/solver.cxx
rename to sccomp/source/solver/CoinMPSolver.cxx
index 76ac1af..13ecd3b 100644
--- a/sccomp/source/solver/solver.cxx
+++ b/sccomp/source/solver/CoinMPSolver.cxx
@@ -19,276 +19,34 @@
 
 #include <CoinMP.h>
 
-#include "solver.hxx"
+#include "SolverComponent.hxx"
 #include "solver.hrc"
 
-#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/container/XIndexAccess.hpp>
 #include <com/sun/star/frame/XModel.hpp>
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
-#include <com/sun/star/sheet/XSpreadsheet.hpp>
 #include <com/sun/star/table/CellAddress.hpp>
-#include <com/sun/star/table/CellRangeAddress.hpp>
-#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
 
 #include <rtl/math.hxx>
-#include <rtl/ustrbuf.hxx>
-#include <cppuhelper/factory.hxx>
-#include <cppuhelper/supportsservice.hxx>
 #include <vector>
-#include <boost/unordered_map.hpp>
-
-#include <tools/resmgr.hxx>
 
 using namespace com::sun::star;
 
-
-#define STR_NONNEGATIVE   "NonNegative"
-#define STR_INTEGER       "Integer"
-#define STR_TIMEOUT       "Timeout"
-#define STR_EPSILONLEVEL  "EpsilonLevel"
-#define STR_LIMITBBDEPTH  "LimitBBDepth"
-
-
-//  Resources from tools are used for translated strings
-
-static ResMgr* pSolverResMgr = NULL;
-
-static OUString lcl_GetResourceString( sal_uInt32 nId )
-{
-    if (!pSolverResMgr)
-        pSolverResMgr = ResMgr::CreateResMgr("solver");
-
-    return ResId(nId, *pSolverResMgr).toString();
-}
-
-
-
-namespace
+class CoinMPSolver : public SolverComponent
 {
-    enum
-    {
-        PROP_NONNEGATIVE,
-        PROP_INTEGER,
-        PROP_TIMEOUT,
-        PROP_EPSILONLEVEL,
-        PROP_LIMITBBDEPTH
-    };
-}
+public:
+    CoinMPSolver() {}
+    virtual ~CoinMPSolver() SAL_OVERRIDE {}
 
-
-
-// hash map for the coefficients of a dependent cell (objective or constraint)
-// The size of each vector is the number of columns (variable cells) plus one, first entry is initial value.
-
-struct ScSolverCellHash
-{
-    size_t operator()( const table::CellAddress& rAddress ) const
+private:
+    virtual void SAL_CALL solve() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+    virtual OUString SAL_CALL getImplementationName()
+        throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     {
-        return ( rAddress.Sheet << 24 ) | ( rAddress.Column << 16 ) | rAddress.Row;
+        return OUString("com.sun.star.comp.Calc.CoinMPSolver");
     }
 };
 
-inline bool AddressEqual( const table::CellAddress& rAddr1, const table::CellAddress& rAddr2 )
-{
-    return rAddr1.Sheet == rAddr2.Sheet && rAddr1.Column == rAddr2.Column && rAddr1.Row == rAddr2.Row;
-}
-
-struct ScSolverCellEqual
-{
-    bool operator()( const table::CellAddress& rAddr1, const table::CellAddress& rAddr2 ) const
-    {
-        return AddressEqual( rAddr1, rAddr2 );
-    }
-};
-
-typedef boost::unordered_map< table::CellAddress, std::vector<double>, ScSolverCellHash, ScSolverCellEqual > ScSolverCellHashMap;
-
-
-
-static uno::Reference<table::XCell> lcl_GetCell( const uno::Reference<sheet::XSpreadsheetDocument>& xDoc,
-                                          const table::CellAddress& rPos )
-{
-    uno::Reference<container::XIndexAccess> xSheets( xDoc->getSheets(), uno::UNO_QUERY );
-    uno::Reference<sheet::XSpreadsheet> xSheet( xSheets->getByIndex( rPos.Sheet ), uno::UNO_QUERY );
-    return xSheet->getCellByPosition( rPos.Column, rPos.Row );
-}
-
-static void lcl_SetValue( const uno::Reference<sheet::XSpreadsheetDocument>& xDoc,
-                   const table::CellAddress& rPos, double fValue )
-{
-    lcl_GetCell( xDoc, rPos )->setValue( fValue );
-}
-
-static double lcl_GetValue( const uno::Reference<sheet::XSpreadsheetDocument>& xDoc,
-                     const table::CellAddress& rPos )
-{
-    return lcl_GetCell( xDoc, rPos )->getValue();
-}
-
-
-
-SolverComponent::SolverComponent( const uno::Reference<uno::XComponentContext>& /* rSMgr */ ) :
-    OPropertyContainer( GetBroadcastHelper() ),
-    mbMaximize( sal_True ),
-    mbNonNegative( sal_False ),
-    mbInteger( sal_False ),
-    mnTimeout( 100 ),
-    mnEpsilonLevel( 0 ),
-    mbLimitBBDepth( sal_True ),
-    mbSuccess( sal_False ),
-    mfResultValue( 0.0 )
-{
-    // for XPropertySet implementation:
-    registerProperty( STR_NONNEGATIVE,  PROP_NONNEGATIVE,  0, &mbNonNegative,  getCppuType( &mbNonNegative )  );
-    registerProperty( STR_INTEGER,      PROP_INTEGER,      0, &mbInteger,      getCppuType( &mbInteger )      );
-    registerProperty( STR_TIMEOUT,      PROP_TIMEOUT,      0, &mnTimeout,      getCppuType( &mnTimeout )      );
-    registerProperty( STR_EPSILONLEVEL, PROP_EPSILONLEVEL, 0, &mnEpsilonLevel, getCppuType( &mnEpsilonLevel ) );
-    registerProperty( STR_LIMITBBDEPTH, PROP_LIMITBBDEPTH, 0, &mbLimitBBDepth, getCppuType( &mbLimitBBDepth ) );
-}
-
-SolverComponent::~SolverComponent()
-{
-}
-
-IMPLEMENT_FORWARD_XINTERFACE2( SolverComponent, SolverComponent_Base, OPropertyContainer )
-IMPLEMENT_FORWARD_XTYPEPROVIDER2( SolverComponent, SolverComponent_Base, OPropertyContainer )
-
-cppu::IPropertyArrayHelper* SolverComponent::createArrayHelper() const
-{
-    uno::Sequence<beans::Property> aProps;
-    describeProperties( aProps );
-    return new cppu::OPropertyArrayHelper( aProps );
-}
-
-cppu::IPropertyArrayHelper& SAL_CALL SolverComponent::getInfoHelper()
-{
-    return *getArrayHelper();
-}
-
-uno::Reference<beans::XPropertySetInfo> SAL_CALL SolverComponent::getPropertySetInfo() throw(uno::RuntimeException, std::exception)
-{
-    return createPropertySetInfo( getInfoHelper() );
-}
-
-// XSolverDescription
-
-OUString SAL_CALL SolverComponent::getComponentDescription() throw (uno::RuntimeException, std::exception)
-{
-    return lcl_GetResourceString( RID_COINMP_SOLVER_COMPONENT );
-}
-
-OUString SAL_CALL SolverComponent::getStatusDescription() throw (uno::RuntimeException, std::exception)
-{
-    return maStatus;
-}
-
-OUString SAL_CALL SolverComponent::getPropertyDescription( const OUString& rPropertyName ) throw (uno::RuntimeException, std::exception)
-{
-    sal_uInt32 nResId = 0;
-    sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName );
-    switch (nHandle)
-    {
-        case PROP_NONNEGATIVE:
-            nResId = RID_PROPERTY_NONNEGATIVE;
-            break;
-        case PROP_INTEGER:
-            nResId = RID_PROPERTY_INTEGER;
-            break;
-        case PROP_TIMEOUT:
-            nResId = RID_PROPERTY_TIMEOUT;
-            break;
-        case PROP_EPSILONLEVEL:
-            nResId = RID_PROPERTY_EPSILONLEVEL;
-            break;
-        case PROP_LIMITBBDEPTH:
-            nResId = RID_PROPERTY_LIMITBBDEPTH;
-            break;
-        default:
-            {
-                // unknown - leave empty
-            }
-    }
-    OUString aRet;
-    if ( nResId )
-        aRet = lcl_GetResourceString( nResId );
-    return aRet;
-}
-
-// XSolver: settings
-
-uno::Reference<sheet::XSpreadsheetDocument> SAL_CALL SolverComponent::getDocument() throw(uno::RuntimeException, std::exception)
-{
-    return mxDoc;
-}
-
-void SAL_CALL SolverComponent::setDocument( const uno::Reference<sheet::XSpreadsheetDocument>& _document )
-                                throw(uno::RuntimeException, std::exception)
-{
-    mxDoc = _document;
-}
-
-table::CellAddress SAL_CALL SolverComponent::getObjective() throw(uno::RuntimeException, std::exception)
-{
-    return maObjective;
-}
-
-void SAL_CALL SolverComponent::setObjective( const table::CellAddress& _objective ) throw(uno::RuntimeException, std::exception)
-{
-    maObjective = _objective;
-}
-
-uno::Sequence<table::CellAddress> SAL_CALL SolverComponent::getVariables() throw(uno::RuntimeException, std::exception)
-{
-    return maVariables;
-}
-
-void SAL_CALL SolverComponent::setVariables( const uno::Sequence<table::CellAddress>& _variables )
-                                throw(uno::RuntimeException, std::exception)
-{
-    maVariables = _variables;
-}
-
-uno::Sequence<sheet::SolverConstraint> SAL_CALL SolverComponent::getConstraints() throw(uno::RuntimeException, std::exception)
-{
-    return maConstraints;
-}
-
-void SAL_CALL SolverComponent::setConstraints( const uno::Sequence<sheet::SolverConstraint>& _constraints )
-                                throw(uno::RuntimeException, std::exception)
-{
-    maConstraints = _constraints;
-}
-
-sal_Bool SAL_CALL SolverComponent::getMaximize() throw(uno::RuntimeException, std::exception)
-{
-    return mbMaximize;
-}
-
-void SAL_CALL SolverComponent::setMaximize( sal_Bool _maximize ) throw(uno::RuntimeException, std::exception)
-{
-    mbMaximize = _maximize;
-}
-
-// XSolver: get results
-
-sal_Bool SAL_CALL SolverComponent::getSuccess() throw(uno::RuntimeException, std::exception)
-{
-    return mbSuccess;
-}
-
-double SAL_CALL SolverComponent::getResultValue() throw(uno::RuntimeException, std::exception)
-{
-    return mfResultValue;
-}
-
-uno::Sequence<double> SAL_CALL SolverComponent::getSolution() throw(uno::RuntimeException, std::exception)
-{
-    return maSolution;
-}
-
-void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException, std::exception)
+void SAL_CALL CoinMPSolver::solve() throw(uno::RuntimeException, std::exception)
 {
     uno::Reference<frame::XModel> xModel( mxDoc, uno::UNO_QUERY );
     if ( !xModel.is() )
@@ -327,46 +85,46 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException, std::excepti
     std::vector<table::CellAddress>::const_iterator aVarIter;
     for ( aVarIter = aVariableCells.begin(); aVarIter != aVariableCells.end(); ++aVarIter )
     {
-        lcl_SetValue( mxDoc, *aVarIter, 0.0 );
+        SolverComponent::SetValue( mxDoc, *aVarIter, 0.0 );
     }
 
     // read initial values from all dependent cells
     ScSolverCellHashMap::iterator aCellsIter;
     for ( aCellsIter = aCellsHash.begin(); aCellsIter != aCellsHash.end(); ++aCellsIter )
     {
-        double fValue = lcl_GetValue( mxDoc, aCellsIter->first );
+        double fValue = SolverComponent::GetValue( mxDoc, aCellsIter->first );
         aCellsIter->second.push_back( fValue );                         // store as first element, as-is
     }
 
     // loop through variables
     for ( aVarIter = aVariableCells.begin(); aVarIter != aVariableCells.end(); ++aVarIter )
     {
-        lcl_SetValue( mxDoc, *aVarIter, 1.0 );      // set to 1 to examine influence
+        SolverComponent::SetValue( mxDoc, *aVarIter, 1.0 );      // set to 1 to examine influence
 
         // read value change from all dependent cells
         for ( aCellsIter = aCellsHash.begin(); aCellsIter != aCellsHash.end(); ++aCellsIter )
         {
-            double fChanged = lcl_GetValue( mxDoc, aCellsIter->first );
+            double fChanged = SolverComponent::GetValue( mxDoc, aCellsIter->first );
             double fInitial = aCellsIter->second.front();
             aCellsIter->second.push_back( fChanged - fInitial );
         }
 
-        lcl_SetValue( mxDoc, *aVarIter, 2.0 );      // minimal test for linearity
+        SolverComponent::SetValue( mxDoc, *aVarIter, 2.0 );      // minimal test for linearity
 
         for ( aCellsIter = aCellsHash.begin(); aCellsIter != aCellsHash.end(); ++aCellsIter )
         {
             double fInitial = aCellsIter->second.front();
             double fCoeff   = aCellsIter->second.back();       // last appended: coefficient for this variable
-            double fTwo     = lcl_GetValue( mxDoc, aCellsIter->first );
+            double fTwo     = SolverComponent::GetValue( mxDoc, aCellsIter->first );
 
             bool bLinear = rtl::math::approxEqual( fTwo, fInitial + 2.0 * fCoeff ) ||
                            rtl::math::approxEqual( fInitial, fTwo - 2.0 * fCoeff );
             // second comparison is needed in case fTwo is zero
             if ( !bLinear )
-                maStatus = lcl_GetResourceString( RID_ERROR_NONLINEAR );
+                maStatus = SolverComponent::GetResourceString( RID_ERROR_NONLINEAR );
         }
 
-        lcl_SetValue( mxDoc, *aVarIter, 0.0 );      // set back to zero for examining next variable
+        SolverComponent::SetValue( mxDoc, *aVarIter, 0.0 );      // set back to zero for examining next variable
     }
 
     xModel->unlockControllers();
@@ -565,9 +323,9 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException, std::excepti
     {
         int nSolutionStatus = CoinGetSolutionStatus( hProb );
         if ( nSolutionStatus == 1 )
-            maStatus = lcl_GetResourceString( RID_ERROR_INFEASIBLE );
+            maStatus = SolverComponent::GetResourceString( RID_ERROR_INFEASIBLE );
         else if ( nSolutionStatus == 2 )
-            maStatus = lcl_GetResourceString( RID_ERROR_UNBOUNDED );
+            maStatus = SolverComponent::GetResourceString( RID_ERROR_UNBOUNDED );
         // TODO: detect timeout condition and report as RID_ERROR_TIMEOUT
         // (currently reported as infeasible)
     }
@@ -575,65 +333,12 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException, std::excepti
     CoinUnloadProblem( hProb );
 }
 
-// XServiceInfo
-
-uno::Sequence< OUString > SolverComponent_getSupportedServiceNames()
-{
-    uno::Sequence< OUString > aServiceNames( 1 );
-    aServiceNames[ 0 ] = "com.sun.star.sheet.Solver";
-    return aServiceNames;
-}
-
-OUString SolverComponent_getImplementationName()
-{
-    return OUString("com.sun.star.comp.Calc.CoinMPSolver");
-}
-
-OUString SAL_CALL SolverComponent::getImplementationName() throw(uno::RuntimeException, std::exception)
-{
-    return SolverComponent_getImplementationName();
-}
-
-sal_Bool SAL_CALL SolverComponent::supportsService( const OUString& rServiceName ) throw(uno::RuntimeException, std::exception)
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
+com_sun_star_comp_Calc_CoinMPSolver_get_implementation(
+    css::uno::XComponentContext *,
+    css::uno::Sequence<css::uno::Any> const &)
 {
-    return cppu::supportsService(this, rServiceName);
-}
-
-uno::Sequence<OUString> SAL_CALL SolverComponent::getSupportedServiceNames() throw(uno::RuntimeException, std::exception)
-{
-    return SolverComponent_getSupportedServiceNames();
-}
-
-uno::Reference<uno::XInterface> SolverComponent_createInstance( const uno::Reference<uno::XComponentContext>& rSMgr )
-    throw(uno::Exception)
-{
-    return (cppu::OWeakObject*) new SolverComponent( rSMgr );
-}
-
-extern "C"
-{
-    SAL_DLLPUBLIC_EXPORT void* SAL_CALL coinmp_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
-    {
-        OUString    aImplName( OUString::createFromAscii( pImplName ) );
-        void*       pRet = 0;
-
-        if( pServiceManager )
-        {
-            uno::Reference< lang::XSingleComponentFactory > xFactory;
-            if( aImplName.equals( SolverComponent_getImplementationName() ) )
-                xFactory = cppu::createSingleComponentFactory(
-                        SolverComponent_createInstance,
-                        OUString::createFromAscii( pImplName ),
-                        SolverComponent_getSupportedServiceNames() );
-
-            if( xFactory.is() )
-            {
-                xFactory->acquire();
-                pRet = xFactory.get();
-            }
-        }
-        return pRet;
-    }
+    return cppu::acquire(new CoinMPSolver());
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sccomp/source/solver/LpsolveSolver.cxx b/sccomp/source/solver/LpsolveSolver.cxx
new file mode 100644
index 0000000..3c2a014
--- /dev/null
+++ b/sccomp/source/solver/LpsolveSolver.cxx
@@ -0,0 +1,336 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   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 .
+ *
+ ************************************************************************/
+
+#include "sal/config.h"
+#include <config_lgpl.h>
+
+#undef LANGUAGE_NONE
+#if defined SAL_W32
+#define WINAPI __stdcall
+#endif
+#define LoadInverseLib FALSE
+#define LoadLanguageLib FALSE
+#ifdef SYSTEM_LPSOLVE
+#include <lpsolve/lp_lib.h>
+#else
+#include <lp_lib.h>
+#endif
+#undef LANGUAGE_NONE
+
+#include "SolverComponent.hxx"
+#include "solver.hrc"
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <rtl/math.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <vector>
+
+using namespace com::sun::star;
+
+class LpsolveSolver : public SolverComponent
+{
+public:
+    LpsolveSolver() {}
+    virtual ~LpsolveSolver() SAL_OVERRIDE {}
+
+private:
+    virtual void SAL_CALL solve() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+    virtual OUString SAL_CALL getImplementationName()
+        throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE
+    {
+        return OUString("com.sun.star.comp.Calc.LpsolveSolver");
+    }
+};
+
+void SAL_CALL LpsolveSolver::solve() throw(uno::RuntimeException, std::exception)
+{
+    uno::Reference<frame::XModel> xModel( mxDoc, uno::UNO_QUERY );
+    if ( !xModel.is() )
+        throw uno::RuntimeException();
+
+    maStatus = "";
+    mbSuccess = false;
+
+    if ( mnEpsilonLevel < EPS_TIGHT || mnEpsilonLevel > EPS_BAGGY )
+    {
+        maStatus = SolverComponent::GetResourceString( RID_ERROR_EPSILONLEVEL );
+        return;
+    }
+
+    xModel->lockControllers();
+
+    // collect variables in vector (?)
+
+    std::vector<table::CellAddress> aVariableCells;
+    for (sal_Int32 nPos=0; nPos<maVariables.getLength(); nPos++)
+        aVariableCells.push_back( maVariables[nPos] );
+    size_t nVariables = aVariableCells.size();
+    size_t nVar = 0;
+
+    // collect all dependent cells
+
+    ScSolverCellHashMap aCellsHash;
+    aCellsHash[maObjective].reserve( nVariables + 1 );                  // objective function
+
+    for (sal_Int32 nConstrPos = 0; nConstrPos < maConstraints.getLength(); ++nConstrPos)
+    {
+        table::CellAddress aCellAddr = maConstraints[nConstrPos].Left;
+        aCellsHash[aCellAddr].reserve( nVariables + 1 );                // constraints: left hand side
+
+        if ( maConstraints[nConstrPos].Right >>= aCellAddr )
+            aCellsHash[aCellAddr].reserve( nVariables + 1 );            // constraints: right hand side
+    }
+
+    // set all variables to zero
+    //! store old values?
+    //! use old values as initial values?
+    std::vector<table::CellAddress>::const_iterator aVarIter;
+    for ( aVarIter = aVariableCells.begin(); aVarIter != aVariableCells.end(); ++aVarIter )
+    {
+        SolverComponent::SetValue( mxDoc, *aVarIter, 0.0 );
+    }
+
+    // read initial values from all dependent cells
+    ScSolverCellHashMap::iterator aCellsIter;
+    for ( aCellsIter = aCellsHash.begin(); aCellsIter != aCellsHash.end(); ++aCellsIter )
+    {
+        double fValue = SolverComponent::GetValue( mxDoc, aCellsIter->first );
+        aCellsIter->second.push_back( fValue );                         // store as first element, as-is
+    }
+
+    // loop through variables
+    for ( aVarIter = aVariableCells.begin(); aVarIter != aVariableCells.end(); ++aVarIter )
+    {
+        SolverComponent::SetValue( mxDoc, *aVarIter, 1.0 );      // set to 1 to examine influence
+
+        // read value change from all dependent cells
+        for ( aCellsIter = aCellsHash.begin(); aCellsIter != aCellsHash.end(); ++aCellsIter )
+        {
+            double fChanged = SolverComponent::GetValue( mxDoc, aCellsIter->first );
+            double fInitial = aCellsIter->second.front();
+            aCellsIter->second.push_back( fChanged - fInitial );
+        }
+
+        SolverComponent::SetValue( mxDoc, *aVarIter, 2.0 );      // minimal test for linearity
+
+        for ( aCellsIter = aCellsHash.begin(); aCellsIter != aCellsHash.end(); ++aCellsIter )
+        {
+            double fInitial = aCellsIter->second.front();
+            double fCoeff   = aCellsIter->second.back();       // last appended: coefficient for this variable
+            double fTwo     = SolverComponent::GetValue( mxDoc, aCellsIter->first );
+
+            bool bLinear = rtl::math::approxEqual( fTwo, fInitial + 2.0 * fCoeff ) ||
+                           rtl::math::approxEqual( fInitial, fTwo - 2.0 * fCoeff );
+            // second comparison is needed in case fTwo is zero
+            if ( !bLinear )
+                maStatus = SolverComponent::GetResourceString( RID_ERROR_NONLINEAR );
+        }
+
+        SolverComponent::SetValue( mxDoc, *aVarIter, 0.0 );      // set back to zero for examining next variable
+    }
+
+    xModel->unlockControllers();
+
+    if ( !maStatus.isEmpty() )
+        return;
+
+
+    // build lp_solve model
+
+
+    lprec* lp = make_lp( 0, nVariables );
+    if ( !lp )
+        return;
+
+    set_outputfile( lp, const_cast<char*>( "" ) );  // no output
+
+    // set objective function
+
+    const std::vector<double>& rObjCoeff = aCellsHash[maObjective];
+    REAL* pObjVal = new REAL[nVariables+1];
+    pObjVal[0] = 0.0;                           // ignored
+    for (nVar=0; nVar<nVariables; nVar++)
+        pObjVal[nVar+1] = rObjCoeff[nVar+1];
+    set_obj_fn( lp, pObjVal );
+    delete[] pObjVal;
+    set_rh( lp, 0, rObjCoeff[0] );              // constant term of objective
+
+    // add rows
+
+    set_add_rowmode(lp, TRUE);
+
+    for (sal_Int32 nConstrPos = 0; nConstrPos < maConstraints.getLength(); ++nConstrPos)
+    {
+        // integer constraints are set later
+        sheet::SolverConstraintOperator eOp = maConstraints[nConstrPos].Operator;
+        if ( eOp == sheet::SolverConstraintOperator_LESS_EQUAL ||
+             eOp == sheet::SolverConstraintOperator_GREATER_EQUAL ||
+             eOp == sheet::SolverConstraintOperator_EQUAL )
+        {
+            double fDirectValue = 0.0;
+            bool bRightCell = false;
+            table::CellAddress aRightAddr;
+            const uno::Any& rRightAny = maConstraints[nConstrPos].Right;
+            if ( rRightAny >>= aRightAddr )
+                bRightCell = true;                  // cell specified as right-hand side
+            else
+                rRightAny >>= fDirectValue;         // constant value
+
+            table::CellAddress aLeftAddr = maConstraints[nConstrPos].Left;
+
+            const std::vector<double>& rLeftCoeff = aCellsHash[aLeftAddr];
+            REAL* pValues = new REAL[nVariables+1];
+            pValues[0] = 0.0;                               // ignored?
+            for (nVar=0; nVar<nVariables; nVar++)
+                pValues[nVar+1] = rLeftCoeff[nVar+1];
+
+            // if left hand cell has a constant term, put into rhs value
+            double fRightValue = -rLeftCoeff[0];
+
+            if ( bRightCell )
+            {
+                const std::vector<double>& rRightCoeff = aCellsHash[aRightAddr];
+                // modify pValues with rhs coefficients
+                for (nVar=0; nVar<nVariables; nVar++)
+                    pValues[nVar+1] -= rRightCoeff[nVar+1];
+
+                fRightValue += rRightCoeff[0];      // constant term
+            }
+            else
+                fRightValue += fDirectValue;
+
+            int nConstrType = LE;
+            switch ( eOp )
+            {
+                case sheet::SolverConstraintOperator_LESS_EQUAL:    nConstrType = LE; break;
+                case sheet::SolverConstraintOperator_GREATER_EQUAL: nConstrType = GE; break;
+                case sheet::SolverConstraintOperator_EQUAL:         nConstrType = EQ; break;
+                default:
+                    OSL_FAIL( "unexpected enum type" );
+            }
+            add_constraint( lp, pValues, nConstrType, fRightValue );
+
+            delete[] pValues;
+        }
+    }
+
+    set_add_rowmode(lp, FALSE);
+
+    // apply settings to all variables
+
+    for (nVar=0; nVar<nVariables; nVar++)
+    {
+        if ( !mbNonNegative )
+            set_unbounded(lp, nVar+1);          // allow negative (default is non-negative)
+                                                //! collect bounds from constraints?
+        if ( mbInteger )
+            set_int(lp, nVar+1, TRUE);
+    }
+
+    // apply single-var integer constraints
+
+    for (sal_Int32 nConstrPos = 0; nConstrPos < maConstraints.getLength(); ++nConstrPos)
+    {
+        sheet::SolverConstraintOperator eOp = maConstraints[nConstrPos].Operator;
+        if ( eOp == sheet::SolverConstraintOperator_INTEGER ||
+             eOp == sheet::SolverConstraintOperator_BINARY )
+        {
+            table::CellAddress aLeftAddr = maConstraints[nConstrPos].Left;
+            // find variable index for cell
+            for (nVar=0; nVar<nVariables; nVar++)
+                if ( AddressEqual( aVariableCells[nVar], aLeftAddr ) )
+                {
+                    if ( eOp == sheet::SolverConstraintOperator_INTEGER )
+                        set_int(lp, nVar+1, TRUE);
+                    else
+                        set_binary(lp, nVar+1, TRUE);
+                }
+        }
+    }
+
+    if ( mbMaximize )
+        set_maxim(lp);
+    else
+        set_minim(lp);
+
+    if ( !mbLimitBBDepth )
+        set_bb_depthlimit( lp, 0 );
+
+    set_epslevel( lp, mnEpsilonLevel );
+    set_timeout( lp, mnTimeout );
+
+    // solve model
+
+    int nResult = ::solve( lp );
+
+    mbSuccess = ( nResult == OPTIMAL );
+    if ( mbSuccess )
+    {
+        // get solution
+
+        maSolution.realloc( nVariables );
+
+        REAL* pResultVar = NULL;
+        get_ptr_variables( lp, &pResultVar );
+        for (nVar=0; nVar<nVariables; nVar++)
+            maSolution[nVar] = pResultVar[nVar];
+
+        mfResultValue = get_objective( lp );
+    }
+    else if ( nResult == INFEASIBLE )
+        maStatus = SolverComponent::GetResourceString( RID_ERROR_INFEASIBLE );
+    else if ( nResult == UNBOUNDED )
+        maStatus = SolverComponent::GetResourceString( RID_ERROR_UNBOUNDED );
+    else if ( nResult == TIMEOUT || nResult == SUBOPTIMAL )
+        maStatus = SolverComponent::GetResourceString( RID_ERROR_TIMEOUT );
+    // SUBOPTIMAL is assumed to be caused by a timeout, and reported as an error
+
+    delete_lp( lp );
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
+com_sun_star_comp_Calc_LpsolveSolver_get_implementation(
+    css::uno::XComponentContext *,
+    css::uno::Sequence<css::uno::Any> const &)
+{
+    return cppu::acquire(new LpsolveSolver());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sccomp/source/solver/SolverComponent.cxx b/sccomp/source/solver/SolverComponent.cxx
new file mode 100644
index 0000000..bb20cfe
--- /dev/null
+++ b/sccomp/source/solver/SolverComponent.cxx
@@ -0,0 +1,270 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   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 .
+ */
+
+#include "SolverComponent.hxx"
+#include "solver.hrc"
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+#include <cppuhelper/supportsservice.hxx>
+#include <vector>
+
+#include <tools/resmgr.hxx>
+
+using namespace com::sun::star;
+
+
+#define STR_NONNEGATIVE   "NonNegative"
+#define STR_INTEGER       "Integer"
+#define STR_TIMEOUT       "Timeout"
+#define STR_EPSILONLEVEL  "EpsilonLevel"
+#define STR_LIMITBBDEPTH  "LimitBBDepth"
+
+
+//  Resources from tools are used for translated strings
+
+ResMgr* SolverComponent::pSolverResMgr = NULL;
+
+OUString SolverComponent::GetResourceString( sal_uInt32 nId )
+{
+    if (!pSolverResMgr)
+        pSolverResMgr = ResMgr::CreateResMgr("solver");
+
+    return ResId(nId, *pSolverResMgr).toString();
+}
+
+size_t ScSolverCellHash::operator()( const css::table::CellAddress& rAddress ) const
+{
+    return ( rAddress.Sheet << 24 ) | ( rAddress.Column << 16 ) | rAddress.Row;
+}
+
+bool ScSolverCellEqual::operator()( const css::table::CellAddress& rAddr1, const css::table::CellAddress& rAddr2 ) const
+{
+    return AddressEqual( rAddr1, rAddr2 );
+}
+
+namespace
+{
+    enum
+    {
+        PROP_NONNEGATIVE,
+        PROP_INTEGER,
+        PROP_TIMEOUT,
+        PROP_EPSILONLEVEL,
+        PROP_LIMITBBDEPTH
+    };
+}
+
+uno::Reference<table::XCell> SolverComponent::GetCell( const uno::Reference<sheet::XSpreadsheetDocument>& xDoc,
+                                          const table::CellAddress& rPos )
+{
+    uno::Reference<container::XIndexAccess> xSheets( xDoc->getSheets(), uno::UNO_QUERY );
+    uno::Reference<sheet::XSpreadsheet> xSheet( xSheets->getByIndex( rPos.Sheet ), uno::UNO_QUERY );
+    return xSheet->getCellByPosition( rPos.Column, rPos.Row );
+}
+
+void SolverComponent::SetValue( const uno::Reference<sheet::XSpreadsheetDocument>& xDoc,
+                   const table::CellAddress& rPos, double fValue )
+{
+    SolverComponent::GetCell( xDoc, rPos )->setValue( fValue );
+}
+
+double SolverComponent::GetValue( const uno::Reference<sheet::XSpreadsheetDocument>& xDoc,
+                     const table::CellAddress& rPos )
+{
+    return SolverComponent::GetCell( xDoc, rPos )->getValue();
+}
+
+SolverComponent::SolverComponent() :
+    OPropertyContainer( GetBroadcastHelper() ),
+    mbMaximize( sal_True ),
+    mbNonNegative( sal_False ),
+    mbInteger( sal_False ),
+    mnTimeout( 100 ),
+    mnEpsilonLevel( 0 ),
+    mbLimitBBDepth( sal_True ),
+    mbSuccess( sal_False ),
+    mfResultValue( 0.0 )
+{
+    // for XPropertySet implementation:
+    registerProperty( STR_NONNEGATIVE,  PROP_NONNEGATIVE,  0, &mbNonNegative,  getCppuType( &mbNonNegative )  );
+    registerProperty( STR_INTEGER,      PROP_INTEGER,      0, &mbInteger,      getCppuType( &mbInteger )      );
+    registerProperty( STR_TIMEOUT,      PROP_TIMEOUT,      0, &mnTimeout,      getCppuType( &mnTimeout )      );
+    registerProperty( STR_EPSILONLEVEL, PROP_EPSILONLEVEL, 0, &mnEpsilonLevel, getCppuType( &mnEpsilonLevel ) );
+    registerProperty( STR_LIMITBBDEPTH, PROP_LIMITBBDEPTH, 0, &mbLimitBBDepth, getCppuType( &mbLimitBBDepth ) );
+}
+
+SolverComponent::~SolverComponent()
+{
+}
+
+IMPLEMENT_FORWARD_XINTERFACE2( SolverComponent, SolverComponent_Base, OPropertyContainer )
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( SolverComponent, SolverComponent_Base, OPropertyContainer )
+
+cppu::IPropertyArrayHelper* SolverComponent::createArrayHelper() const
+{
+    uno::Sequence<beans::Property> aProps;
+    describeProperties( aProps );
+    return new cppu::OPropertyArrayHelper( aProps );
+}
+
+cppu::IPropertyArrayHelper& SAL_CALL SolverComponent::getInfoHelper()
+{
+    return *getArrayHelper();
+}
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL SolverComponent::getPropertySetInfo() throw(uno::RuntimeException, std::exception)
+{
+    return createPropertySetInfo( getInfoHelper() );
+}
+
+// XSolverDescription
+
+OUString SAL_CALL SolverComponent::getComponentDescription() throw (uno::RuntimeException, std::exception)
+{
+    return SolverComponent::GetResourceString( RID_SOLVER_COMPONENT );
+}
+
+OUString SAL_CALL SolverComponent::getStatusDescription() throw (uno::RuntimeException, std::exception)
+{
+    return maStatus;
+}
+
+OUString SAL_CALL SolverComponent::getPropertyDescription( const OUString& rPropertyName ) throw (uno::RuntimeException, std::exception)
+{
+    sal_uInt32 nResId = 0;
+    sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName );
+    switch (nHandle)
+    {
+        case PROP_NONNEGATIVE:
+            nResId = RID_PROPERTY_NONNEGATIVE;
+            break;
+        case PROP_INTEGER:
+            nResId = RID_PROPERTY_INTEGER;
+            break;
+        case PROP_TIMEOUT:
+            nResId = RID_PROPERTY_TIMEOUT;
+            break;
+        case PROP_EPSILONLEVEL:
+            nResId = RID_PROPERTY_EPSILONLEVEL;
+            break;
+        case PROP_LIMITBBDEPTH:
+            nResId = RID_PROPERTY_LIMITBBDEPTH;
+            break;
+        default:
+            {
+                // unknown - leave empty
+            }
+    }
+    OUString aRet;
+    if ( nResId )
+        aRet = SolverComponent::GetResourceString( nResId );
+    return aRet;
+}
+
+// XSolver: settings
+
+uno::Reference<sheet::XSpreadsheetDocument> SAL_CALL SolverComponent::getDocument() throw(uno::RuntimeException, std::exception)
+{
+    return mxDoc;
+}
+
+void SAL_CALL SolverComponent::setDocument( const uno::Reference<sheet::XSpreadsheetDocument>& _document )
+                                throw(uno::RuntimeException, std::exception)
+{
+    mxDoc = _document;
+}
+
+table::CellAddress SAL_CALL SolverComponent::getObjective() throw(uno::RuntimeException, std::exception)
+{
+    return maObjective;
+}
+
+void SAL_CALL SolverComponent::setObjective( const table::CellAddress& _objective ) throw(uno::RuntimeException, std::exception)
+{
+    maObjective = _objective;
+}
+
+uno::Sequence<table::CellAddress> SAL_CALL SolverComponent::getVariables() throw(uno::RuntimeException, std::exception)
+{
+    return maVariables;
+}
+
+void SAL_CALL SolverComponent::setVariables( const uno::Sequence<table::CellAddress>& _variables )
+                                throw(uno::RuntimeException, std::exception)
+{
+    maVariables = _variables;
+}
+
+uno::Sequence<sheet::SolverConstraint> SAL_CALL SolverComponent::getConstraints() throw(uno::RuntimeException, std::exception)
+{
+    return maConstraints;
+}
+
+void SAL_CALL SolverComponent::setConstraints( const uno::Sequence<sheet::SolverConstraint>& _constraints )
+                                throw(uno::RuntimeException, std::exception)
+{
+    maConstraints = _constraints;
+}
+
+sal_Bool SAL_CALL SolverComponent::getMaximize() throw(uno::RuntimeException, std::exception)
+{
+    return mbMaximize;
+}
+
+void SAL_CALL SolverComponent::setMaximize( sal_Bool _maximize ) throw(uno::RuntimeException, std::exception)
+{
+    mbMaximize = _maximize;
+}
+
+// XSolver: get results
+
+sal_Bool SAL_CALL SolverComponent::getSuccess() throw(uno::RuntimeException, std::exception)
+{
+    return mbSuccess;
+}
+
+double SAL_CALL SolverComponent::getResultValue() throw(uno::RuntimeException, std::exception)
+{
+    return mfResultValue;
+}
+
+uno::Sequence<double> SAL_CALL SolverComponent::getSolution() throw(uno::RuntimeException, std::exception)
+{
+    return maSolution;
+}
+
+// XServiceInfo
+
+sal_Bool SAL_CALL SolverComponent::supportsService( const OUString& rServiceName ) throw(uno::RuntimeException, std::exception)
+{
+    return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL SolverComponent::getSupportedServiceNames() throw(uno::RuntimeException, std::exception)
+{
+    uno::Sequence< OUString > aServiceNames( 1 );
+    aServiceNames[ 0 ] = "com.sun.star.sheet.Solver";
+    return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sccomp/source/solver/solver.hxx b/sccomp/source/solver/SolverComponent.hxx
similarity index 81%
rename from sccomp/source/solver/solver.hxx
rename to sccomp/source/solver/SolverComponent.hxx
index 223c7d1..2d1c2e7 100644
--- a/sccomp/source/solver/solver.hxx
+++ b/sccomp/source/solver/SolverComponent.hxx
@@ -22,13 +22,38 @@
 
 #include <com/sun/star/sheet/XSolver.hpp>
 #include <com/sun/star/sheet/XSolverDescription.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/XCell.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
-#include <com/sun/star/uno/XComponentContext.hpp>
 #include <cppuhelper/implbase3.hxx>
 #include <comphelper/broadcasthelper.hxx>
 #include <comphelper/propertycontainer.hxx>
 #include <comphelper/proparrhlp.hxx>
 
+#include <boost/unordered_map.hpp>
+
+class ResMgr;
+
+// hash map for the coefficients of a dependent cell (objective or constraint)
+// The size of each vector is the number of columns (variable cells) plus one, first entry is initial value.
+
+struct ScSolverCellHash
+{
+    size_t operator()( const css::table::CellAddress& rAddress ) const;
+};
+
+inline bool AddressEqual( const css::table::CellAddress& rAddr1, const css::table::CellAddress& rAddr2 )
+{
+    return rAddr1.Sheet == rAddr2.Sheet && rAddr1.Column == rAddr2.Column && rAddr1.Row == rAddr2.Row;
+}
+
+struct ScSolverCellEqual
+{
+    bool operator()( const css::table::CellAddress& rAddr1, const css::table::CellAddress& rAddr2 ) const;
+};
+
+typedef boost::unordered_map< css::table::CellAddress, std::vector<double>, ScSolverCellHash, ScSolverCellEqual > ScSolverCellHashMap;
+
 typedef cppu::WeakImplHelper3<
                 com::sun::star::sheet::XSolver,
                 com::sun::star::sheet::XSolverDescription,
@@ -40,6 +65,9 @@ class SolverComponent : public comphelper::OMutexAndBroadcastHelper,
                         public comphelper::OPropertyArrayUsageHelper< SolverComponent >,
                         public SolverComponent_Base
 {
+protected:
+    static ResMgr* pSolverResMgr;
+
     // settings
     com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheetDocument > mxDoc;
     com::sun::star::table::CellAddress                                            maObjective;
@@ -58,9 +86,19 @@ class SolverComponent : public comphelper::OMutexAndBroadcastHelper,
     com::sun::star::uno::Sequence< double >                                       maSolution;
     OUString                                                                 maStatus;
 
+    static OUString GetResourceString( sal_uInt32 nId );
+    static css::uno::Reference<css::table::XCell> GetCell(
+            const css::uno::Reference<css::sheet::XSpreadsheetDocument>& xDoc,
+            const css::table::CellAddress& rPos );
+    static void SetValue(
+            const css::uno::Reference<css::sheet::XSpreadsheetDocument>& xDoc,
+            const css::table::CellAddress& rPos, double fValue );
+    static double GetValue(
+            const css::uno::Reference<css::sheet::XSpreadsheetDocument>& xDoc,
+            const css::table::CellAddress& rPos );
+
 public:
-                            SolverComponent( const com::sun::star::uno::Reference<
-                                    com::sun::star::uno::XComponentContext >& rxMSF );
+                            SolverComponent();
     virtual                 ~SolverComponent();
 
     DECLARE_XINTERFACE()
@@ -98,7 +136,7 @@ public:
     virtual ::com::sun::star::uno::Sequence< double > SAL_CALL getSolution()
                                 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
 
-    virtual void SAL_CALL solve() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+    virtual void SAL_CALL solve() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE = 0;
 
                             // XSolverDescription
     virtual OUString SAL_CALL getComponentDescription() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
@@ -108,7 +146,7 @@ public:
 
                             // XServiceInfo
     virtual OUString SAL_CALL getImplementationName()
-                                throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+                                throw(::com::sun::star::uno::RuntimeException, std::exception) = 0;
     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName )
                                 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames()
diff --git a/sccomp/source/solver/coinmpsolver.component b/sccomp/source/solver/coinmpsolver.component
index 0feb3d0..3ddeeea 100644
--- a/sccomp/source/solver/coinmpsolver.component
+++ b/sccomp/source/solver/coinmpsolver.component
@@ -7,9 +7,10 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  -->
 
-<component loader="com.sun.star.loader.SharedLibrary" prefix="coinmp"
+<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
     xmlns="http://openoffice.org/2010/uno-components">
-  <implementation name="com.sun.star.comp.Calc.CoinMPSolver">
+  <implementation name="com.sun.star.comp.Calc.CoinMPSolver"
+      constructor="com_sun_star_comp_Calc_CoinMPSolver_get_implementation">
     <service name="com.sun.star.sheet.Solver"/>
   </implementation>
 </component>
diff --git a/sccomp/source/solver/solver.component b/sccomp/source/solver/lpsolvesolver.component
similarity index 84%
rename from sccomp/source/solver/solver.component
rename to sccomp/source/solver/lpsolvesolver.component
index fd0690b..76e2f3b 100644
--- a/sccomp/source/solver/solver.component
+++ b/sccomp/source/solver/lpsolvesolver.component
@@ -18,8 +18,9 @@
  -->
 
 <component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
-    prefix="solver" xmlns="http://openoffice.org/2010/uno-components">
-  <implementation name="com.sun.star.comp.Calc.Solver">
+    xmlns="http://openoffice.org/2010/uno-components">
+  <implementation name="com.sun.star.comp.Calc.LpsolveSolver"
+      constructor="com_sun_star_comp_Calc_LpsolveSolver_get_implementation">
     <service name="com.sun.star.sheet.Solver"/>
   </implementation>
 </component>
diff --git a/sccomp/source/solver/solver-lpsolve.cxx b/sccomp/source/solver/solver-lpsolve.cxx
deleted file mode 100644
index 0c8e811..0000000
--- a/sccomp/source/solver/solver-lpsolve.cxx
+++ /dev/null
@@ -1,631 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org.  If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   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 .
- *
- ************************************************************************/
-
-#include "sal/config.h"
-#include <config_lgpl.h>
-
-#undef LANGUAGE_NONE
-#if defined SAL_W32
-#define WINAPI __stdcall
-#endif
-#define LoadInverseLib FALSE
-#define LoadLanguageLib FALSE
-#ifdef SYSTEM_LPSOLVE
-#include <lpsolve/lp_lib.h>
-#else
-#include <lp_lib.h>
-#endif
-#undef LANGUAGE_NONE
-
-#include "solver.hxx"
-#include "solver.hrc"
-
-#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/container/XIndexAccess.hpp>
-#include <com/sun/star/frame/XModel.hpp>
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
-#include <com/sun/star/sheet/XSpreadsheet.hpp>
-#include <com/sun/star/table/CellAddress.hpp>
-#include <com/sun/star/table/CellRangeAddress.hpp>
-#include <com/sun/star/text/XTextRange.hpp>
-
-#include <rtl/math.hxx>
-#include <rtl/ustrbuf.hxx>
-#include <cppuhelper/factory.hxx>
-#include <cppuhelper/supportsservice.hxx>
-#include <vector>
-#include <boost/unordered_map.hpp>
-
-#include <tools/resmgr.hxx>
-
-using namespace com::sun::star;
-
-
-#define STR_NONNEGATIVE   "NonNegative"
-#define STR_INTEGER       "Integer"
-#define STR_TIMEOUT       "Timeout"
-#define STR_EPSILONLEVEL  "EpsilonLevel"
-#define STR_LIMITBBDEPTH  "LimitBBDepth"
-
-
-//  Resources from tools are used for translated strings
-
-static ResMgr* pSolverResMgr = NULL;
-
-static OUString lcl_GetResourceString( sal_uInt32 nId )
-{
-    if (!pSolverResMgr)
-        pSolverResMgr = ResMgr::CreateResMgr("solver");
-
-    return ResId(nId, *pSolverResMgr).toString();
-}
-
-
-
-namespace
-{
-    enum
-    {
-        PROP_NONNEGATIVE,
-        PROP_INTEGER,
-        PROP_TIMEOUT,
-        PROP_EPSILONLEVEL,
-        PROP_LIMITBBDEPTH
-    };
-}
-
-
-
-// hash map for the coefficients of a dependent cell (objective or constraint)
-// The size of each vector is the number of columns (variable cells) plus one, first entry is initial value.
-
-struct ScSolverCellHash
-{
-    size_t operator()( const table::CellAddress& rAddress ) const
-    {
-        return ( rAddress.Sheet << 24 ) | ( rAddress.Column << 16 ) | rAddress.Row;
-    }
-};
-
-inline bool AddressEqual( const table::CellAddress& rAddr1, const table::CellAddress& rAddr2 )
-{
-    return rAddr1.Sheet == rAddr2.Sheet && rAddr1.Column == rAddr2.Column && rAddr1.Row == rAddr2.Row;
-}
-
-struct ScSolverCellEqual
-{
-    bool operator()( const table::CellAddress& rAddr1, const table::CellAddress& rAddr2 ) const
-    {
-        return AddressEqual( rAddr1, rAddr2 );
-    }
-};
-
-typedef boost::unordered_map< table::CellAddress, std::vector<double>, ScSolverCellHash, ScSolverCellEqual > ScSolverCellHashMap;
-
-
-
-static uno::Reference<table::XCell> lcl_GetCell( const uno::Reference<sheet::XSpreadsheetDocument>& xDoc,
-                                          const table::CellAddress& rPos )
-{
-    uno::Reference<container::XIndexAccess> xSheets( xDoc->getSheets(), uno::UNO_QUERY );
-    uno::Reference<sheet::XSpreadsheet> xSheet( xSheets->getByIndex( rPos.Sheet ), uno::UNO_QUERY );
-    return xSheet->getCellByPosition( rPos.Column, rPos.Row );
-}
-
-static void lcl_SetValue( const uno::Reference<sheet::XSpreadsheetDocument>& xDoc,
-                   const table::CellAddress& rPos, double fValue )
-{
-    lcl_GetCell( xDoc, rPos )->setValue( fValue );
-}
-
-static double lcl_GetValue( const uno::Reference<sheet::XSpreadsheetDocument>& xDoc,
-                     const table::CellAddress& rPos )
-{
-    return lcl_GetCell( xDoc, rPos )->getValue();
-}
-
-
-
-SolverComponent::SolverComponent( const uno::Reference<uno::XComponentContext>& /* rSMgr */ ) :
-    OPropertyContainer( GetBroadcastHelper() ),
-    mbMaximize( sal_True ),
-    mbNonNegative( sal_False ),
-    mbInteger( sal_False ),
-    mnTimeout( 100 ),
-    mnEpsilonLevel( 0 ),
-    mbLimitBBDepth( sal_True ),
-    mbSuccess( sal_False ),
-    mfResultValue( 0.0 )
-{
-    // for XPropertySet implementation:
-    registerProperty( STR_NONNEGATIVE,  PROP_NONNEGATIVE,  0, &mbNonNegative,  getCppuType( &mbNonNegative )  );
-    registerProperty( STR_INTEGER,      PROP_INTEGER,      0, &mbInteger,      getCppuType( &mbInteger )      );
-    registerProperty( STR_TIMEOUT,      PROP_TIMEOUT,      0, &mnTimeout,      getCppuType( &mnTimeout )      );
-    registerProperty( STR_EPSILONLEVEL, PROP_EPSILONLEVEL, 0, &mnEpsilonLevel, getCppuType( &mnEpsilonLevel ) );
-    registerProperty( STR_LIMITBBDEPTH, PROP_LIMITBBDEPTH, 0, &mbLimitBBDepth, getCppuType( &mbLimitBBDepth ) );
-}
-
-SolverComponent::~SolverComponent()
-{
-}
-
-IMPLEMENT_FORWARD_XINTERFACE2( SolverComponent, SolverComponent_Base, OPropertyContainer )
-IMPLEMENT_FORWARD_XTYPEPROVIDER2( SolverComponent, SolverComponent_Base, OPropertyContainer )
-
-cppu::IPropertyArrayHelper* SolverComponent::createArrayHelper() const
-{
-    uno::Sequence<beans::Property> aProps;
-    describeProperties( aProps );
-    return new cppu::OPropertyArrayHelper( aProps );
-}
-
-cppu::IPropertyArrayHelper& SAL_CALL SolverComponent::getInfoHelper()
-{
-    return *getArrayHelper();
-}
-
-uno::Reference<beans::XPropertySetInfo> SAL_CALL SolverComponent::getPropertySetInfo() throw(uno::RuntimeException, std::exception)
-{
-    return createPropertySetInfo( getInfoHelper() );
-}
-
-// XSolverDescription
-
-OUString SAL_CALL SolverComponent::getComponentDescription() throw (uno::RuntimeException, std::exception)
-{
-    return lcl_GetResourceString( RID_SOLVER_COMPONENT );
-}
-
-OUString SAL_CALL SolverComponent::getStatusDescription() throw (uno::RuntimeException, std::exception)
-{
-    return maStatus;
-}
-
-OUString SAL_CALL SolverComponent::getPropertyDescription( const OUString& rPropertyName ) throw (uno::RuntimeException, std::exception)
-{
-    sal_uInt32 nResId = 0;
-    sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName );
-    switch (nHandle)
-    {
-        case PROP_NONNEGATIVE:
-            nResId = RID_PROPERTY_NONNEGATIVE;
-            break;
-        case PROP_INTEGER:
-            nResId = RID_PROPERTY_INTEGER;
-            break;
-        case PROP_TIMEOUT:
-            nResId = RID_PROPERTY_TIMEOUT;
-            break;
-        case PROP_EPSILONLEVEL:
-            nResId = RID_PROPERTY_EPSILONLEVEL;
-            break;
-        case PROP_LIMITBBDEPTH:
-            nResId = RID_PROPERTY_LIMITBBDEPTH;
-            break;
-        default:
-            {
-                // unknown - leave empty
-            }
-    }
-    OUString aRet;
-    if ( nResId )
-        aRet = lcl_GetResourceString( nResId );
-    return aRet;
-}
-
-// XSolver: settings
-
-uno::Reference<sheet::XSpreadsheetDocument> SAL_CALL SolverComponent::getDocument() throw(uno::RuntimeException, std::exception)
-{
-    return mxDoc;
-}
-
-void SAL_CALL SolverComponent::setDocument( const uno::Reference<sheet::XSpreadsheetDocument>& _document )
-                                throw(uno::RuntimeException, std::exception)
-{
-    mxDoc = _document;
-}
-
-table::CellAddress SAL_CALL SolverComponent::getObjective() throw(uno::RuntimeException, std::exception)
-{
-    return maObjective;
-}
-
-void SAL_CALL SolverComponent::setObjective( const table::CellAddress& _objective ) throw(uno::RuntimeException, std::exception)
-{
-    maObjective = _objective;
-}
-
-uno::Sequence<table::CellAddress> SAL_CALL SolverComponent::getVariables() throw(uno::RuntimeException, std::exception)
-{
-    return maVariables;
-}
-
-void SAL_CALL SolverComponent::setVariables( const uno::Sequence<table::CellAddress>& _variables )
-                                throw(uno::RuntimeException, std::exception)
-{
-    maVariables = _variables;
-}
-
-uno::Sequence<sheet::SolverConstraint> SAL_CALL SolverComponent::getConstraints() throw(uno::RuntimeException, std::exception)
-{
-    return maConstraints;
-}
-
-void SAL_CALL SolverComponent::setConstraints( const uno::Sequence<sheet::SolverConstraint>& _constraints )
-                                throw(uno::RuntimeException, std::exception)
-{
-    maConstraints = _constraints;
-}
-
-sal_Bool SAL_CALL SolverComponent::getMaximize() throw(uno::RuntimeException, std::exception)
-{
-    return mbMaximize;
-}
-
-void SAL_CALL SolverComponent::setMaximize( sal_Bool _maximize ) throw(uno::RuntimeException, std::exception)
-{
-    mbMaximize = _maximize;
-}
-
-// XSolver: get results
-
-sal_Bool SAL_CALL SolverComponent::getSuccess() throw(uno::RuntimeException, std::exception)
-{
-    return mbSuccess;
-}
-
-double SAL_CALL SolverComponent::getResultValue() throw(uno::RuntimeException, std::exception)
-{
-    return mfResultValue;
-}
-
-uno::Sequence<double> SAL_CALL SolverComponent::getSolution() throw(uno::RuntimeException, std::exception)
-{
-    return maSolution;
-}
-
-void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException, std::exception)
-{
-    uno::Reference<frame::XModel> xModel( mxDoc, uno::UNO_QUERY );
-    if ( !xModel.is() )
-        throw uno::RuntimeException();
-
-    maStatus = "";
-    mbSuccess = false;
-
-    if ( mnEpsilonLevel < EPS_TIGHT || mnEpsilonLevel > EPS_BAGGY )
-    {
-        maStatus = lcl_GetResourceString( RID_ERROR_EPSILONLEVEL );
-        return;
-    }
-
-    xModel->lockControllers();
-
-    // collect variables in vector (?)
-
-    std::vector<table::CellAddress> aVariableCells;
-    for (sal_Int32 nPos=0; nPos<maVariables.getLength(); nPos++)
-        aVariableCells.push_back( maVariables[nPos] );
-    size_t nVariables = aVariableCells.size();
-    size_t nVar = 0;
-
-    // collect all dependent cells
-
-    ScSolverCellHashMap aCellsHash;
-    aCellsHash[maObjective].reserve( nVariables + 1 );                  // objective function
-
-    for (sal_Int32 nConstrPos = 0; nConstrPos < maConstraints.getLength(); ++nConstrPos)
-    {
-        table::CellAddress aCellAddr = maConstraints[nConstrPos].Left;
-        aCellsHash[aCellAddr].reserve( nVariables + 1 );                // constraints: left hand side
-
-        if ( maConstraints[nConstrPos].Right >>= aCellAddr )
-            aCellsHash[aCellAddr].reserve( nVariables + 1 );            // constraints: right hand side
-    }
-
-    // set all variables to zero
-    //! store old values?
-    //! use old values as initial values?
-    std::vector<table::CellAddress>::const_iterator aVarIter;
-    for ( aVarIter = aVariableCells.begin(); aVarIter != aVariableCells.end(); ++aVarIter )
-    {
-        lcl_SetValue( mxDoc, *aVarIter, 0.0 );
-    }
-
-    // read initial values from all dependent cells
-    ScSolverCellHashMap::iterator aCellsIter;
-    for ( aCellsIter = aCellsHash.begin(); aCellsIter != aCellsHash.end(); ++aCellsIter )
-    {
-        double fValue = lcl_GetValue( mxDoc, aCellsIter->first );
-        aCellsIter->second.push_back( fValue );                         // store as first element, as-is
-    }
-
-    // loop through variables
-    for ( aVarIter = aVariableCells.begin(); aVarIter != aVariableCells.end(); ++aVarIter )
-    {
-        lcl_SetValue( mxDoc, *aVarIter, 1.0 );      // set to 1 to examine influence
-
-        // read value change from all dependent cells
-        for ( aCellsIter = aCellsHash.begin(); aCellsIter != aCellsHash.end(); ++aCellsIter )
-        {
-            double fChanged = lcl_GetValue( mxDoc, aCellsIter->first );
-            double fInitial = aCellsIter->second.front();
-            aCellsIter->second.push_back( fChanged - fInitial );
-        }
-
-        lcl_SetValue( mxDoc, *aVarIter, 2.0 );      // minimal test for linearity
-
-        for ( aCellsIter = aCellsHash.begin(); aCellsIter != aCellsHash.end(); ++aCellsIter )
-        {
-            double fInitial = aCellsIter->second.front();
-            double fCoeff   = aCellsIter->second.back();       // last appended: coefficient for this variable
-            double fTwo     = lcl_GetValue( mxDoc, aCellsIter->first );
-
-            bool bLinear = rtl::math::approxEqual( fTwo, fInitial + 2.0 * fCoeff ) ||
-                           rtl::math::approxEqual( fInitial, fTwo - 2.0 * fCoeff );
-            // second comparison is needed in case fTwo is zero
-            if ( !bLinear )
-                maStatus = lcl_GetResourceString( RID_ERROR_NONLINEAR );
-        }
-
-        lcl_SetValue( mxDoc, *aVarIter, 0.0 );      // set back to zero for examining next variable
-    }
-
-    xModel->unlockControllers();
-
-    if ( !maStatus.isEmpty() )
-        return;
-
-
-    // build lp_solve model
-
-
-    lprec* lp = make_lp( 0, nVariables );
-    if ( !lp )
-        return;
-
-    set_outputfile( lp, const_cast<char*>( "" ) );  // no output
-
-    // set objective function
-
-    const std::vector<double>& rObjCoeff = aCellsHash[maObjective];
-    REAL* pObjVal = new REAL[nVariables+1];
-    pObjVal[0] = 0.0;                           // ignored
-    for (nVar=0; nVar<nVariables; nVar++)
-        pObjVal[nVar+1] = rObjCoeff[nVar+1];
-    set_obj_fn( lp, pObjVal );
-    delete[] pObjVal;
-    set_rh( lp, 0, rObjCoeff[0] );              // constant term of objective
-
-    // add rows
-
-    set_add_rowmode(lp, TRUE);
-
-    for (sal_Int32 nConstrPos = 0; nConstrPos < maConstraints.getLength(); ++nConstrPos)
-    {
-        // integer constraints are set later
-        sheet::SolverConstraintOperator eOp = maConstraints[nConstrPos].Operator;
-        if ( eOp == sheet::SolverConstraintOperator_LESS_EQUAL ||
-             eOp == sheet::SolverConstraintOperator_GREATER_EQUAL ||
-             eOp == sheet::SolverConstraintOperator_EQUAL )
-        {
-            double fDirectValue = 0.0;
-            bool bRightCell = false;
-            table::CellAddress aRightAddr;
-            const uno::Any& rRightAny = maConstraints[nConstrPos].Right;
-            if ( rRightAny >>= aRightAddr )
-                bRightCell = true;                  // cell specified as right-hand side
-            else
-                rRightAny >>= fDirectValue;         // constant value
-
-            table::CellAddress aLeftAddr = maConstraints[nConstrPos].Left;
-
-            const std::vector<double>& rLeftCoeff = aCellsHash[aLeftAddr];
-            REAL* pValues = new REAL[nVariables+1];
-            pValues[0] = 0.0;                               // ignored?
-            for (nVar=0; nVar<nVariables; nVar++)
-                pValues[nVar+1] = rLeftCoeff[nVar+1];
-
-            // if left hand cell has a constant term, put into rhs value
-            double fRightValue = -rLeftCoeff[0];
-
-            if ( bRightCell )
-            {
-                const std::vector<double>& rRightCoeff = aCellsHash[aRightAddr];
-                // modify pValues with rhs coefficients
-                for (nVar=0; nVar<nVariables; nVar++)
-                    pValues[nVar+1] -= rRightCoeff[nVar+1];
-
-                fRightValue += rRightCoeff[0];      // constant term
-            }
-            else
-                fRightValue += fDirectValue;
-
-            int nConstrType = LE;
-            switch ( eOp )
-            {
-                case sheet::SolverConstraintOperator_LESS_EQUAL:    nConstrType = LE; break;
-                case sheet::SolverConstraintOperator_GREATER_EQUAL: nConstrType = GE; break;
-                case sheet::SolverConstraintOperator_EQUAL:         nConstrType = EQ; break;
-                default:
-                    OSL_FAIL( "unexpected enum type" );
-            }
-            add_constraint( lp, pValues, nConstrType, fRightValue );
-
-            delete[] pValues;
-        }
-    }
-
-    set_add_rowmode(lp, FALSE);
-
-    // apply settings to all variables
-
-    for (nVar=0; nVar<nVariables; nVar++)
-    {
-        if ( !mbNonNegative )
-            set_unbounded(lp, nVar+1);          // allow negative (default is non-negative)
-                                                //! collect bounds from constraints?
-        if ( mbInteger )
-            set_int(lp, nVar+1, TRUE);
-    }
-
-    // apply single-var integer constraints
-
-    for (sal_Int32 nConstrPos = 0; nConstrPos < maConstraints.getLength(); ++nConstrPos)
-    {
-        sheet::SolverConstraintOperator eOp = maConstraints[nConstrPos].Operator;
-        if ( eOp == sheet::SolverConstraintOperator_INTEGER ||
-             eOp == sheet::SolverConstraintOperator_BINARY )
-        {
-            table::CellAddress aLeftAddr = maConstraints[nConstrPos].Left;
-            // find variable index for cell
-            for (nVar=0; nVar<nVariables; nVar++)
-                if ( AddressEqual( aVariableCells[nVar], aLeftAddr ) )
-                {
-                    if ( eOp == sheet::SolverConstraintOperator_INTEGER )
-                        set_int(lp, nVar+1, TRUE);
-                    else
-                        set_binary(lp, nVar+1, TRUE);
-                }
-        }
-    }
-
-    if ( mbMaximize )
-        set_maxim(lp);
-    else
-        set_minim(lp);
-
-    if ( !mbLimitBBDepth )
-        set_bb_depthlimit( lp, 0 );
-
-    set_epslevel( lp, mnEpsilonLevel );
-    set_timeout( lp, mnTimeout );
-
-    // solve model
-
-    int nResult = ::solve( lp );
-
-    mbSuccess = ( nResult == OPTIMAL );
-    if ( mbSuccess )
-    {
-        // get solution
-
-        maSolution.realloc( nVariables );
-
-        REAL* pResultVar = NULL;
-        get_ptr_variables( lp, &pResultVar );
-        for (nVar=0; nVar<nVariables; nVar++)
-            maSolution[nVar] = pResultVar[nVar];
-
-        mfResultValue = get_objective( lp );
-    }
-    else if ( nResult == INFEASIBLE )
-        maStatus = lcl_GetResourceString( RID_ERROR_INFEASIBLE );
-    else if ( nResult == UNBOUNDED )
-        maStatus = lcl_GetResourceString( RID_ERROR_UNBOUNDED );
-    else if ( nResult == TIMEOUT || nResult == SUBOPTIMAL )
-        maStatus = lcl_GetResourceString( RID_ERROR_TIMEOUT );
-    // SUBOPTIMAL is assumed to be caused by a timeout, and reported as an error
-
-    delete_lp( lp );
-}
-
-// XServiceInfo
-
-uno::Sequence< OUString > SolverComponent_getSupportedServiceNames()
-{
-    uno::Sequence< OUString > aServiceNames( 1 );
-    aServiceNames[ 0 ] = "com.sun.star.sheet.Solver";
-    return aServiceNames;
-}
-
-OUString SolverComponent_getImplementationName()
-{
-    return OUString("com.sun.star.comp.Calc.Solver");
-}
-
-OUString SAL_CALL SolverComponent::getImplementationName() throw(uno::RuntimeException, std::exception)
-{
-    return SolverComponent_getImplementationName();
-}
-
-sal_Bool SAL_CALL SolverComponent::supportsService( const OUString& rServiceName ) throw(uno::RuntimeException, std::exception)
-{
-    return cppu::supportsService(this, rServiceName);
-}
-
-uno::Sequence<OUString> SAL_CALL SolverComponent::getSupportedServiceNames() throw(uno::RuntimeException, std::exception)
-{
-    return SolverComponent_getSupportedServiceNames();
-}
-
-uno::Reference<uno::XInterface> SolverComponent_createInstance( const uno::Reference<uno::XComponentContext>& rSMgr )
-    throw(uno::Exception)
-{
-    return (cppu::OWeakObject*) new SolverComponent( rSMgr );
-}
-
-extern "C"
-{
-    SAL_DLLPUBLIC_EXPORT void* SAL_CALL solver_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
-    {
-        OUString    aImplName( OUString::createFromAscii( pImplName ) );
-        void*       pRet = 0;
-
-        if( pServiceManager )
-        {
-            uno::Reference< lang::XSingleComponentFactory > xFactory;
-            if( aImplName.equals( SolverComponent_getImplementationName() ) )
-                xFactory = cppu::createSingleComponentFactory(
-                        SolverComponent_createInstance,
-                        OUString::createFromAscii( pImplName ),
-                        SolverComponent_getSupportedServiceNames() );
-
-            if( xFactory.is() )
-            {
-                xFactory->acquire();
-                pRet = xFactory.get();
-            }
-        }
-        return pRet;
-    }
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit dae3e18376a0fa770fa839959aeedc7c2044d4b6
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Thu Apr 3 10:40:48 2014 +0200

    sccomp_lpsolver does not need to link against sc
    
    Change-Id: I47a758fbcfcefc2bdd1cdbb89ef219a7ebb2af47

diff --git a/sccomp/CppunitTest_sccomp_lpsolver.mk b/sccomp/CppunitTest_sccomp_lpsolver.mk
index 4cb71fd..1c0c72a 100644
--- a/sccomp/CppunitTest_sccomp_lpsolver.mk
+++ b/sccomp/CppunitTest_sccomp_lpsolver.mk
@@ -25,7 +25,6 @@ $(eval $(call gb_CppunitTest_add_defs,sccomp_lpsolver,\
 $(eval $(call gb_CppunitTest_use_libraries,sccomp_lpsolver,\
 	cppu \
 	sal \
-	sc \
 	test \
 	$(gb_UWINAPI) \
 ))
commit c79c969d64ccae69518dba52e0abfc133d8adad9
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Thu Apr 3 10:38:32 2014 +0200

    gbuild: fix check for registered libraries
    
    Change-Id: I0e8524a0933114196a80317b9a427d8cd3f3e459

diff --git a/solenv/gbuild/Library.mk b/solenv/gbuild/Library.mk
index 3fd6e19..f308985 100644
--- a/solenv/gbuild/Library.mk
+++ b/solenv/gbuild/Library.mk
@@ -49,7 +49,7 @@ gb_Library_get_ilib_target = $(if $(filter $(1),$(gb_Library_RTVERLIBS) $(gb_Lib
 
 define gb_Library_Library
 $(call gb_Postprocess_register_target,AllLibraries,Library,$(1))
-ifeq (,$$(findstring $(1),$$(gb_Library_KNOWNLIBS)))
+ifeq (,$$(filter $(1),$$(gb_Library_KNOWNLIBS)))
 $$(eval $$(call gb_Output_info,Currently known libraries are: $(sort $(gb_Library_KNOWNLIBS)),ALL))
 $$(eval $$(call gb_Output_error,Library $(1) must be registered in Repository.mk or RepositoryExternal.mk))
 endif
commit 604bd3be0fb6d4ce0138a7a1b3b48d518cf6ba46
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Thu Apr 3 08:50:26 2014 +0200

    gbuild: Allow to use more components in one library.
    
    It probably does not make much sense in general but will be used to
    optionally disable some implementations in a library.
    
    Change-Id: Ib491b8b642907b5bb20d458cbf766c9c9a5a5111

diff --git a/solenv/gbuild/Library.mk b/solenv/gbuild/Library.mk
index 9c8f914..3fd6e19 100644
--- a/solenv/gbuild/Library.mk
+++ b/solenv/gbuild/Library.mk
@@ -125,9 +125,6 @@ endef
 # gb_Library_get_exports_target for that purpose, since it is already
 # the "final" target of the Library...
 define gb_Library_set_componentfile
-$(call gb_Library_get_target,$(gb_Library__get_name)) : \
-	COMPONENT := $$(if $$(and $$(COMPONENT),$(filter-out $(gb_MERGEDLIBS) $(gb_URELIBS),$(1))),\
-	  $$(call gb_Output_error,$(1) already has a component file $$(COMPONENT)))$(2)
 $(call gb_ComponentTarget_ComponentTarget,$(2),\
 	$(call gb_Library__get_componentprefix,$(gb_Library__get_name)),\
 	$(call gb_Library_get_runtime_filename,$(gb_Library__get_name)))


More information about the Libreoffice-commits mailing list