Index: lemon/config.h.in
===================================================================
--- lemon/config.h.in	(revision 1435)
+++ lemon/config.h.in	(revision 2605)
@@ -4,2 +4,5 @@
 /* Define to 1 if you have GLPK. */
 #undef HAVE_GLPK
+
+/* Define to 1 if you have SOPLEX. */
+#undef HAVE_SOPLEX
Index: lemon/lp_base.h
===================================================================
--- lemon/lp_base.h	(revision 2569)
+++ lemon/lp_base.h	(revision 2605)
@@ -372,23 +372,4 @@
       }
 
-      //std::ostream &
-      void prettyPrint(std::ostream &os) {
-	//std::fmtflags os.flags();
-	//os.setf(std::ios::showpos);
-	Base::iterator j=Base::begin();
-	if (j!=Base::end())
-	  os<<j->second<<"*x["<<id(j->first)<<"]";
-	++j;
-	for (; j!=Base::end(); ++j){
-	  if (j->second>=0)
-	    os<<"+";
-	  os<<j->second<<"*x["<<id(j->first)<<"]";
-	}
-	//Nem valami korrekt, de nem talaltam meg, hogy kell
-	//os.unsetf(std::ios::showpos);
-
-	//return os;
-      }
-
     };
     
@@ -482,17 +463,4 @@
       }
 
-      void prettyPrint(std::ostream &os) {
-	if (_lb==-LpSolverBase::INF||isNaN(_lb))
-	  os<<"-infty<=";
-	else
-	  os<<_lb<<"<=";
-	_expr.prettyPrint(os);
-	if (_ub==LpSolverBase::INF)
-	  os<<"<=infty";
-	else
-	  os<<"<="<<_ub;
-	//return os;
-      }
-
     };
     
@@ -736,13 +704,31 @@
 
     //Abstract virtual functions
-    virtual LpSolverBase &_newLp() = 0;
-    virtual LpSolverBase &_copyLp(){
-      ///\todo This should be implemented here, too, when we have
-      ///problem retrieving routines. It can be overriden.
-
-      //Starting:
-      LpSolverBase & newlp(_newLp());
+    virtual LpSolverBase* _newLp() = 0;
+    virtual LpSolverBase* _copyLp(){
+      LpSolverBase* newlp = _newLp();
+
+      std::map<Col, Col> ref;
+      for (LpSolverBase::ColIt it(*this); it != INVALID; ++it) {
+	Col ccol = newlp->addCol();
+	ref[it] = ccol;
+	newlp->colName(ccol, colName(it));
+	newlp->colLowerBound(ccol, colLowerBound(it));
+	newlp->colUpperBound(ccol, colUpperBound(it));
+      }
+
+      for (LpSolverBase::RowIt it(*this); it != INVALID; ++it) {
+	Expr e = row(it), ce;
+	for (Expr::iterator jt = e.begin(); jt != e.end(); ++jt) {
+	  ce[ref[jt->first]] = jt->second;
+	}
+	ce += e.constComp();
+	Row r = newlp->addRow(ce);
+
+        double lower, upper;
+        getRowBounds(it, lower, upper);
+	newlp->rowBounds(r, lower, upper);
+      }
+
       return newlp;
-      //return *(LpSolverBase*)0;
     };
 
@@ -805,7 +791,7 @@
 
     ///Creates a new LP problem
-    LpSolverBase &newLp() {return _newLp();}
+    LpSolverBase* newLp() {return _newLp();}
     ///Makes a copy of the LP problem
-    LpSolverBase &copyLp() {return _copyLp();}
+    LpSolverBase* copyLp() {return _copyLp();}
     
     ///\name Build up and modify the LP
Index: lemon/lp_cplex.cc
===================================================================
--- lemon/lp_cplex.cc	(revision 2591)
+++ lemon/lp_cplex.cc	(revision 2605)
@@ -18,4 +18,5 @@
 
 #include <iostream>
+#include <vector>
 #include<lemon/lp_cplex.h>
 
@@ -24,31 +25,30 @@
 namespace lemon {
   
-  LpCplex::LpCplex() : LpSolverBase() {
+  LpCplex::LpCplex() {
     //    env = CPXopenCPLEXdevelop(&status);     
     env = CPXopenCPLEX(&status);     
     lp = CPXcreateprob(env, &status, "LP problem");
   }
+
+  LpCplex::LpCplex(const LpCplex& cplex) : LpSolverBase() {
+    env = CPXopenCPLEX(&status);     
+    lp = CPXcloneprob(env, cplex.lp, &status);
+    rows = cplex.rows;
+    cols = cplex.cols;
+  }
   
   LpCplex::~LpCplex() {
-    CPXfreeprob(env,&lp); 
-    CPXcloseCPLEX(&env); 
-  }
-  
-  LpSolverBase &LpCplex::_newLp() 
+    CPXfreeprob(env,&lp);
+    CPXcloseCPLEX(&env);
+  }
+  
+  LpSolverBase* LpCplex::_newLp() 
   {
     //The first approach opens a new environment
-    LpCplex* newlp=new LpCplex();
-    return *newlp;
-  }
-
-  LpSolverBase &LpCplex::_copyLp() {
-    ///\bug FixID data is not copied!
-    //The first approach opens a new environment
-    LpCplex* newlp=new LpCplex();
-    //The routine CPXcloneprob can be used to create a new CPLEX problem 
-    //object and copy all the problem data from an existing problem 
-    //object to it. Solution and starting information is not copied.
-    newlp->lp = CPXcloneprob(env, lp, &status);
-    return *newlp;
+    return new LpCplex();
+  }
+
+  LpSolverBase* LpCplex::_copyLp() {
+    return new LpCplex(*this);
   }
 
@@ -57,6 +57,6 @@
     int i = CPXgetnumcols(env, lp);
     Value lb[1],ub[1];
-    lb[0]=-INF;//-CPX_INFBOUND;
-    ub[0]=INF;//CPX_INFBOUND;
+    lb[0]=-INF;
+    ub[0]=INF;
     status = CPXnewcols(env, lp, 1, NULL, lb, ub, NULL, NULL);
     return i;
@@ -90,5 +90,9 @@
     int storespace;
     CPXgetcolname(env, lp, 0, 0, 0, &storespace, col, col);
-
+    if (storespace == 0) {
+      name.clear();
+      return;
+    }
+    
     storespace *= -1;
     std::vector<char> buf(storespace);
@@ -137,4 +141,19 @@
 
   void LpCplex::_getRowCoeffs(int i, RowIterator b) const {
+    int tmp1, tmp2, tmp3, length;
+    CPXgetrows(env, lp, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
+    
+    length = -length;
+    std::vector<int> indices(length);
+    std::vector<double> values(length);
+
+    CPXgetrows(env, lp, &tmp1, &tmp2, &indices[0], &values[0], 
+	       length, &tmp3, i, i);
+    
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+    
     /// \todo implement
   }
@@ -157,5 +176,20 @@
 
   void LpCplex::_getColCoeffs(int i, ColIterator b) const {
-    /// \todo implement
+
+    int tmp1, tmp2, tmp3, length;
+    CPXgetcols(env, lp, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
+    
+    length = -length;
+    std::vector<int> indices(length);
+    std::vector<double> values(length);
+
+    CPXgetcols(env, lp, &tmp1, &tmp2, &indices[0], &values[0], 
+	       length, &tmp3, i, i);
+    
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+    
   }
   
@@ -188,4 +222,5 @@
     LpCplex::Value x;
     CPXgetlb (env, lp, &x, i, i);
+    if (x <= -CPX_INFBOUND) x = -INF;
     return x;
   }
@@ -206,4 +241,5 @@
     LpCplex::Value x;
     CPXgetub (env, lp, &x, i, i);
+    if (x >= CPX_INFBOUND) x = INF;
     return x;
   }
@@ -470,6 +506,6 @@
 // Description: Method for linear optimization. 
 // Determines which algorithm is used when CPXlpopt() (or "optimize" in the Interactive Optimizer) is called. Currently the behavior of the "Automatic" setting is that CPLEX simply invokes the dual simplex method, but this capability may be expanded in the future so that CPLEX chooses the method based on problem characteristics 
+#if CPX_VERSION < 900
   void statusSwitch(CPXENVptr env,int& stat){
-#if CPX_VERSION < 900
     int lpmethod;
     CPXgetintparam (env,CPX_PARAM_LPMETHOD,&lpmethod);
@@ -483,6 +519,8 @@
       }
     }
+  }
+#else
+  void statusSwitch(CPXENVptr,int&){}
 #endif
-  }
 
   LpCplex::SolutionStatus LpCplex::_getPrimalStatus() const
Index: lemon/lp_cplex.h
===================================================================
--- lemon/lp_cplex.h	(revision 2553)
+++ lemon/lp_cplex.h	(revision 2605)
@@ -50,9 +50,11 @@
     LpCplex();
     /// \e
+    LpCplex(const LpCplex&);
+    /// \e
     ~LpCplex();
 
   protected:
-    virtual LpSolverBase &_newLp();
-    virtual LpSolverBase &_copyLp();
+    virtual LpSolverBase* _newLp();
+    virtual LpSolverBase* _copyLp();
 
 
@@ -101,4 +103,9 @@
     virtual bool _isMax() const;
 
+  public:
+
+    CPXENVptr cplexEnv() { return env; } 
+    CPXLPptr cplexLp() { return lp; }
+
   };
 } //END OF NAMESPACE LEMON
Index: lemon/lp_glpk.cc
===================================================================
--- lemon/lp_glpk.cc	(revision 2591)
+++ lemon/lp_glpk.cc	(revision 2605)
@@ -90,4 +90,6 @@
 				LEMON_glp(get_col_ub)(glp.lp,i));
       }
+    rows = glp.rows;
+    cols = glp.cols;
   }
   
@@ -106,16 +108,16 @@
 
 
-  LpSolverBase &LpGlpk::_newLp()
-  {
-    LpGlpk* newlp=new LpGlpk;
-    return *newlp;
+  LpSolverBase* LpGlpk::_newLp()
+  {
+    LpGlpk* newlp = new LpGlpk;
+    return newlp;
   }
   
   ///\e
 
-  LpSolverBase &LpGlpk::_copyLp()
-  {
-    LpGlpk* newlp=new LpGlpk(*this);
-    return *newlp;
+  LpSolverBase* LpGlpk::_copyLp()
+  {
+    LpGlpk *newlp = new LpGlpk(*this);
+    return newlp;
   }
 
Index: lemon/lp_glpk.h
===================================================================
--- lemon/lp_glpk.h	(revision 2557)
+++ lemon/lp_glpk.h	(revision 2605)
@@ -50,6 +50,6 @@
     
   protected:
-    virtual LpSolverBase &_newLp();
-    virtual LpSolverBase &_copyLp();
+    virtual LpSolverBase* _newLp();
+    virtual LpSolverBase* _copyLp();
 
     virtual int _addCol();
@@ -121,4 +121,10 @@
     ///Pointer to the underlying GLPK data structure.
     LPX *lpx() {return lp;}
+
+    ///Returns the constraint identifier understood by GLPK.
+    int lpxRow(Row r) { return _lpId(r); }
+
+    ///Returns the variable identifier understood by GLPK.
+    int lpxCol(Col c) { return _lpId(c); }
   };
 } //END OF NAMESPACE LEMON
Index: lemon/lp_skeleton.cc
===================================================================
--- lemon/lp_skeleton.cc	(revision 2553)
+++ lemon/lp_skeleton.cc	(revision 2605)
@@ -23,14 +23,14 @@
 namespace lemon {
   
-  LpSolverBase &LpSkeleton::_newLp()
+  LpSolverBase* LpSkeleton::_newLp()
   {
     LpSolverBase *tmp=0;
-    return *tmp;
+    return tmp;
   }
   
-  LpSolverBase &LpSkeleton::_copyLp()
+  LpSolverBase* LpSkeleton::_copyLp()
   {
     LpSolverBase *tmp=0;
-    return *tmp;
+    return tmp;
   }
 
Index: lemon/lp_skeleton.h
===================================================================
--- lemon/lp_skeleton.h	(revision 2553)
+++ lemon/lp_skeleton.h	(revision 2605)
@@ -33,7 +33,7 @@
 
     ///\e
-    virtual LpSolverBase &_newLp();
+    virtual LpSolverBase* _newLp();
     ///\e
-    virtual LpSolverBase &_copyLp();
+    virtual LpSolverBase* _copyLp();
     /// \e
     virtual int _addCol();
Index: lemon/lp_soplex.cc
===================================================================
--- lemon/lp_soplex.cc	(revision 2553)
+++ lemon/lp_soplex.cc	(revision 2605)
@@ -37,14 +37,31 @@
     delete soplex;
   }
-  
-  LpSolverBase &LpSoplex::_newLp() {
+
+  LpSoplex::LpSoplex(const LpSoplex& lp) : LpSolverBase() {
+    rows = lp.rows;
+    rows.setIdHandler(relocateIdHandler);
+
+    cols = lp.cols;
+    cols.setIdHandler(relocateIdHandler);
+
+    soplex = new soplex::SoPlex;
+    (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
+
+    colNames = lp.colNames;
+    invColNames = lp.invColNames;
+
+    primal_value = lp.primal_value;
+    dual_value = lp.dual_value;
+
+  }
+  
+  LpSolverBase* LpSoplex::_newLp() {
     LpSoplex* newlp = new LpSoplex();
-    return *newlp;
-  }
-
-  LpSolverBase &LpSoplex::_copyLp() {
-    LpSoplex* newlp = new LpSoplex();
-    (*static_cast<soplex::SPxLP*>(newlp->soplex)) = *soplex;
-    return *newlp;
+    return newlp;
+  }
+
+  LpSolverBase* LpSoplex::_copyLp() {
+    LpSoplex* newlp = new LpSoplex(*this);
+    return newlp;
   }
 
Index: lemon/lp_soplex.h
===================================================================
--- lemon/lp_soplex.h	(revision 2553)
+++ lemon/lp_soplex.h	(revision 2605)
@@ -67,10 +67,12 @@
     LpSoplex();
     /// \e
+    LpSoplex(const LpSoplex&);
+    /// \e
     ~LpSoplex();
 
   protected:
 
-    virtual LpSolverBase &_newLp();
-    virtual LpSolverBase &_copyLp();
+    virtual LpSolverBase* _newLp();
+    virtual LpSolverBase* _copyLp();
 
     virtual int _addCol();
Index: test/lp_test.cc
===================================================================
--- test/lp_test.cc	(revision 2571)
+++ test/lp_test.cc	(revision 2605)
@@ -21,4 +21,5 @@
 #include "test_tools.h"
 #include <lemon/tolerance.h>
+#include <lemon/lp_utils.h>
 
 #ifdef HAVE_CONFIG_H
@@ -217,5 +218,6 @@
   {
     LP::DualExpr e,f,g;
-    LP::Row p1,p2,p3,p4,p5;
+    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID, 
+      p4 = INVALID, p5 = INVALID;
     
     e[p1]=2;
@@ -296,5 +298,4 @@
   lp.max();
 
-
   //Testing the problem retrieving routines
   check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
@@ -308,5 +309,37 @@
   check(  lb==-LpSolverBase::INF,"The lower bound for the first row should be -infty.");
   check(  ub==1,"The upper bound for the first row should be 1.");
-
+  LpSolverBase::Expr e = lp.row(upright);
+  check(  e.size() == 2, "The row retrieval gives back wrong expression.");
+  check(  e[x1] == 1, "The first coefficient should 1.");
+  check(  e[x2] == 1, "The second coefficient should 1.");
+
+  LpSolverBase::DualExpr de = lp.col(x1);
+  check(  de.size() == 4, "The col retrieval gives back wrong expression.");
+  check(  de[upright] == 1, "The first coefficient should 1.");
+
+  LpSolverBase* clp = lp.copyLp();
+
+  //Testing the problem retrieving routines
+  check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
+  check(clp->isMax(),"This is a maximization!");
+  check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
+  //  std::cout<<lp.colLowerBound(x1)<<std::endl;
+  check(  clp->colLowerBound(x1)==0,"The lower bound for variable x1 should be 0.");
+  std::cerr << clp->colUpperBound(x1) << std::endl;
+  check(  clp->colUpperBound(x1)==LpSolverBase::INF,"The upper bound for variable x1 should be infty.");
+
+  clp->getRowBounds(upright,lb,ub);
+  check(  lb==-LpSolverBase::INF,"The lower bound for the first row should be -infty.");
+  check(  ub==1,"The upper bound for the first row should be 1.");
+  e = clp->row(upright);
+  check(  e.size() == 2, "The row retrieval gives back wrong expression.");
+  check(  e[x1] == 1, "The first coefficient should 1.");
+  check(  e[x2] == 1, "The second coefficient should 1.");
+
+  de = clp->col(x1);
+  check(  de.size() == 4, "The col retrieval gives back wrong expression.");
+  check(  de[upright] == 1, "The first coefficient should 1.");
+  
+  delete clp;
 
   //Maximization of x1+x2
@@ -338,4 +371,5 @@
   lp.min();
   check(lp.primalStatus()==LpSolverBase::UNDEFINED,"Primalstatus should be UNDEFINED");
+
 
 //   lp.solve();
