Index: src/demo/Makefile.am
===================================================================
--- src/demo/Makefile.am	(revision 1362)
+++ src/demo/Makefile.am	(revision 1381)
@@ -1,4 +1,15 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src
 LDADD = $(top_builddir)/src/lemon/libemon.la
+
+if HAVE_GLPK
+LP_CFLAGS = $(GLPK_CFLAGS) -DHAVE_GLPK
+LP_LIBS = $(GLPK_LIBS)
+else !HAVE_GLPK
+if HAVE_CPLEX
+LP_CFLAGS = $(CPLEX_CFLAGS) -DHAVE_CPLEX
+LP_LIBS = $(CPLEX_LIBS)
+endif HAVE_CPLEX
+endif !HAVE_GLPK
+
 
 EXTRA_DIST = sub_graph_wrapper_demo.dim
@@ -13,5 +24,10 @@
 if HAVE_GLPK
 noinst_PROGRAMS += lp_demo lp_maxflow_demo
-endif
+else !HAVE_GLPK
+if HAVE_CPLEX
+noinst_PROGRAMS += lp_demo lp_maxflow_demo
+endif HAVE_CPLEX
+endif !HAVE_GLPK
+
 
 dim_to_dot_SOURCES = dim_to_dot.cc
@@ -28,8 +44,8 @@
 
 lp_demo_SOURCES = lp_demo.cc
-lp_demo_CXXFLAGS = $(GLPK_CFLAGS)
-lp_demo_LDFLAGS = $(GLPK_LIBS)
+lp_demo_CXXFLAGS = $(LP_CFLAGS)
+lp_demo_LDFLAGS = $(LP_LIBS)
 
 lp_maxflow_demo_SOURCES = lp_maxflow_demo.cc
-lp_maxflow_demo_CXXFLAGS = $(GLPK_CFLAGS)
-lp_maxflow_demo_LDFLAGS = $(GLPK_LIBS)
+lp_maxflow_demo_CXXFLAGS = $(LP_CFLAGS)
+lp_maxflow_demo_LDFLAGS = $(LP_LIBS)
Index: src/demo/lp_demo.cc
===================================================================
--- src/demo/lp_demo.cc	(revision 1362)
+++ src/demo/lp_demo.cc	(revision 1381)
@@ -1,5 +1,18 @@
 #include <iostream>
+
+
+#ifdef HAVE_GLPK
 #include <lemon/lp_glpk.h>
+#elif HAVE_CPLEX
+#include <lemon/lp_cplex.h>
+#endif
+
 using namespace lemon;
+
+#ifdef HAVE_GLPK
+typedef LpGlpk LpDefault;
+#elif HAVE_CPLEX
+typedef LpCplex LpDefault;
+#endif
 
 int main()
@@ -7,7 +20,7 @@
  //The following example is taken from the documentation of the GLPK library.
  //See it in the GLPK reference manual and among the GLPK sample files (sample.c)
-  LpGlpk lp;
-  typedef LpGlpk::Row Row;
-  typedef LpGlpk::Col Col;
+  LpDefault lp;
+  typedef LpDefault::Row Row;
+  typedef LpDefault::Col Col;
 
   lp.max();
Index: src/demo/lp_maxflow_demo.cc
===================================================================
--- src/demo/lp_maxflow_demo.cc	(revision 1361)
+++ src/demo/lp_maxflow_demo.cc	(revision 1381)
@@ -1,12 +1,25 @@
-#include<lemon/lp_glpk.h>
 #include<lemon/graph_reader.h>
 #include<lemon/list_graph.h>
 
+
+#ifdef HAVE_GLPK
+#include <lemon/lp_glpk.h>
+#elif HAVE_CPLEX
+#include <lemon/lp_cplex.h>
+#endif
+
 using namespace lemon;
+
+#ifdef HAVE_GLPK
+typedef LpGlpk LpDefault;
+#elif HAVE_CPLEX
+typedef LpCplex LpDefault;
+#endif
+
 
 template<class G,class C>
 double maxFlow(const G &g,const C &cap,typename G::Node s,typename G::Node t)
 {
-  LpGlpk lp;
+  LpDefault lp;
   
   typedef G Graph;
@@ -18,5 +31,5 @@
   typedef typename G::InEdgeIt InEdgeIt;
   
-  typename G::template EdgeMap<LpGlpk::Col> x(g);
+  typename G::template EdgeMap<LpDefault::Col> x(g);
   lp.addColSet(x);
   
@@ -27,5 +40,5 @@
 
   for(NodeIt n(g);n!=INVALID;++n) if(n!=s&&n!=t) {
-    LpGlpk::Expr ex;
+    LpDefault::Expr ex;
     for(InEdgeIt  e(g,n);e!=INVALID;++e) ex+=x[e];
     for(OutEdgeIt e(g,n);e!=INVALID;++e) ex-=x[e];
@@ -33,5 +46,5 @@
   }
   {
-    LpGlpk::Expr ex;
+    LpDefault::Expr ex;
     for(InEdgeIt  e(g,t);e!=INVALID;++e) ex+=x[e];
     for(OutEdgeIt e(g,t);e!=INVALID;++e) ex-=x[e];
@@ -40,7 +53,8 @@
   lp.max();
 
+#ifdef HAVE_GLPK
   lp.presolver(true);
-  
   lp.messageLevel(3);
+#endif
 
   lp.solve();
Index: src/lemon/Makefile.am
===================================================================
--- src/lemon/Makefile.am	(revision 1378)
+++ src/lemon/Makefile.am	(revision 1381)
@@ -14,4 +14,10 @@
 libemon_la_CXXFLAGS = $(GLPK_CFLAGS)
 libemon_la_LDFLAGS = $(GLPK_LIBS)
+endif
+
+if HAVE_CPLEX
+libemon_la_SOURCES += lp_cplex.cc
+libemon_la_CXXFLAGS = $(CPLEX_CFLAGS)
+libemon_la_LDFLAGS = $(CPLEX_LIBS)
 endif
 
@@ -33,4 +39,5 @@
 	list_graph.h \
 	lp_base.h \
+	lp_cplex.h \
 	lp_glpk.h \
 	lp_skeleton.h \
Index: src/lemon/lp_base.h
===================================================================
--- src/lemon/lp_base.h	(revision 1379)
+++ src/lemon/lp_base.h	(revision 1381)
@@ -465,5 +465,5 @@
     ///Creates a new LP problem
     LpSolverBase &newLp() {return _newLp();}
-    ///Make a copy of the LP problem
+    ///Makes a copy of the LP problem
     LpSolverBase &copyLp() {return _copyLp();}
     
Index: src/lemon/lp_cplex.cc
===================================================================
--- src/lemon/lp_cplex.cc	(revision 1381)
+++ src/lemon/lp_cplex.cc	(revision 1381)
@@ -0,0 +1,309 @@
+/* -*- C++ -*-
+ * src/lemon/lp_cplex.cc
+ * - Part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include"lp_cplex.h"
+
+///\file
+///\brief Implementation of the LEMON-CPLEX lp solver interface.
+namespace lemon {
+  
+  LpCplex::LpCplex() : LpSolverBase() {
+    env = NULL;
+    lp = NULL;
+    env = CPXopenCPLEXdevelop(&status);     
+//     if (Env == NULL)
+//     {
+//          fprintf(stderr,"A CPLEX környezet megnyitása sikertelen.\n");
+// 	 CPXgeterrorstring(Env, Status, ErrorMsg);
+// 	 fprintf(stderr,"%s",ErrorMsg);
+// 	 goto Terminate;
+//     }
+    
+    // *** A problema létrehozása ***
+    lp = CPXcreateprob(env, &status, "LP problem");
+    
+    //    if (Problem == NULL)
+//     {
+// 	fprintf(stderr,"Az LP létrehozása sikertelen");
+// 	goto Terminate;
+//     }
+    
+  }
+  
+  LpCplex::~LpCplex() {
+    status = CPXfreeprob(env,&lp); 
+    //       if (Status != 0)
+    // 	{
+// 	  fprintf(stderr,"A CPLEX feladat törlése sikertelen.\n");
+// 	  CPXgeterrorstring(Env, Status, ErrorMsg);
+// 	  fprintf(stderr,"%s",ErrorMsg);
+// 	  goto Terminate;
+// 	}
+       
+    status = CPXcloseCPLEX(&env); 
+    //       if (Status != 0)
+    // 	{
+    // 	  fprintf(stderr,"A CPLEX környezet bezárása sikertelen.\n");
+// 	  CPXgeterrorstring(Env, Status, ErrorMsg);
+// 	  fprintf(stderr,"%s",ErrorMsg);
+// 	  goto Terminate;
+// 	}
+      
+  }
+  
+  LpSolverBase &LpCplex::_newLp() {return *(LpSolverBase*)0;}
+  LpSolverBase &LpCplex::_copyLp() {return *(LpSolverBase*)0;}
+
+  int LpCplex::_addCol()
+  {
+    int i = CPXgetnumcols (env, lp);
+    Value lb[1],ub[1];
+    lb[0]=-INF;//-CPX_INFBOUND;
+    ub[0]=INF;//CPX_INFBOUND;
+    status = CPXnewcols (env, lp, 1, NULL, lb, ub, NULL, NULL);
+    return i;
+  }
+  
+  int LpCplex::_addRow() 
+  {
+    //We want a row that is not constrained
+    char sense[1];
+    sense[0]='L';//<= constraint
+    Value rhs[1];
+    rhs[0]=INF;
+    int i = CPXgetnumrows (env, lp);
+    status = CPXnewrows (env, lp, 1, rhs, sense, NULL, NULL);
+    return i;
+  }
+  
+  ///\warning Data at index 0 is ignored in the arrays.
+  void LpCplex::_setRowCoeffs(int i, 
+			      int length,
+			      int  const * indices, 
+			      Value  const * values )
+  {
+    int rowlist[length+1];
+    int* p=rowlist;
+    for (int k=1;k<=length;++k){
+      rowlist[k]=i;
+    }
+    status = CPXchgcoeflist(env, lp, 
+			    length, 
+			    p+1, 
+			    const_cast<int * >(indices+1), 
+			    const_cast<Value * >(values+1));
+  }
+  
+  void LpCplex::_setColCoeffs(int i, 
+			      int length,
+			      int  const * indices, 
+			      Value  const * values)
+  {
+    int collist[length+1];
+    int* p=collist;
+    for (int k=1;k<=length;++k){
+      collist[k]=i;
+    }
+    status = CPXchgcoeflist(env, lp, 
+			    length, 
+			    const_cast<int * >(indices+1), 
+			    p+1, 
+			    const_cast<Value * >(values+1));
+  }
+  
+  void LpCplex::_setColLowerBound(int i, Value value)
+  {
+    int indices[1];
+    indices[0]=i;
+    char lu[1];
+    lu[0]='L';
+    Value bd[1];
+    bd[0]=value;
+    status = CPXchgbds (env, lp, 1, indices, lu, bd);
+ 
+  }
+  
+  void LpCplex::_setColUpperBound(int i, Value value)
+  {
+    int indices[1];
+    indices[0]=i;
+    char lu[1];
+    lu[0]='U';
+    Value bd[1];
+    bd[0]=value;
+    status = CPXchgbds (env, lp, 1, indices, lu, bd);
+  }
+
+  //This will be easier to implement
+  void LpCplex::_setRowBounds(int i, Value lb, Value ub)
+  {
+    //Bad parameter
+    if (lb==INF || ub==-INF) {
+      //FIXME error
+    }
+
+    int cnt=1;
+    int indices[1];
+    indices[0]=i;
+    char sense[1];
+
+    if (lb==-INF){
+      sense[0]='L';
+      CPXchgsense (env, lp, cnt, indices, sense);
+      CPXchgcoef (env, lp, i, -1, ub);
+    }
+    else{
+      if (ub==INF){
+	sense[0]='G';
+	CPXchgsense (env, lp, cnt, indices, sense);
+	CPXchgcoef (env, lp, i, -1, lb);
+      }
+      else{
+	if (lb == ub){
+	  sense[0]='E';
+	  CPXchgsense (env, lp, cnt, indices, sense);
+	  CPXchgcoef (env, lp, i, -1, lb);
+	}
+	else{
+	  sense[0]='R';
+	  CPXchgsense (env, lp, cnt, indices, sense);
+	  CPXchgcoef (env, lp, i, -1, lb);
+	  CPXchgcoef (env, lp, i, -2, ub-lb);	  
+	}
+      }
+    }
+  }
+
+  void LpCplex::_setRowLowerBound(int i, Value value)
+  {
+    //Not implemented, obsolete
+  }
+  
+  void LpCplex::_setRowUpperBound(int i, Value value)
+  {
+    //Not implemented, obsolete
+//     //TODO Ezt kell meg megirni
+//     //type of the problem
+//     char sense[1];
+//     status = CPXgetsense (env, lp, sense, i, i);
+//     Value rhs[1];
+//     status = CPXgetrhs (env, lp, rhs, i, i);
+
+//     switch (sense[0]) {
+//     case 'L'://<= constraint
+//       break;
+//     case 'E'://= constraint
+//       break;
+//     case 'G'://>= constraint
+//       break;
+//     case 'R'://ranged constraint
+//       break;
+//     default: ;
+//       //FIXME error
+//     }
+
+//     status = CPXchgcoef (env, lp, i, -2, value_rng);
+  }
+  
+  void LpCplex::_setObjCoeff(int i, Value obj_coef)
+  {
+    CPXchgcoef (env, lp, -1, i, obj_coef);
+  }
+
+  void LpCplex::_clearObj()
+  {
+    for (int i=0;i< CPXgetnumcols (env, lp);++i){
+      CPXchgcoef (env, lp, -1, i, 0);
+    }
+    
+  }
+
+  LpCplex::SolveExitStatus LpCplex::_solve()
+  {
+    
+    status = CPXlpopt (env, lp);
+    if (status == 0){
+      return SOLVED;
+    }
+    else{
+      return UNSOLVED;
+    }
+//     int i=  lpx_simplex(lp);
+//     switch (i) {
+//     case LPX_E_OK: 
+//       return SOLVED;
+//       break;
+//     default:
+//       return UNSOLVED;
+//     }
+  }
+
+  LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
+  {
+    //Unimplemented
+    return OPTIMAL;
+//     int stat=  lpx_get_status(lp);
+//     switch (stat) {
+//     case LPX_UNDEF://Undefined (no solve has been run yet)
+//       return UNDEFINED;
+//       break;
+//     case LPX_NOFEAS://There is no feasible solution (primal, I guess)
+//     case LPX_INFEAS://Infeasible 
+//       return INFEASIBLE;
+//       break;
+//     case LPX_UNBND://Unbounded
+//       return INFINITE;
+//       break;
+//     case LPX_FEAS://Feasible
+//       return FEASIBLE;
+//       break;
+//     case LPX_OPT://Feasible
+//       return OPTIMAL;
+//       break;
+//     default:
+//       return UNDEFINED; //to avoid gcc warning
+//       //FIXME error
+//     }
+  }
+
+  LpCplex::Value LpCplex::_getPrimal(int i)
+  {
+    Value x;
+    CPXgetx (env, lp, &x, i, i);
+    return x;
+  }
+  
+  LpCplex::Value LpCplex::_getPrimalValue()
+  {
+    //Unimplemented
+    return 0;
+  }
+  
+ 
+
+
+  void LpCplex::_setMax()
+  {
+    CPXchgobjsen (env, lp, CPX_MAX);
+   }
+  void LpCplex::_setMin()
+  {
+    CPXchgobjsen (env, lp, CPX_MIN);
+   }
+  
+} //namespace lemon
+
Index: src/lemon/lp_cplex.h
===================================================================
--- src/lemon/lp_cplex.h	(revision 1381)
+++ src/lemon/lp_cplex.h	(revision 1381)
@@ -0,0 +1,108 @@
+/* -*- C++ -*-
+ * src/lemon/lp_cplex.h - Part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_LP_CPLEX_H
+#define LEMON_LP_CPLEX_H
+
+///\file
+///\brief Header of the LEMON-CPLEX lp solver interface.
+
+#include <lemon/lp_base.h>
+extern "C" {
+#include <ilcplex/cplex.h>
+}
+
+namespace lemon {
+
+
+  /// \brief Wrapper for GLPK solver
+  /// 
+  /// This class implements a lemon wrapper for GLPK.
+  class LpCplex : public LpSolverBase {
+
+  public:
+
+    typedef LpSolverBase Parent;
+    
+    /// \e
+    int status;
+    CPXENVptr env;
+    CPXLPptr lp;
+
+
+    /// \e
+    LpCplex();
+    /// \e
+    ~LpCplex();
+
+  protected:
+    virtual LpSolverBase &_newLp();
+    virtual LpSolverBase &_copyLp();
+
+    virtual int _addCol();
+    virtual int _addRow();
+    virtual void _setRowCoeffs(int i, 
+			       int length,
+                               const int   * indices, 
+                               const Value   * values );
+    virtual void _setColCoeffs(int i, 
+			       int length,
+                               const int   * indices, 
+                               const Value   * values);
+    virtual void _setColLowerBound(int i, Value value);
+    virtual void _setColUpperBound(int i, Value value);
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual void _setRowBounds(int i, Value lower, Value upper);
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual void _clearObj();
+    ///\e
+    
+    ///\bug Unimplemented
+    ///
+    virtual SolveExitStatus _solve();
+    ///\e
+
+    ///\bug Unimplemented
+    ///
+    virtual Value _getPrimal(int i);
+    ///\e
+    
+    ///\bug Unimplemented
+    ///
+    virtual Value _getPrimalValue();
+    ///\e
+    
+    ///\bug Unimplemented
+    ///
+    virtual SolutionStatus _getPrimalStatus();
+
+    ///\e
+    
+    ///\bug Unimplemented
+    ///
+    virtual void _setMax();
+    ///\e
+    
+    ///\bug Unimplemented
+    ///
+    virtual void _setMin();
+
+  };
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_LP_CPLEX_H
+
