diff --git a/include/relation.cpp b/include/relation.cpp
index 230873ffb..44a123c31 100755
--- a/include/relation.cpp
+++ b/include/relation.cpp
@@ -14,7 +14,6 @@
 #include <xvtility.h>
 
 #include <codeb.h>
-
 // *** check if not already defined
 #define NOTFOUND (-1)
 
@@ -77,6 +76,7 @@ public:
   int num() const { return _num; }
   int link() const { return _numto; }
   int alias() const { return _alias; }
+  bool allow_lock() const { return _allow_lock; }
   bool write_enable() const { return _write_enable; }
   void write_enable(bool we) { _write_enable = we; }
   TRectype& load_rec(TRectype& r, const TBaseisamfile& from) const;
@@ -470,8 +470,8 @@ void TRelation::write_enable(const char* name, const bool on)
 bool TRelation::add(
      TLocalisamfile* f,     // @parm Descrittore del file da aggiungere
      const char* relexprs,  // @parm Espressione della relazione
-     int key,               // @parm Chiave del file principale
-     int linkto,            // @parm Posizione a cui aggiungere il file
+     int key,               // @parm Chiave del file 
+     int linkto,            // @parm Posizione alla quale aggiungere il file
      int alias,             // @parm Alias da dare al file da aggiungere
      bool allow_lock)       // @parm Indica se fare il lock sul file oppure ignorarli
                             // @parm int | logicnum | Numero logico del file da aggiungere
@@ -524,11 +524,21 @@ bool TRelation::add(const char* tabname, const char* relexprs, int key,
 // @mfunc Sostituisce nella relazione un file
 void TRelation::replace(
      TLocalisamfile* f,  // @parm Descrittore del file sostituto
-     int index)          // @parm Posizione nel quale sostituire il file (default 0)
+     int index,          // @parm Posizione nel quale sostituire il file (default 0)
+     const char* relexprs,  // @parm Nuova Espressione della relazione
+     int key)               // @parm Nuova Chiave del file 
+
 {
   const TLocalisamfile* p = (const TLocalisamfile*)_files.objptr(index);
   CHECK(p && p->num() == f->num(), "Can't replace a file with different logic number");
   _files.add(f, index);
+  if (relexprs && *relexprs ) 
+  {
+  	TRelationdef* oldr=(TRelationdef*)_reldefs.objptr(index-1);
+  	TRelationdef* r = new TRelationdef(this, index, key, oldr->link(),
+                                     relexprs, oldr->alias(), oldr->allow_lock());
+  	_reldefs.add(r,index-1);
+  }
 } 
 
 TRectype& TRelationdef::load_rec(TRectype& r, const TBaseisamfile& from) const
@@ -591,14 +601,20 @@ int TRelation::position_rels(
     // build record
     for (int j = 0 ; j < rd._fields.items(); j++) // for each field
     {
-      const char* expr = rd.evaluate_expr(j, to);
+      TString expr (rd.evaluate_expr(j, to));
       TFieldref& s = (TFieldref&) rd._fields[j];
+      if (from.is_sorted() && from.curr().type(s.name()) ==_alfafld)
+      	expr.rpad(s.len(from.curr()),'~');
       s.write(expr, furr);
     } // for each field
 
+    if (from.is_sorted())
+    {
+    	((TSortedfile &)from).setregion(from.curr(),from.curr());
+    	from.first();
     // read record: if not found, zero current record
- 
-    from.read(op, lck, atdate);
+    } else
+    	from.read(op, lck, atdate);
     if (from.bad())
     {
       bool eq = TRUE;
@@ -2230,5 +2246,204 @@ TRelation_description::~TRelation_description()
 }  
 
 
+////////////////////////////////////
+// TSortedfile
+////////////////////////////////////
+// @mfunc Avanza di <p npos> record
+int TSortedfile::operator +=(const TRecnotype npos)
+{
+	*_curs+=npos;
+	setstatus(_curs->file().status());
+	return _curs->test();
+}
+  // @mfunc Sposta indietro di <p npos> record
+int TSortedfile::operator -=(const TRecnotype npos)
+{
+	*_curs-=npos;
+	setstatus(_curs->file().status());
+	return _curs->test();
+}
+  // @mfunc Avanza al record successivo
+int TSortedfile::operator ++()
+{	
+	return *this+=1;
+}
+  // @mfunc Indietreggia al record precedente
+int TSortedfile::operator --()
+{	
+	return *this-=1;
+}
+
+// @mfunc Si posiziona sul primo record del file (vedi <t TReclock>)
+int TSortedfile::first(word lockop )
+{
+	_curs->first_item();
+	setstatus(_curs->file().status());
+	return _curs->items()>0;
+}
+// @mfunc Si posiziona sull'ultimo record del file (vedi <t TReclock>)
+int TSortedfile::last(word lockop )
+{
+	_curs->last_item();
+	setstatus(_curs->file().status());
+	return _curs->items()>0;
+}
+// @mfunc Si posiziona sul successivo record del file (vedi <t TReclock>)
+int TSortedfile::next(word lockop )
+{
+	_curs->succ_item();
+	setstatus(_curs->file().status());
+	return _curs->pos()<=_curs->items();
+}
+// @mfunc Si posiziona sul precedente record del file (vedi <t TReclock>)
+int TSortedfile::prev(word lockop )
+{
+	_curs->pred_item();
+	setstatus(_curs->file().status());
+	return _curs->pos()>0;
+}
+
+// @mfunc Salta <p nrec> record dalla posizione corrente (vedi <t TReclock>)
+int TSortedfile::skip(TRecnotype nrec, word lockop )
+{
+//	return *this+=nrec; manca il lock...
+	setstatus(_curs->file().status());
+	error_box("Operazione 'skip' non consentita sul cursore");
+	return 0;
+}
+
+// @mfunc Rilegge l'ultimo record letto (vedi <t TReclock>)
+int TSortedfile::reread(word lockop , TDate& atdate )
+{
+	return reread(curr(),lockop,atdate);
+}
+// @mfunc Rilegge l'ultimo record letto e lo copia in <p rec> (vedi <t TReclock>)
+int TSortedfile::reread(TRectype& rec, word lockop , TDate& atdate)
+{
+	return 0;
+}
+
+
+// @mfunc Legge il record (vedi <t TReclock> e <t TIsamop>)
+int TSortedfile::read(word op , word lockop , TDate& atdate )
+{
+	return read(curr(),op,lockop,atdate);
+}
+// @mfunc Legge il record e lo copia in <p rec> (vedi <t TReclock> e <t TIsamop>)
+int TSortedfile::read(TRectype& rec, word op , word lockop, TDate& atdate )
+{
+	_curs->read((TIsamop)op,(TReclock)lockop,atdate);
+	setstatus(_curs->file().status());
+	return status();
+}
+
+// @mfunc Legge il record alla posizione <p nrec> e lo copia in <p rec> (vedi <t TReclock>)
+int TSortedfile::readat(TRectype& rec, TRecnotype nrec, word lockop )
+{
+	*_curs=nrec;
+	//read(_isequal,lockop);
+	rec=curr();
+	setstatus(_curs->file().status());
+	return status();
+}
+// @mfunc Legge il record alla posizione <p nrec> e lo copia in <p rec> (vedi <t TReclock>)
+int TSortedfile::readat(TRecnotype nrec, word lockop )
+{
+	return readat(curr(),nrec, lockop );
+}
+
+// @mfunc Aggiunge un record
+ int TSortedfile::write(TDate& atdate)
+{
+	return write(curr(),atdate);
+}
+// @mfunc Aggiunge un record copiando da <p rec>
+ int TSortedfile::write(const TRectype& rec, TDate& atdate )
+ {
+	return 0;
+ }
+
+// @mfunc Riscrive un record
+ int TSortedfile::rewrite(TDate& atdate )
+ {
+	return 0;
+ }
+// @mfunc Riscrive un record (il record <p rec>)
+ int TSortedfile::rewrite(const TRectype& rec, TDate& atdate )
+ {
+	return 0;
+ }
+
+// @mfunc Riscrive un record alla posizione <p nrec> copiando da <p rec>
+int TSortedfile::rewriteat(TRecnotype nrec)
+{
+	return rewriteat(curr(),nrec);
+}
+// @mfunc Riscrive un record alla posizione <p nrec> copiando da <p rec>
+int TSortedfile::rewriteat(const TRectype& rec, TRecnotype nrec)
+{
+	error_box("Operazione 'rewriteat' non consentita sul cursore");
+	return 0;
+}
+
+// @mfunc Elimina il record
+int TSortedfile::remove(TDate& atdate )
+{
+	return remove(curr(),atdate);
+}
+// @mfunc Elimina il record copiando da <p rec>
+int TSortedfile::remove(const TRectype& rec, TDate& atdate )
+{
+	return 0;
+}
+
+// @mfunc Attiva la chiave <p nkey> sul file aperto
+void TSortedfile::setkey(int nkey)
+{
+	_curs->setkey(nkey);
+}
+// @mfunc Resetta la regione del file (chiama <p TCursor::setregion>
+void TSortedfile::setregion(const TRectype &f,const TRectype &t)
+{
+	_curs->setregion(f,t);
+}
+
+  // @mfunc 
+TRecnotype TSortedfile::eod() const
+{
+	return _curs->items();
+}
+  // @mfunc 
+bool TSortedfile::empty()
+{
+	return _curs->items()==0;
+}
+
+// @mfunc Costruttore. 
+TSortedfile::TSortedfile(int logicnum,TRelation * rel,const char * ordexpr,const char * filter, int nkey)
+	:TLocalisamfile(logicnum),_rel(NULL)
+{
+	// costruisce il cursore
+	if (!rel)
+	{
+	 	_rel = new TRelation(logicnum);
+	}
+ 	else
+ 		_rel=rel;
+  _curs = new TSorted_cursor(_rel,ordexpr,filter,nkey);
+  _curs->setfilter(filter,TRUE); //BUG: cursors doesn't update rel.
+
+	if (&curr()!=&(_curs->file().curr()))
+  	_curs->file().set_curr(&curr());
+}
+// @mfunc Distruttore
+TSortedfile::~TSortedfile()
+{
+	delete _curs;
+  if (_rel) delete _rel;
+}
+
+
+//
 // *** EOF relation.cpp
 
diff --git a/include/relation.h b/include/relation.h
index e4f7431dc..919c05765 100755
--- a/include/relation.h
+++ b/include/relation.h
@@ -126,7 +126,7 @@ public:
   // @cmember Aggiunge una nuovo file alla relazione partendo dal nome della tabella
   bool add(const char* tabname, const char* relexprs, int key = 1, int linkto = 0, int alias = 0, bool allow_lock = FALSE);
   // @cmember Sostituisce nella relazione un file
-  void replace(TLocalisamfile* f, int index = 0);
+  void replace(TLocalisamfile* f, int index = 0,const char * relexprs="",int key=1);
 
   // @cmember Aggiunge il record corrente
   virtual int write (bool force = TRUE, TDate& atdate = (TDate&)botime);
@@ -650,6 +650,106 @@ public:
 // @devnote Domani o doman l'altro gestira' l'editing interattivo e grafico
 };
 
+// @doc EXTERNAL
+
+// @class TSortedfile | Classe per la definizione di ordinamenti arbitrari sui file isam
+//
+// @base public | TLocalisamfile
+//
+// @author:(INTERNAL) Augusto
+class TSortedfile : public TLocalisamfile
+{
+	TRelation * _rel;
+	TSorted_cursor * _curs;
+  // @access:(INTERNAL) Private Member
+
+// @access Protected Members
+protected:
+  // @cmember Apre il file con lock (vedi <mf TBaseisamfile::_open>)
+  int open(unsigned int mode = _manulock);
+  // @cmember Chiude il file aperto
+  int close() ;
+
+// @access Public Members
+public:
+  // @cmember Avanza di <p npos> record
+  virtual int operator +=(const TRecnotype npos);
+  // @cmember Sposta indietro di <p npos> record
+  virtual int operator -=(const TRecnotype npos);
+  // @cmember Avanza al record successivo
+  virtual int operator ++();
+  // @cmember Indietreggia al record precedente
+  virtual int operator --();
+  // @cmember Ritorna TRUE se tabella
+  virtual bool tab() const 
+  { return FALSE;}
+
+  // @cmember Si posiziona sul primo record del file (vedi <t TReclock>)
+  virtual int first(word lockop = _nolock);
+  // @cmember Si posiziona sull'ultimo record del file (vedi <t TReclock>)
+  virtual int last(word lockop = _nolock);
+  // @cmember Si posiziona sul successivo record del file (vedi <t TReclock>)
+  virtual int next(word lockop = _nolock);
+  // @cmember Si posiziona sul precedente record del file (vedi <t TReclock>)
+  virtual int prev(word lockop = _nolock);
+  // @cmember Rilegge l'ultimo record letto (vedi <t TReclock>)
+  virtual int reread(word lockop = _nolock, TDate& atdate = (TDate&)botime);
+  // @cmember Rilegge l'ultimo record letto e lo copia in <p rec> (vedi <t TReclock>)
+  virtual int reread(TRectype& rec, word lockop = _nolock, TDate& atdate = (TDate&)botime);
+  // @cmember Salta <p nrec> record dalla posizione corrente (vedi <t TReclock>)
+  virtual int skip(TRecnotype nrec, word lockop = _nolock);
+  // @cmember Legge il record (vedi <t TReclock> e <t TIsamop>)
+  virtual int read(word op = _isequal, word lockop = _nolock, TDate& atdate = (TDate&)botime);
+  // @cmember Legge il record e lo copia in <p rec> (vedi <t TReclock> e <t TIsamop>)
+  virtual int read(TRectype& rec, word op = _isequal, word lockop = _nolock, TDate& atdate = (TDate&)botime);
+  // @cmember Legge il record alla posizione  <p nrec> (vedi <t TReclock>)
+  virtual int readat(TRecnotype nrec, word lockop = _nolock);
+  // @cmember Legge il record alla posizione <p nrec> e lo copia in <p rec> (vedi <t TReclock>)
+  virtual int readat(TRectype& rec, TRecnotype nrec, word lockop = _nolock);
+  // @cmember Aggiunge un record
+  virtual int write(TDate& atdate = (TDate&)botime);
+  // @cmember Aggiunge un record copiando da <p rec>
+  virtual int write(const TRectype& rec, TDate& atdate = (TDate&)botime);
+  // @cmember Riscrive un record
+  virtual int rewrite(TDate& atdate = (TDate&)botime);
+  // @cmember Riscrive un record (il record <p rec>)
+  virtual int rewrite(const TRectype& rec, TDate& atdate = (TDate&)botime);
+  // @cmember Riscrive un record alla posizione <p nrec>
+  virtual int rewriteat(TRecnotype nrec);
+  // @cmember Riscrive un record alla posizione <p nrec> copiando da <p rec>
+  virtual int rewriteat(const TRectype& rec, TRecnotype nrec);
+  // @cmember Elimina il record
+  virtual int remove(TDate& atdate = (TDate&)botime);
+  // @cmember Elimina il record copiando da <p rec>
+  virtual int remove(const TRectype& rec, TDate& atdate = (TDate&)botime);
+  // @cmember 
+  virtual TRecnotype eod() const ;
+  // @cmember 
+  virtual bool empty();
+  // @cmember Ritorna il numero del record corrente
+  virtual TRecnotype recno() const 
+  {return _curs->pos();}
+  // @cmember setta la chiave 
+	void setkey(int nkey);
+  // @cmember Resetta la regione del file (chiama <p TCursor::setregion>
+	void setregion(const TRectype &f,const TRectype &t);
+
+	// TO REMOVE
+	TRelation &relation()  
+	{return *_rel;}
+	// TO REMOVE
+	TSorted_cursor &cursor() 
+	{return *_curs;}
+  // @cmember Restituisce se il file � ordinato con indice esterno (default:FALSE)
+  virtual bool is_sorted()
+  {return TRUE;}
+  // @cmember Costruttore. 
+  TSortedfile(int logicnum,TRelation * rel,const char * ordexpr="",const char * filter="", int nkey=1);
+  // @cmember Distruttore
+  virtual ~TSortedfile();
+};
+
+
 
 #endif
 // ** EOF relation.h