package UGPGStudentsExample;

import java.sql.*;
import java.io.*;
import uk.ac.ic.doc.automed.*;
import uk.ac.ic.doc.automed.reps.*;
import java.util.ArrayList;
import uk.ac.ic.doc.automed.wrappers.SQLWrapperFactory;

/*
 * An application to demonstrate how to link schemas in YATTA model together 
 * via transformation pathways 
 */

// NOTE: The transformation here doesn't take patterns into consideration. 
//       We just want to test merging schemas in YATTA model. 

public class DefineTransformations {

  public static Schema transformS1ToSyg(Schema s1) 
    throws NotFoundException, TypeMismatchException {
    Model yatta=Model.getModel("yatta");
    Construct rootnode=yatta.getConstruct("rootnode");
    Construct yattanode=yatta.getConstruct("yattanode");
    Construct sequence=yatta.getConstruct("sequence");

    // Retrieve the objects of the schema
    SchemaObject s1_root=s1.getSchemaObject("<<root>>");
    SchemaObject s1_student=s1.getSchemaObject("<<root,student>>");
    SchemaObject s1_name=s1.getSchemaObject("<<<<root,student>>,name>>");

    //********************************************//
    // Start the transformation steps S1 -> Syg   //
    //********************************************//

    //Growing Phrase
    // RENAME "student" to "ug"
    Transformation t1_1 = Transformation.createRenameTransformation(s1, s1_student, 
								 new Object[] {s1_root,"ug","set","+"});
    Schema s1a=t1_1.getOtherSchema(s1);
    SchemaObject newnames=t1_1.getSchemaObject(s1a);
    SchemaObject syg_ug=(SchemaObject)newnames.getSchemeDefinition()[0];

    SchemaObject s1_ug_name=s1a.getSchemaObject("<<<<root,ug>>,name>>");    
    SchemaObject s1_tutor=s1a.getSchemaObject("<<<<root,ug>>,tutor>>");    
    SchemaObject s1_ppt=s1a.getSchemaObject("<<<<root,ug>>,ppt>>");
    SchemaObject s1_course=s1a.getSchemaObject("<<<<root,ug>>,course>>");
    SchemaObject s1_code=s1a.getSchemaObject("<<<<<<root,ug>>,course>>,code>>");
    SchemaObject s1_dept=s1a.getSchemaObject("<<<<<<root,ug>>,course>>,dept>>");
    SchemaObject s1_year=s1a.getSchemaObject("<<<<<<root,ug>>,course>>,year>>");
    SchemaObject s1_grade=s1a.getSchemaObject("<<<<<<root,ug>>,course>>,grade>>");
    SchemaObject s1_seq_name_tutor=s1a.getSchemaObject("<<_,<<<<root,ug>>,name>>,<<<<root,ug>>,tutor>>>>");
    SchemaObject s1_seq_tutor_ppt=s1a.getSchemaObject("<<_,<<<<root,ug>>,tutor>>,<<<<root,ug>>,ppt>>>>");
    SchemaObject s1_seq_ppt_course=s1a.getSchemaObject("<<_,<<<<root,ug>>,ppt>>,<<<<root,ug>>,course>>>>");
    SchemaObject s1_seq_year_grade=s1a.getSchemaObject("<<_,<<<<<<root,ug>>,course>>,year>>,<<<<<<root,ug>>,course>>,grade>>>>");
    SchemaObject s1_seq_dept_year=s1a.getSchemaObject("<<_,<<<<<<root,ug>>,course>>,dept>>,<<<<<<root,ug>>,course>>,year>>>>");
    SchemaObject s1_seq_code_dept=s1a.getSchemaObject("<<_,<<<<<<root,ug>>,course>>,code>>,<<<<<<root,ug>>,course>>,dept>>>>");


    // EXTEND "pg" node
    Transformation t1_2 = Transformation.createExtendTransformation(s1a, yattanode, 
								 new Object[] {s1_root, "pg","set","+"},
								 null,null);
    Schema s1b=t1_2.getOtherSchema(s1a);
    SchemaObject syg_pg=t1_2.getSchemaObject(s1b);

    // EXTEND sequence: pg node comes after ug node
    Transformation t1_3 = Transformation.createExtendTransformation(s1b, sequence,
								    new Object[] {"",syg_ug,syg_pg},
								    "[{ug,pg} | {r,ug} <- <<root,ug>>; {r,pg} <- <<root,pg>>]",
								    null);
    Schema s1c=t1_3.getOtherSchema(s1b);


    // EXTEND "name" node
    Transformation t1_4 = Transformation.createExtendTransformation(s1c, yattanode, 
								 new Object[] {syg_pg,"name","string","k"},
								 null,null);
    Schema s1d=t1_4.getOtherSchema(s1c);
    SchemaObject syg_pg_name=t1_4.getSchemaObject(s1d);

    // EXTEND "student" node
    Transformation t1_5 = Transformation.createExtendTransformation(s1d, yattanode, 
								 new Object[] {s1_root, "student","set","+"},
  								 "[{r,s} | {r,u} <- <<root,ug>>; {u,n} <- <<<<root,ug>>,name>>; s <- [generateGID 's1' u [n] 'student']]", 
								 null);
    Schema s1e=t1_5.getOtherSchema(s1d);
    SchemaObject syg_student=t1_5.getSchemaObject(s1e);

    // EXTEND sequence: student node comes after pg node
    Transformation t1_6 = Transformation.createAddTransformation(s1e, sequence,
								 new Object[] {"",syg_pg,syg_student},
								 "[{pg,s} | {r,pg} <- <<root,pg>>; {r,s} <- <<root,student>>]",
								 null);
    Schema s1f=t1_6.getOtherSchema(s1e);


    // EXTEND "name" node
    Transformation t1_7 = Transformation.createExtendTransformation(s1f, yattanode, 
								 new Object[] {syg_student, "name","string","k"},
								 "[{s,n} | {r,u} <- <<root,ug>>; {u,n} <- <<<<root,ug>>,name>>; s <- [generateGID 's1' u [n] 'student']]", 
								 null);
    Schema s1g=t1_7.getOtherSchema(s1f);
    SchemaObject syg_student_name=t1_7.getSchemaObject(s1g);

     // EXTEND "tutor" node
    Transformation t1_8 = Transformation.createExtendTransformation(s1g, yattanode, 
								 new Object[] {syg_student,"tutor","string",""},
								 "[{s,t} | {r,u} <- <<root,ug>>; {u,n} <- <<<<root,ug>>,name>>; {u,t} <- <<<<root,ug>>,tutor>>; s <- [generateGID 's1' u [n] 'student']]", 
								 null);
    Schema s1h=t1_8.getOtherSchema(s1g);
    SchemaObject syg_student_tutor=t1_8.getSchemaObject(s1h);

    // EXTEND sequence: tutor node comes after name node
    Transformation t1_9 = Transformation.createAddTransformation(s1h, sequence,
								 new Object[] {"",syg_student_name,syg_student_tutor},
								 "[{n,t} | {s,n} <- <<<<root,student>>,name>>; {s,t} <- <<<<root,student>>,tutor>>]", 
								 null);
    Schema s1i=t1_9.getOtherSchema(s1h);


    // CONTRACT sequence: name-tutor 
    Transformation t1_10 = Transformation.createContractTransformation(s1i, s1_seq_name_tutor,
								 "[{n,t} | {r,u} <- <<root,ug>>; {u,n} <- <<<<root,ug>>,name>>; {s,n} <- <<<<root,student>>,name>>; {s,t} <- <<<<root,student>>,tutor>>]", 
								 null);
    Schema s1j=t1_10.getOtherSchema(s1i);

    // CONTRACT sequence: tutor-ppt 
    Transformation t1_11 = Transformation.createContractTransformation(s1j, s1_seq_tutor_ppt,
								 "[{t,p} | {r,u} <- <<root,ug>>; {u,n} <- <<<<root,ug>>,name>>; {u,p} <- <<<<root,ug>>,ppt>>; {s,n} <- <<<<root,student>>,name>>; {s,t} <- <<<<root,student>>,tutor>>]", 
								 null);
    Schema s1k=t1_11.getOtherSchema(s1j);

    // CONTRACT "tutor" node from ug
    Transformation t1_12 = Transformation.createContractTransformation(s1k, s1_tutor, 
								 "[{u,t} | {r,u} <- <<root,ug>>; {u,n1} <- <<<<root,ug>>,name>>; {s,n} <- <<<<root,student>>,name>>; {s,t} <- <<<<root,student>>,tutor>>]", 
								 null);
    Schema s1l=t1_12.getOtherSchema(s1k);

    // EXTEND sequence: ppt node comes after name node
    Transformation t1_13 = Transformation.createExtendTransformation(s1l, sequence,
								  new Object[] {"",s1_ug_name,s1_ppt},
								  "[{n,p} | {u,n} <- <<<<root,ug>>,name>>; {u,p} <- <<<<root,ug>>,ppt>>]",
								  null);
    Schema s1m=t1_13.getOtherSchema(s1l);


    // EXTEND "result" node
    Transformation t1_14 = Transformation.createExtendTransformation(s1m, yattanode, 
								 new Object[] {s1_root,"result","set","+"},
								 "[{r,re} | {r,u} <- <<root,ug>>; {u,n} <- <<<<root,ug>>,name>>; {u,c} <- <<<<root,ug>>,course>>; {c,co} <- <<<<<<root,ug>>,course>>,code>>; re <- [generateGID 's1' c [n,co] 'result']]", 
								 null);
    Schema s1n=t1_14.getOtherSchema(s1m);
    SchemaObject syg_result=t1_14.getSchemaObject(s1n);

    // EXTEND sequence: result node comes after student node
    Transformation t1_15 = Transformation.createExtendTransformation(s1n, sequence,
								  new Object[] {"",syg_student,syg_result},
								  "[{s,re} | {r,s} <- <<root,student>>; {r,re} <- <<root,result>>]",
								  null);
    Schema s1o=t1_15.getOtherSchema(s1n);


    // EXTEND "code" node
    Transformation t1_16 = Transformation.createExtendTransformation(s1o, yattanode, 
								 new Object[] {syg_result,"code","string","k"},
								 "[{re,co} | {r,u} <- <<root,ug>>; {u,n} <- <<<<root,ug>>,name>>; {u,c} <- <<<<root,ug>>,course>>; {c,co} <- <<<<<<root,ug>>,course>>,code>>; re <- [generateGID 's1' c [n,co] 'result']]", 
								 null);
    Schema s1p=t1_16.getOtherSchema(s1o);
    SchemaObject syg_result_code=t1_16.getSchemaObject(s1p);


    // EXTEND "name" node
    Transformation t1_17 = Transformation.createExtendTransformation(s1p, yattanode, 
								 new Object[] {syg_result,"name","string","k"},
								 "[{re,n} | {r,u} <- <<root,ug>>; {u,n} <- <<<<root,ug>>,name>>; {u,c} <- <<<<root,ug>>,course>>; {c,co} <- <<<<<<root,ug>>,course>>,code>>; re <- [generateGID 's1' c [n,co] 'result']]", 
								 null);
    Schema s1q=t1_17.getOtherSchema(s1p);
    SchemaObject syg_result_name=t1_17.getSchemaObject(s1q);


    // EXTEND sequence: name node comes after code node
    Transformation t1_18 = Transformation.createExtendTransformation(s1q, sequence,
								  new Object[] {"",syg_result_code,syg_result_name},
								  "[{co,n} | {re,co} <- <<<<root,result>>,code>>; {re,n} <- <<<<root,result>>,name>>]",
								  null);
    Schema s1r=t1_18.getOtherSchema(s1q);


    // EXTEND "year" node
    Transformation t1_19 = Transformation.createExtendTransformation(s1r, yattanode, 
								 new Object[] {syg_result,"year","integer",""},
								 "[{re,y} | {r,u} <- <<root,ug>>; {u,n} <- <<<<root,ug>>,name>>; {u,c} <- <<<<root,ug>>,course>>; {c,co} <- <<<<<<root,ug>>,course>>,code>>; {c,y} <- <<<<<<root,ug>>,course>>,year>>; re <- [generateGID 's1' c [n,co] 'result']]", 
								 null);
    Schema s1s=t1_19.getOtherSchema(s1r);
    SchemaObject syg_result_year=t1_19.getSchemaObject(s1s);

    // EXTEND sequence: year node comes after name node
    Transformation t1_20 = Transformation.createExtendTransformation(s1s, sequence,
								  new Object[] {"",syg_result_name,syg_result_year},
								  "[{n,y} | {re,n} <- <<<<root,result>>,name>>; {re,y} <- <<<<root,result>>,year>>]",
								  null);
    Schema s1t=t1_20.getOtherSchema(s1s);

    // EXTEND "grade" node
    Transformation t1_21 = Transformation.createExtendTransformation(s1t, yattanode, 
								 new Object[] {syg_result,"grade","string","?"},
								 "[{re,g} | {r,u} <- <<root,ug>>; {u,n} <- <<<<root,ug>>,name>>; {u,c} <- <<<<root,ug>>,course>>; {c,co} <- <<<<<<root,ug>>,course>>,code>>; {c,g} <- <<<<<<root,ug>>,course>>,grade>>; re <- [generateGID 's1' c [n,co] 'result']]", 
								 null);
    Schema s1u=t1_21.getOtherSchema(s1t);
    SchemaObject syg_result_grade=t1_21.getSchemaObject(s1u);

    // EXTEND sequence: grade node comes after year node
    Transformation t1_22 = Transformation.createExtendTransformation(s1u, sequence,
								  new Object[] {"",syg_result_year,syg_result_grade},
								  "[{y,g} | {re,y} <- <<<<root,result>>,year>>; {re,g} <- <<<<root,result>>,grade>>]",
								  null);
    Schema s1v=t1_22.getOtherSchema(s1u);


    // EXTEND "course" node
    Transformation t1_23 = Transformation.createExtendTransformation(s1v, yattanode, 
								 new Object[] {s1_root,"course","set","+"},
								 "[{r,c_yg} | {r,u} <- <<root,ug>>; {u,c} <- <<<<root,ug>>,course>>; {c,co} <- <<<<<<root,ug>>,course>>,code>>; c_yg <- [generateGID 's1' c [co] 'course']]", 
								 null);
    Schema s1w=t1_23.getOtherSchema(s1v);
    SchemaObject syg_course=t1_23.getSchemaObject(s1w);

    // EXTEND sequence: course node comes after result node
    Transformation t1_24 = Transformation.createExtendTransformation(s1w, sequence,
								  new Object[] {"",syg_result,syg_course},
								  "[{re,c} | {r,re} <- <<root,result>>; {r,c} <- <<root,course>>]",
								  null);
    Schema s1x=t1_24.getOtherSchema(s1w);


    // EXTEND "code" node
    Transformation t1_25 = Transformation.createExtendTransformation(s1x, yattanode, 
								 new Object[] {syg_course,"code","string","k"},
								 "[{c_yg,co} | {c,co} <- <<<<<<root,ug>>,course>>,code>>; c_yg <- [generateGID 's1' c [co] 'course']]", 
								 null);
    Schema s1y=t1_25.getOtherSchema(s1x);
    SchemaObject syg_course_code=t1_25.getSchemaObject(s1y);

    // EXTEND "dept" node
    Transformation t1_26 = Transformation.createExtendTransformation(s1y, yattanode, 
								 new Object[] {syg_course,"dept","string",""},
								 "[{c_yg,d} | {c,co} <- <<<<<<root,ug>>,course>>,code>>; {c,d} <- <<<<<<root,ug>>,course>>,dept>>; c_yg <- [generateGID 's1' c [co] 'course']]", 
								 null);
    Schema s1z=t1_26.getOtherSchema(s1y);
    SchemaObject syg_course_dept=t1_26.getSchemaObject(s1z);


    // EXTEND sequence: course node comes after result node
    Transformation t1_27 = Transformation.createExtendTransformation(s1z, sequence,
								  new Object[] {"",syg_course_code,syg_course_dept},
								  "[{c,d} | {c,co} <- <<<<root,course>>,code>>; {c,d} <- <<<<root,course>>,dept>>]",
								  null);
    Schema s1aa=t1_27.getOtherSchema(s1z);


    // SHRINKING Phrase
    // CONTRACT sequence: year-grade
    Transformation t1_28 = Transformation.createContractTransformation(s1aa, s1_seq_year_grade,
								       "[{y,g} | {re,g} <- <<<<root,result>>,grade>>; {re,y} <- <<<<root,result>>,year>>]", 
								       null);
    Schema s1bb=t1_28.getOtherSchema(s1aa);

    // CONTRACT sequence: dept-year
    Transformation t1_29 = Transformation.createContractTransformation(s1bb, s1_seq_dept_year,
								       "[{d,y} | {re,d} <- <<<<root,result>>,dept>>; {re,y} <- <<<<root,result>>,year>>]", 
								       null);
    Schema s1cc=t1_29.getOtherSchema(s1bb);

    // CONTRACT sequence: code-dept
    Transformation t1_30 = Transformation.createContractTransformation(s1cc, s1_seq_code_dept,
								       "[{co,d} | {re,co} <- <<<<root,result>>,code>>; {c_yg,co} <- <<<<root,course>>,code>>; {c_yg,d} <- <<<<root,course>>,dept>>]", 
								       null);
    Schema s1dd=t1_30.getOtherSchema(s1cc);

    // CONTRACT sequence: ppt-course
    Transformation t1_31 = Transformation.createContractTransformation(s1dd, s1_seq_ppt_course,
								       "[{p,c} | {r,re} <- <<root,result>>; {re,co} <- <<<<root,result>>,code>>; {re,n} <- <<<<root,result>>,name>>; {u,n} <- <<<<root,ug>>,name>>; {u,p} <- <<<<root,ug>>,ppt>>; c <- [generateSID 's1' [n,co] 'result']]", 
								       null);
    Schema s1ee=t1_31.getOtherSchema(s1dd);

    // CONTRACT "grade" node <<root.student.course,grade>>
    Transformation t1_32 = Transformation.createContractTransformation(s1ee, s1_grade, 
								       "[{c,g} | {re,co} <- <<<<root,result>>,code>>; {re,n} <- <<<<root,result>>,name>>; {re,g} <- <<<<root,result>>,grade>>; c <- [generateSID 's1' [n,co] 'result']]", 
								       null);
    Schema s1ff=t1_32.getOtherSchema(s1ee);

    // CONTRACT "year" node <<root.student.course,year>>
    Transformation t1_33 = Transformation.createContractTransformation(s1ff, s1_year, 
								       "[{c,y} | {re,co} <- <<<<root,result>>,code>>; {re,n} <- <<<<root,result>>,name>>; {re,y} <- <<<<root,result>>,year>>; c <- [generateSID 's1' [n,co] 'result']]", 
								       null);
    Schema s1gg=t1_33.getOtherSchema(s1ff);

    // CONTRACT "dept" node <<root.student.course,dept>>
    Transformation t1_34 = Transformation.createContractTransformation(s1gg, s1_dept, 
								       "[{c,d} | {re,co} <- <<<<root,result>>,code>>; {re,n} <- <<<<root,result>>,name>>; {c_yg,co} <- <<<<root,course>>,code>>; {c_yg,d} <- <<<<root,course>>,dept>>; c <- [generateSID 's1' [n,co] 'result']]", 
								       null);
    Schema s1hh=t1_34.getOtherSchema(s1gg);

    // CONTRACT "code" node <<root.student.course,code>>
    Transformation t1_35 = Transformation.createContractTransformation(s1hh, s1_code, 
								       "[{c,co} | {re,co} <- <<<<root,result>>,code>>; {re,n} <- <<<<root,result>>,name>>; c <- [generateSID 's1' [n,co] 'result']]", 
								       null);
    Schema s1ii=t1_35.getOtherSchema(s1hh);

    // CONTRACT "course" node <<root.student,course>>
    Transformation t1_36 = Transformation.createContractTransformation(s1ii, s1_course, 
								       "[{u,c} | {r,re} <- <<root,result>>; {re,co} <- <<<<root,result>>,code>>; {re,n} <- <<<<root,result>>,name>>; {u,n} <- <<<<root,ug>>,name>>; c <- [generateSID 's1' [n,co] 'result']]", 
								       null);
    Schema s1jj=t1_36.getOtherSchema(s1ii);

    return(s1jj);

  }

  public static Schema transformS2ToSyg(Schema s2) 
    throws NotFoundException, TypeMismatchException {
    Model yatta=Model.getModel("yatta");
    Construct rootnode=yatta.getConstruct("rootnode");
    Construct yattanode=yatta.getConstruct("yattanode");
    Construct sequence=yatta.getConstruct("sequence");

    // Retrieve the objects of the schema
    SchemaObject s2_root=s2.getSchemaObject("<<root>>");
    SchemaObject s2_course=s2.getSchemaObject("<<root,course>>");
    SchemaObject s2_code=s2.getSchemaObject("<<<<root,course>>,code>>");
    SchemaObject s2_dept=s2.getSchemaObject("<<<<root,course>>,dept>>");

    //********************************************//
    // Start the transformation steps S2 -> Syg    //
    //********************************************//

    //Growing Phrase

    // Extend "ug" node
    Transformation t2_1 = Transformation.createExtendTransformation(s2, yattanode, 
								    new Object[] {s2_root,"ug","set","+"},
								    null,null);
    Schema s2a=t2_1.getOtherSchema(s2);
    SchemaObject syg_ug=t2_1.getSchemaObject(s2a);

    // Extend "name" node
    Transformation t2_2 = Transformation.createExtendTransformation(s2a, yattanode, 
								    new Object[] {syg_ug,"name","string","k"},
								    null,null);
    Schema s2b=t2_2.getOtherSchema(s2a);
    SchemaObject syg_ug_name=t2_2.getSchemaObject(s2b);
    

    // Extend "ppt" node
    Transformation t2_3 = Transformation.createExtendTransformation(s2b, yattanode, 
								    new Object[] {syg_ug,"ppt","string",""},
								    null,null);
    Schema s2c=t2_3.getOtherSchema(s2b);
    SchemaObject syg_ug_ppt=t2_3.getSchemaObject(s2c);

    // EXTEND sequence: name-ppt
    Transformation t2_4 = Transformation.createExtendTransformation(s2c, sequence,
								  new Object[] {"",syg_ug_name,syg_ug_ppt},
								  "[{n,p} | {u,name} <- <<<<root,ug>>,name>>; {u,ppt} <- <<<<root,u>>,ppt>>]",
								  null);
    Schema s2d=t2_4.getOtherSchema(s2c);


    // Add "pg" node
    Transformation t2_5 = Transformation.createAddTransformation(s2d, yattanode, 
								 new Object[] {s2_root,"pg","set","+"},
								 "[{rr,ppg} | {rr,cc} <- <<root,course>>; {cc,ss} <- <<<<root,course>>,student>>; {ss,nn} <- <<<<<<root,course>>,student>>,name>>; ppg <- [generateGID 's2' ss [nn] 'pg']]",   
								 null);
    Schema s2e=t2_5.getOtherSchema(s2d);
    SchemaObject syg_pg=t2_5.getSchemaObject(s2e);

    // EXTEND sequence: ug-pg
    Transformation t2_6 = Transformation.createExtendTransformation(s2e, sequence,
								  new Object[] {"",syg_ug,syg_pg},
								  "[{ug,pg} | {r,ug} <- <<root,ug>>; {r,pg} <- <<root,pg>>]",
								  null);
    Schema s2f=t2_6.getOtherSchema(s2e);

    
    // Add "name" node
    Transformation t2_7 = Transformation.createAddTransformation(s2f, yattanode, 
								 new Object[] {syg_pg,"name","string","k"},
								 "[{ppg,nn} | {rr,cc} <- <<root,course>>; {cc,ss} <- <<<<root,course>>,student>>; {ss,nn} <- <<<<<<root,course>>,student>>,name>>; ppg <- [generateGID 's2' ss [nn] 'pg']]",   
								 null);
    Schema s2g=t2_7.getOtherSchema(s2f);

    // Extend "student" node
    Transformation t2_8 = Transformation.createExtendTransformation(s2g, yattanode, 
								    new Object[] {s2_root,"student","set","+"},
								    "[{rr,rs} | {rr,cc} <- <<root,course>>; {cc,ss} <- <<<<root,course>>,student>>; {ss,nn} <- <<<<<<root,course>>,student>>,name>>; rs <- [generateGID 's2' ss [nn] 'student']]", 
								    null);
    Schema s2h=t2_8.getOtherSchema(s2g);
    SchemaObject syg_student=t2_8.getSchemaObject(s2h);

    // EXTEND sequence: pg-student
    Transformation t2_9 = Transformation.createExtendTransformation(s2h, sequence,
								  new Object[] {"",syg_pg,syg_student},
								  "[{pg,s} | {r,pg} <- <<root,pg>>; {r,s} <- <<root,student>>]",
								  null);
    Schema s2i=t2_9.getOtherSchema(s2h);

    // Extend "name" node
    Transformation t2_10 = Transformation.createExtendTransformation(s2i, yattanode,
								    new Object[] {syg_student,"name","string","k"},
								    "[{rs,nn} | {rr,cc} <- <<root,course>>; {cc,ss} <- <<<<root,course>>,student>>; {ss,nn} <- <<<<<<root,course>>,student>>,name>>; rs <- [generateGID 's2' ss [nn] 'student']]",  
								    null);
    Schema s2j=t2_10.getOtherSchema(s2i);
    SchemaObject syg_student_name=t2_10.getSchemaObject(s2j);

    // Extend "tutor" node
    Transformation t2_11 = Transformation.createExtendTransformation(s2j, yattanode,
								    new Object[] {syg_student,"tutor","string",""},
								    "[{rs,tt} | {rr,cc} <- <<root,course>>; {cc,ss} <- <<<<root,course>>,student>>; {ss,nn} <- <<<<<<root,course>>,student>>,name>>; {ss,tt} <- <<<<<<root,course>>,student>>,tutor>>; rs <- [generateGID 's2' ss [nn] 'student']]", 
								    null);
    Schema s2k=t2_11.getOtherSchema(s2j);
    SchemaObject syg_student_tutor=t2_11.getSchemaObject(s2k);

    // EXTEND sequence: name-tutor
    Transformation t2_12 = Transformation.createExtendTransformation(s2k, sequence,
								  new Object[] {"",syg_student_name,syg_student_tutor},
								  "[{n,t} | {s,n} <- <<<<root,student>>,name>>; {s,t} <- <<<<root,student>>,tutor>>]",
								  null);
    Schema s2l=t2_12.getOtherSchema(s2k);


    // Extend "result" node								 
    Transformation t2_13 = Transformation.createExtendTransformation(s2l, yattanode,
								    new Object[] {s2_root,"result","set","+"},
								    "[{rr,rre} | {rr,cc} <- <<root,course>>; {cc,ss} <- <<<<root,course>>,student>>; {ss,nn} <- <<<<<<root,course>>,student>>,name>>; {cc,cco} <- <<<<root,course>>,code>>; rre <- [generateGID 's2' ss [nn,cco] 'result']]", 
								 null); 		
    Schema s2m=t2_13.getOtherSchema(s2l);
    SchemaObject syg_result=t2_13.getSchemaObject(s2m);

    // EXTEND sequence: student-result
    Transformation t2_14 = Transformation.createExtendTransformation(s2m, sequence,
								  new Object[] {"",syg_student,syg_result},
								  "[{s,re} | {r,s} <- <<root,student>>; {r,re} <- <<root,result>>]",
								  null);
    Schema s2n=t2_14.getOtherSchema(s2m);

    // Extend "code" node
    Transformation t2_15 = Transformation.createExtendTransformation(s2n, yattanode,
								  new Object[] {syg_result,"code","string","k"},
								  "[{rre,cco} | {rr,cc} <- <<root,course>>; {cc,ss} <- <<<<root,course>>,student>>; {ss,nn} <- <<<<<<root,course>>,student>>,name>>; {cc,cco} <- <<<<root,course>>,code>>; rre <- [generateGID 's2' ss [nn,cco] 'result']]", 
								 null);
    Schema s2o=t2_15.getOtherSchema(s2n);
    SchemaObject syg_result_code=t2_15.getSchemaObject(s2o);

    // Extend "name" node
    Transformation t2_16 = Transformation.createExtendTransformation(s2o, yattanode,
								  new Object[] {syg_result,"name","string","k"},
								  "[{rre,nn} | {rr,cc} <- <<root,course>>; {cc,ss} <- <<<<root,course>>,student>>; {ss,nn} <- <<<<<<root,course>>,student>>,name>>; {cc,cco} <- <<<<root,course>>,code>>; rre <- [generateGID 's2' ss [nn,cco] 'result']]", 
								 null);
    Schema s2p=t2_16.getOtherSchema(s2o);
    SchemaObject syg_result_name=t2_16.getSchemaObject(s2p);


    // EXTEND sequence: code-name
    Transformation t2_17 = Transformation.createExtendTransformation(s2p, sequence,
								  new Object[] {"",syg_result_code,syg_result_name},
								  "[{co,n} | {re,co} <- <<<<root,result>>,code>>; {re,n} <- <<<<root,result>>,name>>]",
								  null);
    Schema s2q=t2_17.getOtherSchema(s2p);


    // Extend "year" node
    Transformation t2_18 = Transformation.createExtendTransformation(s2q, yattanode,
								     new Object[] {syg_result,"year","integer",""},
								     "[{rre,yy} | {rr,cc} <- <<root,course>>; {cc,ss} <- <<<<root,course>>,student>>; {ss,nn} <- <<<<<<root,course>>,student>>,name>>; {ss,yy} <- <<<<<<root,course>>,student>>,year>>; {cc,cco} <- <<<<root,course>>,code>>; rre <- [generateGID 's2' ss [nn,cco] 'result']]", 
								     null); 
    Schema s2r=t2_18.getOtherSchema(s2q);
    SchemaObject syg_result_year=t2_18.getSchemaObject(s2r);

    // EXTEND sequence: name-year
    Transformation t2_19 = Transformation.createExtendTransformation(s2r, sequence,
								  new Object[] {"",syg_result_name,syg_result_year},
								  "[{n,y} | {re,n} <- <<<<root,result>>,name>>; {re,y} <- <<<<root,result>>,year>>]",
								  null);
    Schema s2s=t2_19.getOtherSchema(s2r);


    // Extend "grade" node
    Transformation t2_20 = Transformation.createExtendTransformation(s2s, yattanode,
								     new Object[] {syg_result,"grade","string","?"},
								     "[{rre,gg} | {rr,cc} <- <<root,course>>; {cc,ss} <- <<<<root,course>>,student>>; {ss,nn} <- <<<<<<root,course>>,student>>,name>>; {ss,gg} <- <<<<<<root,course>>,student>>,grade>>; {cc,cco} <- <<<<root,course>>,code>>; rre <- [generateGID 's2' ss [nn,cco] 'result']]", 
								     null); 

    Schema s2t=t2_20.getOtherSchema(s2s);
    SchemaObject syg_result_grade=t2_20.getSchemaObject(s2t);

    // EXTEND sequence: name-year
    Transformation t2_21 = Transformation.createExtendTransformation(s2t, sequence,
								  new Object[] {"",syg_result_year,syg_result_grade},
								  "[{y,g} | {re,y} <- <<<<root,result>>,year>>; {re,g} <- <<<<root,result>>,grade>>]",
								  null);
    Schema s2u=t2_21.getOtherSchema(s2t);


    // EXTEND sequence: result-course
    Transformation t2_22 = Transformation.createExtendTransformation(s2u, sequence,
								  new Object[] {"",syg_result,s2_course},
								  "[{re,c} | {r,re} <- <<root,result>>; {r,c} <- <<root,course>>]",
								  null);
    Schema s2v=t2_22.getOtherSchema(s2u);


    //Shrinking Phrase
    SchemaObject s2_student=s2v.getSchemaObject("<<<<root,course>>,student>>");
    SchemaObject s2_name=s2v.getSchemaObject("<<<<<<root,course>>,student>>,name>>");
    SchemaObject s2_tutor=s2v.getSchemaObject("<<<<<<root,course>>,student>>,tutor>>");
    SchemaObject s2_year=s2v.getSchemaObject("<<<<<<root,course>>,student>>,year>>");
    SchemaObject s2_grade=s2v.getSchemaObject("<<<<<<root,course>>,student>>,grade>>");
    SchemaObject s2_seq_dept_student=s2v.getSchemaObject("<<_,<<<<root,course>>,dept>>,<<<<root,course>>,student>>>>");
    SchemaObject s2_seq_name_tutor=s2v.getSchemaObject("<<_,<<<<<<root,course>>,student>>,name>>,<<<<<<root,course>>,student>>,tutor>>>>");
    SchemaObject s2_seq_tutor_year=s2v.getSchemaObject("<<_,<<<<<<root,course>>,student>>,tutor>>,<<<<<<root,course>>,student>>,year>>>>");
    SchemaObject s2_seq_year_grade=s2v.getSchemaObject("<<_,<<<<<<root,course>>,student>>,year>>,<<<<<<root,course>>,student>>,grade>>>>");

    // CONTRACT sequence: dept-student
    Transformation t2_23 = Transformation.createContractTransformation(s2v, s2_seq_dept_student,
								       "[{dd,ss} | {rr,rre} <- <<root,result>>; {rre,cco} <- <<<<root,result>>,code>>; {rre,nn} <- <<<<root,result>>,name>>; {rr,cc} <- <<root,course>>; {cc,cco} <- <<<<root,course>>,code>>; {cc,dd} <- <<<<root,course>>,dept>>; ss <- [generateSID 's2' [nn,cco] 'result']]",
								       null);
    Schema s2w=t2_23.getOtherSchema(s2v);

    // CONTRACT sequence: name-tutor
    Transformation t2_24 = Transformation.createContractTransformation(s2w, s2_seq_name_tutor,
								       "[{nn,tt} | {rre,nn} <- <<<<root,result>>,name>>; {ss,nn} <- <<<<root,student>>,name>>; {ss,tt} <- <<<<root,student>>,tutor>>]",
								       null);
    Schema s2x=t2_24.getOtherSchema(s2w);

    // CONTRACT sequence: tutor-year
    Transformation t2_25 = Transformation.createContractTransformation(s2x, s2_seq_tutor_year,
								       "[{tt,yy} | {rre,nn} <- <<<<root,result>>,name>>; {rre,yy} <- <<<<root,result>>,year>>; {ss,nn} <- <<<<root,student>>,name>>; {ss,tt} <- <<<<root,student>>,tutor>>]",
								       null);
    Schema s2y=t2_25.getOtherSchema(s2x);

    // CONTRACT sequence: year-grade
    Transformation t2_26 = Transformation.createContractTransformation(s2y, s2_seq_year_grade,
								       "[{yy,gg} | {rre,nn} <- <<<<root,result>>,name>>; {rre,yy} <- <<<<root,result>>,year>>; {rre,gg} <- <<<<root,result>>,grade>>; {ss,nn} <- <<<<root,student>>,name>>]",
								       null);
    Schema s2z=t2_26.getOtherSchema(s2y);

    // Contract "grade" node
    Transformation t2_27 = Transformation.createContractTransformation(s2z, s2_grade,
								       "[{ss,gg} | {rre,gg} <- <<<<root,result>>,grade>>; {rre,nn} <- <<<<root,result>>,name>>; {rre,cco} <- <<<<root,result>>,code>>; ss <- [generateSID 's2' [nn,cco] 'result']]",
								       null);
    Schema s2aa=t2_27.getOtherSchema(s2z);

    // Contract "year" node
    Transformation t2_28 = Transformation.createContractTransformation(s2aa, s2_year,
								       "[{ss,yy} | {rre,yy} <- <<<<root,result>>,year>>; {rre,nn} <- <<<<root,result>>,name>>; {rre,cco} <- <<<<root,result>>,code>>; ss <- [generateSID 's2' [nn,cco] 'result']]",
								       null);
    Schema s2bb=t2_28.getOtherSchema(s2aa);

    // Contract "tutor" node
    Transformation t2_29 = Transformation.createContractTransformation(s2bb, s2_tutor,
								       "[{sss,tt} | {rre,nn} <- <<<<root,result>>,name>>; {rre,cco} <- <<<<root,result>>,code>>; {ss,nn} <- <<<<root,student>>,name>>; {ss,tt} <- <<<<root,student>>,tutor>>; sss <- [generateSID 's2' [nn,cco] 'result']]",
								       null);
    Schema s2cc=t2_29.getOtherSchema(s2bb);

    // Contract "name" node
    Transformation t2_30 = Transformation.createDeleteTransformation(s2cc, s2_name,
								     "[{ss,nn} | {rre,nn} <- <<<<root,result>>,name>>; {rre,cco} <- <<<<root,result>>,code>>; ss <- [generateSID 's2' [nn,cco] 'result']]",
								     null);
    Schema s2dd=t2_30.getOtherSchema(s2cc);

    // Contract "student" node
    Transformation t2_31 = Transformation.createContractTransformation(s2dd, s2_student, 
								    "[{cc,ss} | {rr,rre} <- <<root,result>>; {rre,cco} <- <<<<root,result>>,code>>; {rre,nn} <- <<<<root,result>>,name>>; ss <- [generateSID 's2' [nn,cco] 'result']; cc <- [generateSID 's2' [nn,cco] 'result']]",
								     null);
    Schema s2ee=t2_31.getOtherSchema(s2dd);

    return (s2ee);
  }

    public static Schema transformSygToSrg(Schema syg) 
      throws NotFoundException, TypeMismatchException {
      Model yatta=Model.getModel("yatta");
      Construct rootnode=yatta.getConstruct("rootnode");
      Construct yattanode=yatta.getConstruct("yattanode");
      
      SQLWrapperFactory swf=new SQLWrapperFactory();
      try {
	  swf.setFeatures(22);
      }
      catch (Exception e) {
	  System.out.println("Unable to set features");
	  System.exit(0);
      }
      Model sql2=swf.getAutoMedModel();
      Construct table=sql2.getConstruct("table");
      Construct column=sql2.getConstruct("column");
      Construct primary_key=sql2.getConstruct("primary_key");


      // Retrieve the objects of the schema
    SchemaObject syg_root=syg.getSchemaObject("<<root>>");

    SchemaObject syg_ug=syg.getSchemaObject("<<root,ug>>");
    SchemaObject syg_ug_name=syg.getSchemaObject("<<<<root,ug>>,name>>");
    SchemaObject syg_ppt=syg.getSchemaObject("<<<<root,ug>>,ppt>>");
    SchemaObject syg_seq_name_ppt=syg.getSchemaObject("<<_,<<<<root,ug>>,name>>,<<<<root,ug>>,ppt>>>>");

    SchemaObject syg_pg=syg.getSchemaObject("<<root,pg>>");
    SchemaObject syg_pg_name=syg.getSchemaObject("<<<<root,pg>>,name>>");

    SchemaObject syg_student=syg.getSchemaObject("<<root,student>>");
    SchemaObject syg_student_name=syg.getSchemaObject("<<<<root,student>>,name>>");
    SchemaObject syg_tutor=syg.getSchemaObject("<<<<root,student>>,tutor>>");
    SchemaObject syg_seq_name_tutor=syg.getSchemaObject("<<_,<<<<root,student>>,name>>,<<<<root,student>>,tutor>>>>");

    SchemaObject syg_course=syg.getSchemaObject("<<root,course>>");
    SchemaObject syg_course_code=syg.getSchemaObject("<<<<root,course>>,code>>");
    SchemaObject syg_dept=syg.getSchemaObject("<<<<root,course>>,dept>>");
    SchemaObject syg_seq_code_dept=syg.getSchemaObject("<<_,<<<<root,course>>,code>>,<<<<root,course>>,dept>>>>");

    SchemaObject syg_result=syg.getSchemaObject("<<root,result>>");
    SchemaObject syg_result_code=syg.getSchemaObject("<<<<root,result>>,code>>");
    SchemaObject syg_result_name=syg.getSchemaObject("<<<<root,result>>,name>>");
    SchemaObject syg_year=syg.getSchemaObject("<<<<root,result>>,year>>");
    SchemaObject syg_grade=syg.getSchemaObject("<<<<root,result>>,grade>>");
    SchemaObject syg_seq_code_name=syg.getSchemaObject("<<_,<<<<root,result>>,code>>,<<<<root,result>>,name>>>>");
    SchemaObject syg_seq_name_year=syg.getSchemaObject("<<_,<<<<root,result>>,name>>,<<<<root,result>>,year>>>>");
    SchemaObject syg_seq_year_grade=syg.getSchemaObject("<<_,<<<<root,result>>,year>>,<<<<root,result>>,grade>>>>");

    SchemaObject syg_seq_ug_pg=syg.getSchemaObject("<<_,<<root,ug>>,<<root,pg>>>>");
    SchemaObject syg_seq_pg_student=syg.getSchemaObject("<<_,<<root,pg>>,<<root,student>>>>");
    SchemaObject syg_seq_student_result=syg.getSchemaObject("<<_,<<root,student>>,<<root,result>>>>");
    SchemaObject syg_seq_result_course=syg.getSchemaObject("<<_,<<root,result>>,<<root,course>>>>");

    //********************************************//
    // Start the transformation steps Syg -> Srg    //
    //********************************************//

    //Growing Phrase
    
    // ADD "student" table
    Transformation t1 = Transformation.createAddTransformation(syg, table, 
							       new Object[] {"student"},
							       "[{rn} | {rs,rn} <- <<<<root,student>>,name>>]", 
							       null);
    Schema syg_a=t1.getOtherSchema(syg);
    SchemaObject srg_student=t1.getSchemaObject(syg_a);

    // ADD "name" column
    Transformation t2 = Transformation.createAddTransformation(syg_a, column, 
							       new Object[] {srg_student,"name","varchar"},
							       "[{rn,rn} | {rs,rn} <- <<<<root,student>>,name>>]",         
							       null);
    Schema syg_b=t2.getOtherSchema(syg_a);
    SchemaObject srg_name=t2.getSchemaObject(syg_b);

    // ADD "tutor" column
    Transformation t3 = Transformation.createAddTransformation(syg_b, column, 
							       new Object[] {srg_student,"tutor","varchar"},
							       "[{rn,rt} | {rs,rn} <- <<<<root,student>>,name>>; {rs,rt} <- <<<<root,student>>,tutor>>]",
							       null);
    Schema syg_c=t3.getOtherSchema(syg_b);

    // ADD primary key for "student" table
    Transformation t4 = Transformation.createAddTransformation(syg_c, primary_key, new Object[]{"student_pk", srg_student, srg_name},null,null);
    
    Schema syg_d=t4.getOtherSchema(syg_c);
    
    // ADD "ug" table
    Transformation t5 = Transformation.createAddTransformation(syg_d, table, 
							       new Object[] {"ug"},
							       "[{rn} | {rug,rn} <- <<<<root,ug>>,name>>]", 
							       null);
    Schema syg_e=t5.getOtherSchema(syg_d);
    SchemaObject srg_ug=t5.getSchemaObject(syg_e);

    // ADD "name" column
    Transformation t6 = Transformation.createAddTransformation(syg_e, column, 
							       new Object[] {srg_ug,"name","varchar"},
							       "[{rn,rn} | {rug,rn} <- <<<<root,ug>>,name>>]", 
							       null);
    Schema syg_f=t6.getOtherSchema(syg_e);
    SchemaObject srg_ug_name=t6.getSchemaObject(syg_f);

    // ADD "ppt" column
    Transformation t7 = Transformation.createAddTransformation(syg_f, column, 
							       new Object[] {srg_ug,"ppt","varchar"},
							       "[{rn,rp} | {rug1,rn} <- <<<<root,ug>>,name>>; {rug2,rp} <- <<<<root,ug>>,ppt>>; (=) rug1 rug2]", 
							       null);
    Schema syg_g=t7.getOtherSchema(syg_f);

    // ADD primary key for "ug" table
    Transformation t8 = Transformation.createAddTransformation(syg_g, primary_key, new Object[]{"ug_pk", srg_ug, srg_ug_name},null,null);
    
    Schema syg_h=t8.getOtherSchema(syg_g);

    // ADD "pg" table
    Transformation t9 = Transformation.createAddTransformation(syg_h, table, 
							       new Object[] {"pg"},
							       "[{rn} | {rpg,rn} <- <<<<root,pg>>,name>>]", 
							       null);
    Schema syg_i=t9.getOtherSchema(syg_h);
    SchemaObject srg_pg=t9.getSchemaObject(syg_i);

    // ADD "name" column
    Transformation t10 = Transformation.createAddTransformation(syg_i, column, 
							       new Object[] {srg_pg,"name","varchar"},
							       "[{rn,rn} | {rpg,rn} <- <<<<root,pg>>,name>>]", 
							       null);
    Schema syg_j=t10.getOtherSchema(syg_i);
    SchemaObject srg_pg_name=t10.getSchemaObject(syg_j);

    // ADD primary key for "pg" table
    Transformation t11 = Transformation.createAddTransformation(syg_j, primary_key, new Object[]{"pg_pk", srg_pg, srg_pg_name},null,null);
    
    Schema syg_k=t11.getOtherSchema(syg_j);

    // ADD "result" table
    Transformation t12 = Transformation.createAddTransformation(syg_k, table, 
								new Object[] {"result"},
								 "[{rco,rn} | {rre,rco} <- <<<<root,result>>,code>>; {rre,rn} <- <<<<root,result>>,name>>]", 
								 null);
    Schema syg_l=t12.getOtherSchema(syg_k);
    SchemaObject srg_result=t12.getSchemaObject(syg_l);


    //ADD "code" column
    Transformation t13 = Transformation.createAddTransformation(syg_l, column,
								 new Object[] {srg_result,"code","varchar"},
								 "[{rco,rn,rco} | {rre,rco} <- <<<<root,result>>,code>>; {rre,rn} <- <<<<root,result>>,name>>]", 
								 null);
    Schema syg_m=t13.getOtherSchema(syg_l);
    SchemaObject srg_result_code=t13.getSchemaObject(syg_m);

    //ADD "name" column
    Transformation t14 = Transformation.createAddTransformation(syg_m, column,
								 new Object[] {srg_result,"name","varchar"},
								"[{rco,rn,rn} | {rre1,rco} <- <<<<root,result>>,code>>; {rre2,rn} <- <<<<root,result>>,name>>; (=) rre1 rre2]",
								 null);
    Schema syg_n=t14.getOtherSchema(syg_m);
    SchemaObject srg_result_name=t14.getSchemaObject(syg_n);

    //ADD "year" column
    Transformation t15 = Transformation.createAddTransformation(syg_n, column,
								 new Object[] {srg_result,"year","varchar"},
								 "[{rco,rn,ry} | {rre,rco} <- <<<<root,result>>,code>>; {rre,rn} <- <<<<root,result>>,name>>; {rre,ry} <- <<<<root,result>>,year>>]",
								 null);
    Schema syg_o=t15.getOtherSchema(syg_n);


    //ADD "grade" field
    Transformation t16 = Transformation.createAddTransformation(syg_o, column,
								 new Object[] {srg_result,"grade","varchar"},
								 "[{rco,rn,rg} | {rre,rco} <- <<<<root,result>>,code>>; {rre,rn} <- <<<<root,result>>,name>>; {rre,rg} <- <<<<root,result>>,grade>>]", 
								 null);
    Schema syg_p=t16.getOtherSchema(syg_o);

    //ADD primary key for "result" table
    Transformation t17 = Transformation.createAddTransformation(syg_p, primary_key, new Object[]{"result_pk", srg_result, srg_result_code, srg_result_name},null,null);
    
    Schema syg_q=t17.getOtherSchema(syg_p);

    // ADD "course" table
    Transformation t18 = Transformation.createAddTransformation(syg_q, table, 
								new Object[] {"course"},
								"[{rco} | {rc,rco} <- <<<<root,course>>,code>>]", 
								null);
    Schema syg_r=t18.getOtherSchema(syg_q);
    SchemaObject srg_course=t18.getSchemaObject(syg_r);

    //ADD "code" column
    Transformation t19 = Transformation.createAddTransformation(syg_r, column,
								 new Object[] {srg_course,"code","varchar"},
								 "[{rco,rco} | {rc,rco} <- <<<<root,course>>,code>>]", 
								 null);
    Schema syg_s=t19.getOtherSchema(syg_r);
    SchemaObject srg_course_code=t19.getSchemaObject(syg_s);

    //ADD "dept" column
    Transformation t20 = Transformation.createAddTransformation(syg_s, column,
								 new Object[] {srg_course,"dept","varchar"},
								 "[{rco,rd} | {rc,rco} <- <<<<root,course>>,code>>; {rc,rd} <- <<<<root,course>>,dept>>]", 
								 null);
    Schema syg_t=t20.getOtherSchema(syg_s);

    //ADD primary key for "course" table
    Transformation t21 = Transformation.createAddTransformation(syg_t, primary_key, new Object[]{"course_pk", srg_course, srg_course_code},null,null);
    
    Schema syg_u=t21.getOtherSchema(syg_t);

    //Shrinking Phrase
    //DELETE all sequences first
    //DELETE "<<_,<<<<root,ug>>,name>>,<<<<root,ug>>,ppt>>>>"
    Transformation t22 = Transformation.createDeleteTransformation(syg_u, syg_seq_name_ppt,
								   "[{rn,rp} | {rn,rp} <- <<ug,ppt>>]",
								   null);
    Schema syg_v=t22.getOtherSchema(syg_u);

    //DELELTE "<<_,<<<<root,student>>,name>>,<<<<root,student>>,tutor>>>>"
    Transformation t23 = Transformation.createDeleteTransformation(syg_v, syg_seq_name_tutor,
								   "[{rn,rt} | {rn,rt} <- <<student,tutor>>]",
								   null);
    Schema syg_x=t23.getOtherSchema(syg_v);


    //DELETE "<<_,<<<<root,course>>,code>>,<<<<root,course>>,dept>>>>"
    Transformation t24 = Transformation.createDeleteTransformation(syg_x, syg_seq_code_dept,
								   "[{rco,rd} | {rco,rd} <- <<course,dept>>]",
								   null);
    Schema syg_y=t24.getOtherSchema(syg_x);

    //DELETE  "<<_,<<<<root,result>>,code>>,<<<<root,result>>,name>>>>"
    Transformation t25 = Transformation.createDeleteTransformation(syg_y, syg_seq_code_name, 
								   "[{rco,rn} | {rco,rn} <- <<result>>]",
								   null);
    Schema syg_z=t25.getOtherSchema(syg_y);

    //DELETE   "<<_,<<<<root,result>>,name>>,<<<<root,result>>,year>>>>"
    Transformation t26 = Transformation.createDeleteTransformation(syg_z, syg_seq_name_year, 
								   "[{rn,ry} | {rco,rn,ry} <- <<result,year>>]",
								   null);
    Schema syg_za=t26.getOtherSchema(syg_z);

    //DELETE   "<<_,<<<<root,result>>,year>>,<<<<root,result>>,grade>>>>"
    Transformation t27 = Transformation.createDeleteTransformation(syg_za, syg_seq_year_grade,
								   "[{ry,rg} | {rco,rn,ry} <- <<result,year>>; {rco,rn,rg} <- <<result,grade>>]",
								   null);
    Schema syg_zb=t27.getOtherSchema(syg_za);

    //DELETE   "<<_,<<root,ug>>,<<root,pg>>>>"
    Transformation t28 = Transformation.createDeleteTransformation(syg_zb, syg_seq_ug_pg, 
								   "[{rug,rpg} | {rn1,rn1} <- <<pg,name>>; rpg <- [generateId [rr,rn1]]; {rn2,rn2} <- <<ug,name>>; rug <- [generateId [rr,rn2]]; {rr} <- <<root>>]",
								   null);
    Schema syg_zc=t28.getOtherSchema(syg_zb);

    //DELETE   "<<_,<<root,pg>>,<<root,student>>>>"
    Transformation t29 = Transformation.createDeleteTransformation(syg_zc, syg_seq_pg_student, 
								   "[{rpg,rs} | {rn1,rn1} <- <<pg,name>>; rpg <- [generateId [rr,rn1]]; {rn2,rn2} <- <<student,name>>; rs <- [generateId [rr,rn2]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zd=t29.getOtherSchema(syg_zc);

    //DELETE   "<<_,<<root,student>>,<<root,result>>>>"
    Transformation t30 = Transformation.createDeleteTransformation(syg_zd, syg_seq_student_result,
								     "[{rs,rre} | {rn1,rn1} <- <<student,name>>; rs <- [generateId [rr,rn1]]; {rco,rn} <- <<result>>; rre <- [generateId [rco,rn]]; {rr} <- <<root>>]",
								     null);
    Schema syg_ze=t30.getOtherSchema(syg_zd);

    //DELETE   "<<_,<<root,result>>,<<root,course>>>>"
    Transformation t31 = Transformation.createDeleteTransformation(syg_ze, syg_seq_result_course,
								     "[{rre,rc} | {rco1,rn} <- <<result>>; rre <- [generateId [rco1,rn]]; {rco,rco} <- <<course,code>>; rc <- [generateId [rr,rco]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zf=t31.getOtherSchema(syg_ze);


    //DELETE "grade" node
    Transformation t32 = Transformation.createDeleteTransformation(syg_zf, syg_grade,
								   "[{rre,rg} | {rco,rn,rg} <- <<result,grade>>; rre <- [generategid [rn,rco]]]",
								   null);
    Schema syg_zg=t32.getOtherSchema(syg_zf);

    //DELETE "year" node
    Transformation t33 = Transformation.createDeleteTransformation(syg_zg, syg_year,
								   "[{rre,ry} | {rco,rn,ry} <- <<result,year>>; rre <- [generateId [rco,rn]]]",
								   null);
    Schema syg_zh=t33.getOtherSchema(syg_zg);

    //DELETE "name" node
    Transformation t34 = Transformation.createDeleteTransformation(syg_zh, syg_result_name,
								   "[{rre,rn} | {rco,rn} <- <<result>>; rre <- [generateId [rco,rn]]]",
								   null);
    Schema syg_zi=t34.getOtherSchema(syg_zh);

    //DELETE "code" node
    Transformation t35 = Transformation.createDeleteTransformation(syg_zi, syg_result_code, 
								   "[{rre,rco} | {rco,rn} <- <<result>>; rre <- [generateId [rco,rn]]]",
								   null);
    Schema syg_zj=t35.getOtherSchema(syg_zi);

    //DELETE "result" node
    Transformation t36 = Transformation.createDeleteTransformation(syg_zj, syg_result, 
								   "[{rr,rre} | {rco,rn} <- <<result>>; rre <- [generateId [rco,rn]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zk=t36.getOtherSchema(syg_zj);

    //DELETE "dept" node
    Transformation t37 = Transformation.createDeleteTransformation(syg_zk, syg_dept, 
								   "[{rc,rd} | {rco,rd} <- <<course,dept>>; rc <- [generateId [rr,rco]]; {rr} <- <<root>>]",
								   null);
    Schema syg_zl=t37.getOtherSchema(syg_zk);

    //DELETE "code" node
    Transformation t38 = Transformation.createDeleteTransformation(syg_zl, syg_course_code, 
								   "[{rc,rco} | {rco,rco} <- <<course,code>>; rc <- [generateId [rr,rco]]; {rr}<- <<root>>]",
								   null);
    Schema syg_zm=t38.getOtherSchema(syg_zl);

    //DELETE "course" node
    Transformation t39 = Transformation.createDeleteTransformation(syg_zm, syg_course, 
								   "[{rr,rc} | {rco,rco} <- <<course,code>>; rc <- [generateId [rr,rco]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zn=t39.getOtherSchema(syg_zm);

    //DELETE "tutor" node
    Transformation t40 = Transformation.createDeleteTransformation(syg_zn, syg_tutor,
								     "[{rs,rt} | {rn,rt} <- <<student,tutor>>; rs <- [generateId [rr,rn]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zo=t40.getOtherSchema(syg_zn);

    //DELETE "name" node
    Transformation t41 = Transformation.createDeleteTransformation(syg_zo, syg_student_name,
								     "[{rs,rn} | {rn,rn} <- <<student,name>>; rs <- [generateId [rr,rn]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zp=t41.getOtherSchema(syg_zo);

    //DELETE "student" node
    Transformation t42 = Transformation.createDeleteTransformation(syg_zp, syg_student,
								     "[{rr,rs} | {rn,rn} <- <<student,name>>; rs <- [generateId [rr,rn]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zq=t42.getOtherSchema(syg_zp);

    //DELETE "name" node
    Transformation t43 = Transformation.createDeleteTransformation(syg_zq, syg_pg_name,
								     "[{rpg,rn} | {rn,rn} <- <<pg,name>>; rpg <- [generateId [rr,rn]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zr=t43.getOtherSchema(syg_zq);

    //DELETE "pg" node
    Transformation t44 = Transformation.createDeleteTransformation(syg_zr, syg_pg,
								     "[{rr,rpg} | {rn,rn} <- <<pg,name>>; rpg <- [generateId [rr,rn]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zs=t44.getOtherSchema(syg_zr);


    //DELETE "ppt" node
    Transformation t45 = Transformation.createDeleteTransformation(syg_zs, syg_ppt,
								     "[{rug,rp} | {rn,rp} <- <<ug,ppt>>; rug <- [generateId [rr,rn]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zt=t45.getOtherSchema(syg_zs);

    //DELETE "name" node
    Transformation t46 = Transformation.createDeleteTransformation(syg_zt, syg_ug_name,
								     "[{rug,rn} | {rn,rn} <- <<ug,name>>; rug <- [generateId [rr,rn]]; {rr} <- <<root>>]",
								     null);
    Schema syg_zu=t46.getOtherSchema(syg_zt);

    //DELETE "student" node
    Transformation t47 = Transformation.createDeleteTransformation(syg_zu, syg_ug,
								   "[{rr,rug} | {rn,rn} <- <<ug,name>>; rug <- [generateId [rr,rn]]; {rr} <- <<root>>]",
								   null);
    Schema syg_zv=t47.getOtherSchema(syg_zu);

    //DELETE "root" node
    Transformation t48 = Transformation.createDeleteTransformation(syg_zv, syg_root,
								     "[{rr} | (=) rr 0]",
								     null);
    Schema syg_zw=t48.getOtherSchema(syg_zv);


    return (syg_zw);
  }


  // This is a fairly standard check to see if two schemas can be
  // "integrated" via ID transformations
  public static void integrateSchemas(Schema s1,Schema s2)  
    throws AutoMedException {
      SchemaObject[] aLessB=s1.differenceByName(s2);
      SchemaObject[] bLessA=s2.differenceByName(s1);
      boolean integrationOK=true;

      if (aLessB.length>0) {
	System.out.println(s1.getName()+"-"+s2.getName()+"="+aLessB);
	integrationOK=false;
      }
	  
      if (bLessA.length>0) {
	System.out.println(s2.getName()+"-"+s1.getName()+"="+bLessA);
	integrationOK=false;
      }

      if (integrationOK) {	
	try {
	  Transformation.createIdentTransformation(s1,s2,null,null);
	  System.out.println("Integration of "+s1.getName()+" and "+
			     s2.getName()+" succeeded");
	}
	catch (SchemasNotIdenticalException e) {
	  System.out.println(e.toString());
	  e.printStackTrace(System.out);
	  System.out.println("================");
	  System.out.println("*** Schema " + e.getFromSchema().getName());
	  System.out.println(e.getFromSchema().getAllSchemeNamesString(true, -1, -1));
	  //	  s1.listSchema();
	  System.out.println("----------------");
	  System.out.println("*** Objects not matched");
	  SchemaObject[] fromSo = e.getFromObjectsUnmatched();
	  for (int i=0; i<fromSo.length; i++)
	    System.out.println(fromSo[i].getSchemeNamesString(-1, -1));
	  System.out.println("================");
	  System.out.println("*** Schema " + e.getToSchema().getName());
	  System.out.println(e.getToSchema().getAllSchemeNamesString(true, -1, -1));
	  //	  s2.listSchema();
	  System.out.println("----------------");
	  System.out.println("*** Objects not matched");
	  SchemaObject[] toSo = e.getToObjectsUnmatched();
	  for (int i=0; i<toSo.length; i++)
	    System.out.println(toSo[i].getSchemeNamesString(-1, -1));

	  System.out.println("================");
	}
	catch (Throwable t) {
	  System.out.println("================");
	  System.out.println("*** Schema " + s1.getName());
	  System.out.println(s1.getAllSchemeNamesString(true, -1, -1));
	  System.out.println("----------------");
	  System.out.println("*** Schema " + s2.getName());
	  System.out.println(s2.getAllSchemeNamesString(true, -1, -1));
	  System.out.println("================");
	  System.out.println(t.toString());
	  t.printStackTrace(System.out);
	}
      }
      else
	System.out.println("Integration failed, since it is "+
			   "only allowed if schemas identical");
  }

  public static void main(String[] args) {
    try {
      System.out.println("AutoMed Repository: Transformation and "+
			 "Integration of S1, S2 and S3");

      // level 5 prints all the old debug information, 0 makes it silent
      //STR.setDebugLevel(0);

      Schema s1=Schema.getSchema("sc_s1");
      Schema s2=Schema.getSchema("sc_s2");

      Schema syg1=transformS1ToSyg(s1);
      syg1.listSchema();
      Schema syg2=transformS2ToSyg(s2);
      syg2.listSchema();
      integrateSchemas(syg1,syg2);

      Schema srg=transformSygToSrg(syg1);
      srg.listSchema();

    }
    catch (AutoMedException ame) {
      ame.printStackTrace();
    }
    catch (Throwable t) {
      System.err.println(t.toString());
      t.printStackTrace();
    }
  }
}



