/*
   Tamot --- Task Modelling Editor
   Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
   (CSIRO), Australia. All rights reserved. 

   The Software, owned by CSIRO Australia, has been developed by the CSIRO 
   Intelligent Interactive Technology group. 
   For more information, please see http://www.cmis.csiro.au/iit/.

   The Software is a beta-test version for internal research and evaluation purposes 
   by the Licensee. The Software is still at a development stage. 
   It has not undergone complete testing and may have inherent errors,
   bugs or deficiencies that can affect the operation of the Software. 

   We encourage your feedback and suggestions. Any bugs / suggestions found please email to
   Shijian.Lu@cmis.csiro.au and Thomas.Lo@cmis.csiro.au. 

   After you have signed the Beta-Test Software License Agreement with the CSIRO,
   CSIRO grants you a non-exclusive, non-transferable license to use it only for your 
   personal, non-commercial and lawful end use. Implied licenses are negated. 

   Warranty Disclaimer : 

   CSIRO supplies the Software on an "as is" basis and makes no warranties that use of
   the Software by the Licensee will not infringe any third party’s 
   Intellectual Property Rights nor that the Software will be of merchantable quality,
   or suitable for a particular purpose. CSIRO excludes all terms, conditions and
   warranties implied by custom, the general law or statute in relation to the
   Software.
*/

package taskModellingTool;

import domainModel.*;

import java.util.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.print.*;
import javax.swing.*;
import java.lang.reflect.*;
import java.net.*;
import java.io.*;
import java.beans.*;
import utility.*;


/**
 * Manager provide an access to each function required by the GUI.
 */
public class Manager /*extends ManagerToolKit*/{

    //tape_recorder
    public static boolean guiEnableFlag = true;

    protected static AttributesPanel attributesPanel;
    protected static KernelTree skeleton;
    protected static FileManager fileManager;
    protected static DisplayManager displayManager;
    protected static OptionsManager optionsManager;
    protected static MainTree tree;
    protected static GraphicDesktop desktop;
    protected static GraphicToolBar graphicToolBar;
    protected static RTFDataBase RTFDB;
    protected static RTFManager RTFDBM;

    protected static RTFPane editor;
    
    private static XManager xDm =	new XManager(); // domain model manager 

    public static DomainModelManager dmManager;
    
    protected static JPopupMenu popup;
        
    protected static MainMenu menu;
    
    protected static GenericComponent currentComponent=null;
    
    protected static Couple clipboard=null;
    
    protected static boolean nodeSelectionVeto=true;
    
    
    protected static String ROOT_STRING;
    
    protected static String searchName="";
    protected static String searchParentName="";
    
    protected static int progressBarValue=0;    // used to pass progress bar vaule between threads
    
    // decide which attribute to include in the HTML report
    protected static TreeMap taskAttributesBool = new TreeMap();
    
    // contains all public fields of Task & their indexes
    protected static TreeMap filedsKey = new TreeMap();
    
    // contains all fields available in HTML Report Settings & their indexes
    protected static TreeMap filedsKeyForHTML = new TreeMap();  
        
    protected static int currentUnusedID = 1;

    protected static Cursor waitCursor = new Cursor(Cursor.WAIT_CURSOR);
	protected static Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
    
    protected static final boolean displayLinkInTreeEnableFlag = true;
    
    protected static SystemOptions systemOptions = new SystemOptions();
    
    //shijian 2001-4-17
    protected static SortArrayList _predecessorComponents = 
    	new SortArrayList (new GCCompare());
    protected static SortArrayList _successorComponents = 
    	new SortArrayList (new GCCompare());

    //tape_recorder
	public Manager(boolean guiEnableFlag) {
        this.guiEnableFlag = guiEnableFlag;
        
    	skeleton=new KernelTree(ROOT_STRING);
    	RTFDB=new RTFDataBase();
    	//shijian 25-9-2001
    	RTFDBM=new RTFManager();

    	//Static !
    	displayManager=new DisplayManager();
    	optionsManager=new OptionsManager();
    	dmManager=new DomainModelManager();
        
        if (guiEnableFlag) {
            tree=MainFrame.tree;
            editor=MainFrame.editor;
            attributesPanel=MainFrame.attributesPanel;
            desktop=MainFrame.desktop;
            graphicToolBar=MainFrame.graphicToolBar;
            menu=MainFrame.menu;
            popup=MainFrame.popup;
        }
        else {
            tree=TapeRecorder_MainFrame.tree;
        }
        
    	ROOT_STRING=MainTree.ROOT_STRING;
    	    	
        if (guiEnableFlag) {
            systemOptions.readFile();
            menu.setOptions();
        }
        
    	fileManager=new FileManager(guiEnableFlag);
    	
        if (guiEnableFlag) {
        	editor.reset();
        }
    	
    	tree.expandRow(0);
    	tree.setSelectionRow(0);
        
        if (guiEnableFlag) {
            openChildFrame(tree.getPathForRow(0));
            
            // to include all attribute in the html report by defualt 
            Task task= new Task();
            Field[] filds= task.getClass().getFields(); //getDeclaredFields(); 
            
            String fieldName;
            for(int i = 18; i < filds.length; i++) {
                fieldName = filds[i].getName();
                
                filedsKey.put(fieldName,new Integer(i));
                filedsKeyForHTML.put(fieldName,new Integer(i));
               
                // default settings for HTML report generation
                if (HTMLReportSettingDialog.checkIfIncludedInHTMLReportSettings(fieldName))
                    taskAttributesBool.put(fieldName,new Boolean(false));
            }
    
            HTMLReportSettingDialog.readHTMLReportSettings();
        }
    }
    
    //----------------------------------------------------------------
    //				I O
    //----------------------------------------------------------------
    public static void exportHTML() {
    	fileManager.exportHTML();
    }
    
    public static void exportHTMLfromXSL() {
        if (fileSavedForXSL()) {
            fileManager.exportHTMLfromXSL();
        }
    }
        
    public static void exportLG(){
    	fileManager.exportLG();  
    	
    }
    
    public static void importDomain(){
    	fileManager.importDomain();
    }
    
	//Thomas
    //public static void save() {
    public static boolean save() {
    	//fileManager.save();
    	if (fileManager.save()) {
	    	FileManager.MODIFIED=false; 
    		MainFrame.mainFrame.changeTitle();
    		return true;
    	}
    	else
    		return false;
    }
    
    public static void saveAs(){
    	fileManager.saveAs();
    	FileManager.MODIFIED=false; 
    	MainFrame.mainFrame.changeTitle();
    }
    
    //tape_recorder
    public static void saveAs(String fileName) {
        fileManager.saveAs(fileName);
        FileManager.MODIFIED=false; 

        if (guiEnableFlag) {
            MainFrame.mainFrame.changeTitle();
        }
    }
    
    //tape_recorder
    public static void readXML(String fileName) {
        if (fileSaved()) {
            if (fileManager.readXML(fileName)) {
                if (guiEnableFlag) {
                    MainFrame.mainFrame.changeTitle();
                }
                
                resetGUI();
                tree.fill(skeleton);
                tree.expandRow(0);
                tree.setSelectionRow(0);
                openChildFrame(tree.getPathForRow(0));
            }
        }
    }
    
    public static void open() {
    	if (fileManager.open()) {
     	    MainFrame.mainFrame.changeTitle();
    	    resetGUI();
    	    tree.fill(skeleton);
    	    tree.expandRow(0);
    	    tree.setSelectionRow(0);
    	    openChildFrame(tree.getPathForRow(0));
    	}
    	//openAllFramesInternaly();
    }
    
    public static void open(JProgressBarDia jpbarDia) {
        if (fileSaved()) {
	    	if (fileManager.open(jpbarDia)) {
	     	    MainFrame.mainFrame.changeTitle();
	    	    resetGUI();
	    	    tree.fill(skeleton);
	    	    tree.expandRow(0);
	    	    tree.setSelectionRow(0);
	    	    openChildFrame(tree.getPathForRow(0));
	    	}
	    	//openAllFramesInternaly();
        }
    }
    
    public static void domainDialog() {
    	dmManager.editor();
    }
    
    public static void resetID() {
    	currentUnusedID = 1;
    }
    
    //tape_recorder
    private static void resetGUI(){
    	tree.reset();

        if (guiEnableFlag) {
            tree.setVisible(false);
            desktop.reset();
            //System.out.println("Manager: resetGUI, desktop="+desktop);
            //desktop.setVisible(false);
            //desktop=null;
            //desktop=new GraphicDesktop();
            //System.out.println("Manager: resetGUI, desktop="+desktop);
            tree.setVisible(true);
            attributesPanel.reset();
            editor.reset();
            ComponentInternalFrame.resetCount();
        }
    }
    
    //tape_recorder
    public static void newTree(){
    	if (fileSaved()) {	
            if (guiEnableFlag) {
                MainFrame.TITLE_VARIABLE = MainFrame.TITLE_NEW;
                MainFrame.mainFrame.changeTitle();
                FileManager.FILE_NAME= MainFrame.TITLE_NEW;
            }
            
            resetID();
            
            if (guiEnableFlag) {
                resetGUI();
            }
            
            skeleton=new KernelTree(ROOT_STRING);
            tree.fill(skeleton);
                
            RTFDB=new RTFDataBase();
                    	//shijian 25-9-2001
            RTFDBM= new RTFManager();

            dmManager=new DomainModelManager();
                    
            // create new DOM doc
            fileManager.setXDM(new XManager());
            
           
            tree.expandRow(0);
            tree.setSelectionRow(0);
            openChildFrame(tree.getPathForRow(0));
            
            FileManager.CURRENT=null;
            FileManager.CURRENT_EXP=null;
            FileManager.CURRENT_HTML=null;
    
            FileManager.MODIFIED=false;
            
            //shijian 2001-3-28
            //now delete all domain elements
            xDm.getDmManager().clearDMAll();
            
    	}
    }
    
    public static void resizeAll(double ratio){
    	GenericComponent.u=GenericComponent.u*ratio;
    	resizeNode(skeleton.root,ratio);
    	resizePanels();
    }

    
    private static void resizeNode(Node n,double ratio){
    	Collection c = n.values();
    	TreeMap t;
    	GenericComponent gc;
    	Couple couple;
    	Node child;
    	Rectangle r=new Rectangle();
    	for (Iterator i=c.iterator();i.hasNext();){
    		t = (TreeMap)i.next();
    	    couple=(Couple)t.get(t.firstKey());
    	    gc=couple.object;
    	    child=couple.node;
    	    if (gc instanceof LinkableComponent){
    	    	LinkableComponent lc=(LinkableComponent)gc;
    	        r.width=(int)Math.round(gc.getWidth()*ratio);
    	        r.height=(int)Math.round(gc.getHeight()*ratio);
    	        lc.backupX*=ratio;
    	        lc.backupY*=ratio;
    	        r.x=(int)Math.round(lc.backupX);
    	        r.y=(int)Math.round(lc.backupY);
    	        gc.setBounds(r);
    	    }
    	    if (!child.isEmpty()) resizeNode(child,ratio);    	    
    	}
    	
    	if (DisplayManager.centeredZoom){
    	    JInternalFrame [] tab=desktop.getAllFrames();
            JInternalFrame frameFound=null;
            if (tab!=null){
                GraphicPanel gpanel;
                for (int i=0;i<tab.length;i++){
            	    gpanel=((ComponentInternalFrame)tab[i]).gpanel;
            	    r=gpanel.getVisibleRect();
    	            r.x=r.x+(int)Math.round(r.width*(ratio-1)/2);
    	            r.y=r.y+(int)Math.round(r.height*(ratio-1)/2);
            	    gpanel.scrollRectToVisible(r);
                }
            }
        }    	
    }
    
    protected static void resizePanels(){
        JInternalFrame [] tab=desktop.getAllFrames();
        GraphicPanel gpanel;
        Component [] comps;
        int maxw,maxh,tempw,temph;
        for (int j=0;j<tab.length;j++){
            gpanel=((ComponentInternalFrame)tab[j]).gpanel;
            comps=gpanel.getComponents();
            if (DisplayManager.centeredZoom){
    	        maxw=gpanel.getWidth();
    	        maxh=gpanel.getHeight();            	
            }else{
    	        maxw=0;
    	        maxh=0;
    	    }
    	    for (int i=0;i<comps.length;i++){
    	        tempw=comps[i].getX()+comps[i].getWidth();    	    
    	        temph=comps[i].getY()+comps[i].getHeight();
    	        if (tempw>maxw) maxw=tempw;
    	        if (temph>maxh) maxh=temph;
    	    }
    	    gpanel.setPreferredSize(new Dimension(maxw,maxh));
    	    gpanel.revalidate();
        }
    }
    
    
    
    //-----------------------------------------------------------------
    //                   new,copy,paste,cut,delete
    //-----------------------------------------------------------------    
    
    /**
     * Create a new {@link Task}
     * and automaticly position this component in the selected frame.
     * <A HREF="../source/Manager.html#newTask">Source</A>
     */
    //tape_recorder
    public static Task newTask(int posx,int posy) {
    	String DEFAULTTASKNAME= "do something";
    	
    	Task gc = null;
    	boolean auto = (posx<0)||(posy<0);
        TreePath treePath = tree.getSelectionPath();
        
        if (treePath!=null) {
            String name = treePathToString(treePath);
            String parentName;
            Task parentTask = null;		//shijian 2001-3-28
            
            boolean ok = (name.equals(ROOT_STRING));
            if (!ok) {
                parentName = treePathToString(truncTreePath(treePath));
                GenericComponent pa = skeleton.stringToGenericComponent(name,parentName);
                if (pa instanceof Task){	//CompositeComponent){
                	ok = true ;
                	parentTask = (Task) pa;
                } else {
                	ok = false ;
                	parentTask = null;
                }
            }
            else
            	parentName = skeleton.ROOT_STRING;/*_PARENT*/
            
            if (ok) {
                if (auto) gc = new Task(DEFAULTTASKNAME);
                else gc = new Task(DEFAULTTASKNAME,posx,posy);
                
                gc.setID();
                
                String childName = gc.getName();
                Integer childID = new Integer(gc.ID);
                
                Node currentNode;
                Integer currentID = null;
                
                if (currentComponent != null) {
                    currentID = new Integer(currentComponent.ID);
                }

                // Adds in a branch
                if ((currentID != null) && (skeleton.hasChildNode(name,currentID))) {
                    currentNode = skeleton.toChildNode(name,currentID);
                    
                    currentNode.add(gc);
                   // JOptionPane.showMessageDialog(MainFrame.mainFrame,"add brach");
                }
                else if (skeleton.hasChildNode(name)) {
                    currentNode = skeleton.toChildNode(name);
                    currentID = skeleton.toChildNodeID(name);
                    
                    currentNode.add(gc);
                }
                // Adds in a leaf
                else {
                    Node parentNode = skeleton.toParentNode(name,parentName);
                    
                    currentNode = parentNode.getChild(name);
                    currentID = parentNode.getChildID(name);
                    
                    currentNode.add(gc);
                   // JOptionPane.showMessageDialog(MainFrame.mainFrame,"add leaf");
                }
                skeleton.addInRegister(childName,childID,name,currentNode);

                // String mesg =   "treePathToString: "+ s+ "  Parent Name: " +  parentS+ "task name : " +newCompName;
                // JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);

                RTFDB.add(childName);
                    	//shijian 25-9-2001
                RTFDBM.add(childName);

                int childIndex = skeleton.getTreeIndex(childName,name,childID);
    	        tree.addInTree(treePath,childName,childIndex);

    	        tree.synchronizeTreeStructure(treePath);
    	        
    	        updateChildFrame(treePath);

                if (!isRoot(treePath)) {
                    ((Task)skeleton.toParentNode(name,parentName).getComponent(name)).setComposite(true);
                    updateParentFrame(treePath);
                
                    //synchronize everything of the same duplicated tasks
                    restoreChildrenCoherence(name,parentName,currentID,false);
                    synchronizeCoreFields(name,parentName,currentID);
                }
        
                if (guiEnableFlag) {
                    // automaticly find a position for the GenericComponent
                    attributesPanel.displayAttributes(currentComponent);
                }
                
                if (auto) autoPlace(gc,currentNode);
                
                //mark parent task as dirty TRUE if it is not the root
                markTaskDirty(name,true); 
            }
            tree.expandRow(0);
            
            //shijian 2001-3-28
	        if (parentTask != null)
	        	inherentParentActor(gc, parentTask);
            
        }
        
		//shijian 2001-3-12
        select(gc,treePath,new Integer(1));  
        
  		menu.setOptions(gc);
      	edit();
        
        
    	FileManager.MODIFIED = true;    
    	
        return gc;
    }
    
    public static Task newTask(){

    	return newTask(-1,-1);
    }

    //tape_recorder
    public static Task newTask(String taskName,String semantics) {
        tree.setSelectionRow(0);                    // point to the root

        Task task = newTask(-1,-1,taskName);
        task.semantics = semantics;
        
        return task;
    }

    //tape_recorder
    public static Task newTask(String parentName,String taskName,String semantics) {
        TreePath treePath = Manager.fetchTreePath(parentName,tree);
        tree.setSelectionPath(treePath);

        Task task = newTask(-1,-1,taskName);
        task.semantics = semantics;
        
        return task;
    }

    //tape_recorder
    public static Task newTask(int posx,int posy,String taskName) {
        String DEFAULTTASKNAME = taskName;
        
        Task gc = null;
        boolean auto = (posx<0)||(posy<0);
        TreePath treePath = tree.getSelectionPath();
        
        if (treePath!=null) {
            String name = treePathToString(treePath);
            String parentName;
            
            //System.out.println("newTask : name = "+name+", taskName = "+taskName);
            
            boolean ok = (name.equals(ROOT_STRING));
            if (!ok) {
                parentName = treePathToString(truncTreePath(treePath));
                ok = (skeleton.stringToGenericComponent(name,parentName) instanceof CompositeComponent);
            }
            else
                parentName = skeleton.ROOT_STRING;/*_PARENT*/
            
            if (ok) {
                if (auto) gc = new Task(DEFAULTTASKNAME);
                else gc = new Task(DEFAULTTASKNAME,posx,posy);
                
                //Thomas ?V5
                gc.setID();
                
                String childName = gc.getName();
                Integer childID = new Integer(gc.ID);
                
                Node currentNode;
                Integer currentID;

                // Adds in a branch
                if (skeleton.hasChildNode(name)) {
                    currentNode = skeleton.toChildNode(name);
                    currentID = skeleton.toChildNodeID(name);
                    
                    currentNode.add(gc);
                   // JOptionPane.showMessageDialog(MainFrame.mainFrame,"add brach");
                }
                // Adds in a leaf
                else {
                    Node parentNode = skeleton.toParentNode(name,parentName);
                    
                    currentNode = parentNode.getChild(name);
                    currentID = parentNode.getChildID(name);
                    
                    currentNode.add(gc);
                   //  JOptionPane.showMessageDialog(MainFrame.mainFrame,"add leaf");
                }
                skeleton.addInRegister(childName,childID,name,currentNode);

                // String mesg =   "treePathToString: "+ s+ "  Parent Name: " +  parentS+ "task name : " +newCompName;
                //JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);

                RTFDB.add(childName);
                    	//shijian 25-9-2001
                RTFDBM.add(childName);

                int childIndex = skeleton.getTreeIndex(childName,name,childID);
                tree.addInTree(treePath,childName,childIndex);

                tree.synchronizeTreeStructure(treePath);
                
                updateChildFrame(treePath);

                if (!isRoot(treePath)) {
                    ((Task)skeleton.toParentNode(name,parentName).getComponent(name)).setComposite(true);
                    updateParentFrame(treePath);
                
                    //synchronize everything of the same duplicated tasks
                    restoreChildrenCoherence(name,parentName,currentID,false);
                    synchronizeCoreFields(name,parentName,currentID);
                }
        
                if (guiEnableFlag) {
                    // automaticly find a position for the GenericComponent
                    attributesPanel.displayAttributes(currentComponent);
                }
                
                if (auto) autoPlace(gc,currentNode);
                
                //mark parent task as dirty TRUE if it is not the root
                markTaskDirty(name,true); 
            }
            tree.expandRow(0);
        }
        
        FileManager.MODIFIED = true;    
        
        return gc;
    }
    
    /**
     * Create a new {@link BooleanConnector}
     * and automaticly position this component in the selected frame.
     * <A HREF="../source/Manager.html#newBooleanConnector">Source</A>
     */
    //tape_recorder
    public static BooleanConnector newBooleanConnector(String type,int posx,int posy) {
    	BooleanConnector gc = null;
    	boolean auto = (posx<0)||(posy<0);
        TreePath treePath = tree.getSelectionPath();
        
        if (treePath!=null) {
            String name = treePathToString(treePath);
            String parentName;
            
            boolean ok = (name.equals(ROOT_STRING));
            if (!ok) {
                parentName = treePathToString(truncTreePath(treePath));
                ok = (skeleton.stringToGenericComponent(name,parentName) instanceof CompositeComponent);
            }
            else
            	parentName = skeleton.ROOT_STRING;/*_PARENT*/
            	
            if (ok) {
                //gc=new BooleanConnector(type);
                if (auto) gc = new BooleanConnector(type);
                else gc = new BooleanConnector(type,posx,posy);
                
			    //Thomas ?V5
                gc.setID();
                
                String childName = gc.getName();
                Integer childID = new Integer(gc.ID);
                
                Node currentNode;
                Integer currentID;
                
                // Adds in a branch
                if (skeleton.hasChildNode(name)){
                    currentNode = skeleton.toChildNode(name);
                    currentID = skeleton.toChildNodeID(name);
                    
                    currentNode.add(gc);
                }
                // Adds in a leaf
                else {
                    Node parentNode = skeleton.toParentNode(name,parentName);
                    
                    currentNode = parentNode.getChild(name);
                    currentID = parentNode.getChildID(name);
                    
                    currentNode.add(gc);
                }   
                skeleton.addInRegister(childName,childID,name,currentNode);
                
                RTFDB.add(childName);
                    	//shijian 25-9-2001
                RTFDBM.add(childName);
                
               	int childIndex = skeleton.getTreeIndex(childName,name,childID);
    	        tree.addInTree(treePath,childName,childIndex);
    	        
    	        updateChildFrame(treePath);

                if (!isRoot(treePath)) {
                   ((Task)skeleton.toParentNode(name,parentName).getComponent(name)).setComposite(true);
                   updateParentFrame(treePath);
                   
                   restoreChildrenCoherence(name,parentName,currentID,false);
                }
        
                // automaticly find a position for the GenericComponent
                if (auto) autoPlace(gc,currentNode);
                
                if (guiEnableFlag) {
                    attributesPanel.displayAttributes(currentComponent);
                }
                
                //mark parent task as dirty TRUE if it is not the root
                markTaskDirty(name,true); 

            }
            tree.expandRow(0);
        }
    	FileManager.MODIFIED = true;                 
        return gc;        
    }
    
    public static BooleanConnector newBooleanConnector(String type){
    	return newBooleanConnector(type,-1,-1);
    }

    /**
     * Create a new {@link Link}
     * and automaticly position this component in the selected frame.
     * <A HREF="../source/Manager.html#newLink">Source</A>
     */
    ///newLink
    public static void newLink(LinkableComponent lc1,LinkableComponent lc2,String name) {
        TreePath currentTreePath = truncTreePath(fetchTreePath(lc1.getName(),name,tree,new Integer(lc1.ID)));
        
        Link link = new Link(lc1,lc2,name);
                
	    //Thomas ?V5
        link.setID();
        
        String linkName = link.getName();
        Integer linkID = new Integer(link.ID);
                
        Node currentNode = skeleton.toChildNode(name);
        Integer currentID = skeleton.toChildNodeID(name);
        String parentName = skeleton.toParentName(name);

        currentNode.add(link);
        skeleton.addInRegister(linkName,linkID,name,currentNode);
        
        RTFDB.add(linkName);
    	//shijian 25-9-2001
        RTFDBM.add(linkName);

        int linkIndex = skeleton.getTreeIndex(linkName,name,linkID);
    	tree.addInTree(currentTreePath,linkName,linkIndex);

    	updateChildFrame(currentTreePath);
    	
        if (!isRoot(currentTreePath)) {
            //synchronize everything of the same duplicated tasks
            restoreChildrenCoherence(name,parentName,currentID,false);
        }
        
        //mark parent task as dirty TRUE if it is not the root
        markTaskDirty(name,true); 

    	FileManager.MODIFIED = true;         
    }
    
    private static void deleteLeaf(String name,String parentName) {
    	deleteFrame(name); //look if a frame of this name exist
    	skeleton.removeFromRegister(name,parentName);
    	
    	if (!skeleton.isInRegister(name)){
    	    if (clipboard==null) {
    	    	RTFDB.remove(name);
    	        //shijian 25-9-2001
    	 		RTFDBM.remove(name);

    	    }
    	    else{
    	        if (!name.equals(clipboard.object.getName())) RTFDB.remove(name);
    	        //shijian 25-9-2001
    	        if (!name.equals(clipboard.object.getName())) RTFDBM.remove(name);
    	    }
    	}
    	
    }
        
    private static void deleteLeaf(String name,String parentName,Node parentNode,Integer id2) {
    	deleteFrame(name); //look if a frame of this name exist
    	
    	parentNode.removeCouple(name,id2);
    	
    	if (!parentNode.containsKey(name))
    		skeleton.removeFromRegister(name,parentName);
    	
    	if (!skeleton.isInRegister(name)){
    	    if (clipboard==null) {
    	    	RTFDB.remove(name);
    	        //shijian 25-9-2001
    	 		RTFDBM.remove(name);

    	    }
    	    else{
    	        if (!name.equals(clipboard.object.getName())) RTFDB.remove(name);
    	        //shijian 25-9-2001
    	        if (!name.equals(clipboard.object.getName())) RTFDBM.remove(name);
    	    }
    	}
    }
    
    //remove all subtrees of name (including name) within parentName in NodeRegister
    //remove all corresponding comments
    //dispose of all corresponding frames in Desktop
    private static void deleteSubTree(String name,String parentName,Node parentNode,Integer id2) {
    	if (parentNode.hasOtherDuplicatedTask(name)) {
    		parentNode.removeCouple(name,id2);
    		return;
    	}
    	
    	if (parentNode.hasLeaf(name,id2)) {
    		deleteLeaf(name,parentName,parentNode,id2);
    		//JOptionPane.showMessageDialog(MainFrame.mainFrame,"delete leaf");
    	}
    	else {
    		// JOptionPane.showMessageDialog(MainFrame.mainFrame,"delete brach");
            Node currentNode = parentNode.getChild(name,id2);
            
    	    Set keys = currentNode.keySet();
    	    String [] childName = new String[keys.size()];
    	    
            int i = 0;
            for(Iterator it=keys.iterator();it.hasNext();)
            	childName[i++]=(String)(it.next());
            
            Integer childID;
            for (i=0;i<childName.length;i++) {
	        	for (Iterator itID = currentNode.getIDIterator(childName[i]);itID.hasNext();) {
	        		childID = (Integer)(itID.next());
	            	deleteSubTree(childName[i],name,currentNode,childID);
	        	}
            }
            	
            deleteLeaf(name,parentName,parentNode,id2);
    	}
    }
    
    //Thomas
    public static boolean askForTaskDeletion() {
      if (currentComponent == null) {
      	return false;
      }
      
	    //shijian 2001-4-20 
		resetPredecessorStore();
		findPrecComs(currentComponent);
		printPredecessors();
		//find successors
		resetSuccessorStore();
		findSuccComs(currentComponent);
		printSuccessors();
			
      int choice;

      if (currentComponent instanceof Link) {
      	String [] options={"Delete the link","Cancel"};
      	String newline = "\n";
      	String message="Are you sure that you want to delete the following link :"+newline+
        	"\""+currentComponent.name+"\" ?";
      	choice=JOptionPane.showOptionDialog(currentComponent.getParent(),
      		message,
      		"Link Deletion",
      		JOptionPane.YES_NO_OPTION,
      		JOptionPane.WARNING_MESSAGE,
      		null,
      		options,
      		options[0]);
      }
      else {
      	String [] options={"Delete the task","Cancel"};
      	String newline = "\n";
      	String message="Are you sure that you want to delete the following task :"+newline+
        	"\""+currentComponent.name+"\" ?";
      	choice=JOptionPane.showOptionDialog(currentComponent.getParent(),
      		message,
      		"Task Deletion",
      		JOptionPane.YES_NO_OPTION,
      		JOptionPane.WARNING_MESSAGE,
      		null,
      		options,
      		options[0]);
      }
      
      /*System.out.println("choice = "+choice);
      System.out.println("YES_OPTION = "+JOptionPane.YES_OPTION);
      System.out.println("NO_OPTION = "+JOptionPane.NO_OPTION);
      System.out.println("CANCEL_OPTION = "+JOptionPane.CANCEL_OPTION);
      System.out.println("");*/
      if (choice == 0) {
      	return true;
      }
      else {
      	return false;
      }
    }
    
    //tape_recorder
    public static void deleteGenericComponent(String name,String parentName) {
        GenericComponent gc = skeleton.getComponent(name,parentName);
        
        if (gc == null) return;
        
        TreePath treePath = fetchTreePath(name,parentName,tree);

        if (isRoot(treePath)) return;
        
        Node parentNode = skeleton.toChildNode(parentName);

        //remove all links connected to current component
        LinkableComponent lct2;
        if (gc instanceof LinkableComponent) {
            LinkableComponent lc = (LinkableComponent)gc;
            Vector links = lc.getLinks();
            int size = links.size();
            Link l;
            for (int i=size-1;i>=0;i--) {
                l=(Link)links.elementAt(i);
                lc.deleteLink(l);
                deleteLink(l.getName(),parentName);
            }       
            lct2 = new Task();
        }
        else lct2=((Link) gc).getSecondLC();

        Integer id2 = new Integer(gc.ID);
        
        //doesn't remove anything from the tree
        deleteSubTree(name,parentName,parentNode,id2);
        
        //if all compoents of parentS deleted, mark parentS as non-composite task
        if ((parentNode.isEmpty())&&(!(skeleton.isRoot(parentNode)))) {
             GenericComponent [] tab = skeleton.getComponents(parentName);
             for (int i=0;i<tab.length;i++)
                 if (tab[i] instanceof CompositeComponent)
                     ((CompositeComponent)tab[i]).setComposite(false);
        }

        //if current component is a link, delete the link
        if (!(gc instanceof LinkableComponent)) 
            lct2.deleteLink((Link) gc);

        select(truncTreePath(treePath));

        tree.removeInTree(treePath);

        //remove name for all other occurrences of parentName in tree
        //tree.removeAllInTree(name,parentName);
        tree.synchronizeTreeStructure(truncTreePath(treePath));
        
        //redisplay the original parent frame --- corresponds to parentName
        updateParentFrame(treePath);
        
        //synchronize everything of the same duplicated tasks
        restoreChildrenCoherence(name,parentName,id2,false);
        
        //mark parent task as dirty TRUE if it is not the root
        markTaskDirty(parentName,true);
        
        FileManager.MODIFIED=true;
    }
    
    /**
     * Delete recursively the selected component.
     */
    public static void delete() {
    	//Thomas
     	if (!askForTaskDeletion()) return;
    	

       if (currentComponent!=null)
        {
            int choice=0;
            if (currentComponent instanceof LinkableComponent) 
            {
             	LinkableComponent lc=(LinkableComponent)currentComponent;
             	int nbLinks=lc.linkList.size();
               	if (nbLinks>0)
               	{
               		String [] options={"Ok","Cancel"};
             	    String message="This component has "+nbLinks+" link"+
             	        ((nbLinks>1)?"s.\nThey":".\nIt") +" will be removed with it.";
             	                    
             	    choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,message,"Warning",
             	    JOptionPane.OK_CANCEL_OPTION,JOptionPane.WARNING_MESSAGE,null,options,options[0]);
                }
            
             }
            
            if (choice == 0) {
                TreePath treePath = tree.getSelectionPath();
    	        if (!isRoot(treePath)) {
    	            GenericComponent gc = currentComponent;
    	            String name = gc.getName();
                   // String st=treePathToString(treePath);
    	            String parentName = treePathToString(truncTreePath(treePath));
    	            //String mesg =  " Parent Name: " +  parentS;
                    //JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);

    	            Node parentNode = skeleton.toChildNode(parentName); ///toParentNode(s,parentS);
    	            
                    LinkableComponent lct2;
    	            //remove all links connected to current component
    	            if (gc instanceof LinkableComponent) {
    	            	LinkableComponent lc = (LinkableComponent)gc;
    	            	Vector links = lc.getLinks();
    	            	int size = links.size();
    	            	Link l;
    	            	//for (int i=0;i<size;i++){
                        for (int i=size-1;i>=0;i--) {
    	            	    l=(Link)links.elementAt(i);
    	            	    lc.deleteLink(l);
    	            	    deleteLink(l.getName(),parentName);
                            //String mesg =   "Link Name: "+ l.getName()+ "  Parent Name: " +  parentS;
                            //JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);
    	                }       
    	            	lct2 = new Task();
    	            }
    	            else lct2=((Link) gc).getSecondLC();

    	            Integer id2 = new Integer(gc.ID);
    	            
            	    //doesn't remove anything from the tree
   	                deleteSubTree(name,parentName,parentNode,id2);
   	                
   	                //removes the selected subtree
   	                //parent.remove(s);
                	
   	                //if all compoents of parentS deleted, mark parentS as non-composite task
                	if ((parentNode.isEmpty())&&(!(skeleton.isRoot(parentNode)))) {
                		 GenericComponent [] tab = skeleton.getComponents(parentName);
                		 for (int i=0;i<tab.length;i++)
                		 	if (tab[i] instanceof CompositeComponent)
                		     	((CompositeComponent)tab[i]).setComposite(false);
                	}

                	//if current component is a link, delete the link
                    if (!(gc instanceof LinkableComponent)) 
                        lct2.deleteLink((Link) gc);
 
                    select(truncTreePath(treePath));

                    tree.removeInTree(treePath);

                    //remove name for all other occurrences of parentName in tree
                    //tree.removeAllInTree(name,parentName);
                    tree.synchronizeTreeStructure(truncTreePath(treePath));
                    
                    //redisplay the original parent frame --- corresponds to parentName
                    updateParentFrame(treePath);
                    
                    //synchronize everything of the same duplicated tasks
                    restoreChildrenCoherence(name,parentName,id2,false);
                    
                    //mark parent task as dirty TRUE if it is not the root
                    markTaskDirty(parentName,true); 
                }
            }
        }
        
    	FileManager.MODIFIED=true;         
    }
    
    /**
     * Deletes a component without any selection
     */ 
    private static void deleteLink(String name,String parentName) {
    	
	    if (skeleton.isInTree(name)) {    	    	
	        TreePath treePath = fetchTreePath(name,parentName,tree);
	        Node parentNode = skeleton.toParentNode(name,parentName);
	        	        	       	    
            deleteLeaf(name,parentName);
	        parentNode.remove(name);
	        
	        tree.removeInTree(treePath);

	        //remove name for all other occurrences of parentName in tree
            tree.removeAllInTree(name,parentName);
	    }
    }
    
    private static void cutLeaf(Node n,String s,String parentName){
    	deleteFrame(s);//look if a frame of this name exist
    	skeleton.removeFromRegister(s,parentName);
    }
        
    private static void cutSubTree(Node node,String s,String parentName){
	if (node.hasLeaf(s)) cutLeaf(node,s,parentName);
	else {
            Node n=node.getChild(s); 
    	    Set keys=n.keySet();
    	    String [] tab=new String[keys.size()];
            int i=0;
            for(Iterator it=keys.iterator();it.hasNext();)
	        tab[i++]=(String)(it.next());
	    for (i=0;i<tab.length;i++) cutSubTree(n,tab[i],s);
	    cutLeaf(node,s,parentName);
	}
    }
    
    /**
     * Cut recursively the selected component
     */
    public static void cut(){
      if (currentComponent instanceof Link)
      	  JOptionPane.showMessageDialog(MainFrame.mainFrame,"Cannot cut a link.\nUse delete instead.","Operation not allowed",JOptionPane.ERROR_MESSAGE);
      else if (currentComponent instanceof LinkableComponent) {
    	LinkableComponent lc=(LinkableComponent)currentComponent;
    	int choice=0;
    	int nbLinks=lc.linkList.size();
      	if (nbLinks>0){
            String [] options={"Ok","Cancel"};
    	    String message="This component has "+nbLinks+((nbLinks>1)?" links.\nThey":" link.\nIt")+" will be removed with it.";
    	    choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,message,"Warning",
    	            JOptionPane.OK_CANCEL_OPTION,
    	            JOptionPane.WARNING_MESSAGE,null,options,options[0]);
       }
       if (choice==0){
        TreePath treePath=tree.getSelectionPath();
    	if (!isRoot(treePath)){
    	    GenericComponent gc=currentComponent;
    	    String s=gc.getName();
    	    String parentS=treePathToString(truncTreePath(treePath));
    	    
    	    Node parent=skeleton.toParentNode(s,parentS);
    	        	    
    	    
    	    //remove links
    	    //if (gc instanceof LinkableComponent) {
    	    	//LinkableComponent lc=(LinkableComponent)gc;
    	    	Vector links=lc.getLinks();
    	    	int size=links.size();
                System.out.println("No of links to " + s + "= " + size);
    	    	Link l;

                while (!(links.isEmpty()))
                {

                    l=(Link)links.lastElement();
                    lc.deleteLink(l);
                    deleteLink(l.getName(),parentS);  
                } 	    
    	    
    	    //value to put in the clipboard
    	    Node clipNode=skeleton.toChildNode(s);
    	    clipboard=new Couple(parent.getComponent(s),(clipNode!=null)?clipNode:(new Node()));
    	    
    	    //doesn't remove anything from the tree
   	    	cutSubTree(parent,s,parentS);
   	    
   	    	//removes the selected subtree
   	    	parent.remove(s);
   	    
    	    if ((parent.isEmpty())&&(!(skeleton.isRoot(parent)))){
    	    	 GenericComponent [] tab=skeleton.getComponents(parentS);
                 System.out.println("No of components to " +tab.length);
    	    	 for (int i=0;i<tab.length;i++)
    	    	     if (tab[i] instanceof CompositeComponent)((CompositeComponent)tab[i]).setComposite(false);
    	    }

            select(truncTreePath(treePath));
    	    
    	    tree.removeInTree(treePath);
    	    updateParentFrame(treePath);    	        	

    	    restoreChildrenCoherence(s,parentS);
    	    
    	    String type;
    	    if (gc instanceof Task) type="Task";
    	    else /*if (gc instanceof BooleanConnector)*/
    	    	type=((BooleanConnector)gc).type;
    	    graphicToolBar.setClipboard(type);
    	        	    
    	    //mark parent task as dirty TRUE if it is not the root
            markTaskDirty(parentS,true); 

        }
      }
      }
    	FileManager.MODIFIED=true;         
    }


    public static void copy() {
        if (currentComponent instanceof Link)
      	    JOptionPane.showMessageDialog(MainFrame.mainFrame,
                  "Cannot cut a link.\nUse delete instead.","Operation not allowed",JOptionPane.ERROR_MESSAGE);
        else if (currentComponent instanceof LinkableComponent) {
            LinkableComponent lc=(LinkableComponent)currentComponent;
            TreePath treePath=tree.getSelectionPath();
    	    if (!isRoot(treePath)){
    	        GenericComponent gc=currentComponent;
    	        String s=gc.getName();
    	        String parentS=treePathToString(truncTreePath(treePath));
    	        Node parent=skeleton.toParentNode(s,parentS);
    	        
    	        //Bad method, introspection is better
    	        LinkableComponent newComp;
    	        if (gc instanceof Task)
    	            newComp=new Task((Task)gc);
    	        else newComp=new BooleanConnector((BooleanConnector)gc);
    	        Node originalNode=skeleton.toChildNode(s);
    	        // This node, as well as all the components it contains have
    	        //to be duplicated. We cannot have two different frames with
    	        //the same components.
    	        if (originalNode!=null){
    	            Node clipNode = duplicateNodeAndComponents(originalNode,newComp.getName());
    	            clipboard = new Couple(newComp,clipNode);
    	        } else clipboard = new Couple(newComp,new Node());
    	     
    	        String type;
    	        if (gc instanceof Task) type="Task";
    	        else /*if (gc instanceof BooleanConnector)*/
    	    	    type=((BooleanConnector)gc).type;
    	        graphicToolBar.setClipboard(type);
    	    
    	    }
    	}
        
    	FileManager.MODIFIED=true;         
    }
    
    //return a new node with new components with the same attributes and the
    //same name except for the links.
    private static Node duplicateNodeAndComponents(Node node,String parentName){
    	Node n=new Node();
    	String name;
    	GenericComponent g;
    	LinkedList links=new LinkedList();
    	LinkedList linkedComponents=new LinkedList();
    	LinkableComponent lc;
    	for (Iterator i=node.keySet().iterator();i.hasNext();){
    	    name=(String)i.next();
    	    g=node.getComponent(name);
    	    //There is a better way to do it with introspection
    	    if (g instanceof Task) {
    	    	n.add(new Task((Task)g));
    	    	lc=(LinkableComponent)g;
    	    	if (lc.linkList.size()>0) linkedComponents.add(g);
    	    }
    	    else if (g instanceof BooleanConnector) {
    	    	n.add(new BooleanConnector((BooleanConnector)g));
    	    	lc=(LinkableComponent)g;
    	    	if (lc.linkList.size()>0) linkedComponents.add(g);
    	    }
    	    else if (g instanceof Link) links.add(g);
    	}
    	int length=links.size();
    	if (length>0){
    	    Link link;
    	    LinkableComponent lc1,lc2;
    	    int i;
    	    int index=GenericComponent.getIndex(Link.REF_STRING);
    	    for (i=0;i<length;i++){
    	    	link=(Link)links.removeFirst();
    	    	lc1=(LinkableComponent)n.getComponent(link.lc1.getName());
    	    	lc2=(LinkableComponent)n.getComponent(link.lc2.getName());
    	    	link=new Link(link,index++,lc1,lc2,parentName);
    	    	link.updateLink();
    	    	n.add(link);
    	    }
    	}
    	return n;
    }

    


    public static LinkableComponent paste(){
    	return paste(-1,-1);
    }    
    /**
     * Recursive paste of a cut component. Can only be done once.
     */
    public static LinkableComponent paste(int posx,int posy){
    	LinkableComponent gc=null;
    	boolean auto=(posx<0)||(posy<0);
        TreePath treePath=tree.getSelectionPath();
        String s=treePathToString(treePath);
        String parentS;        
        boolean okComp=(s.equals(ROOT_STRING));
        if (!okComp) {
            parentS=treePathToString(truncTreePath(treePath));
            okComp=(skeleton.stringToGenericComponent(s,parentS) instanceof CompositeComponent);
        } else parentS=skeleton.ROOT_STRING;/*_PARENT*/
        	
        if ((okComp)&&(clipboard!=null)){
            gc=(LinkableComponent)clipboard.object;
            if (!(auto)) gc.setLocation(posx,posy);
            Node child=clipboard.node;
                        
            boolean failled=false;
            boolean addInChild=skeleton.hasChildNode(s);
            Node n;
            if (addInChild){
            	n=skeleton.toChildNode(s);
            } else {
            	n=skeleton.toParentNode(s,parentS);
            }
            
            String na=gc.getName();
            if (n.containsKey(na)){
                failled=true;
    	        String [] options={"Ok","Cancel"};
    	        String message="A component of the same name ("+na+") already exists in this frame.\n"+na+" will be renamed.";
    	        int choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,message,"Warning",JOptionPane.OK_CANCEL_OPTION,JOptionPane.WARNING_MESSAGE,null,options,options[0]);

                if (choice==0){
                    failled=false;
                    String ss=GenericComponent.findName(na);
                    gc.setName(ss);
                    RTFDB.add(ss);//put(ss,RTFDB.get(na));
                    //shijian 25-9-2001
                    RTFDBM.add(ss);//put(ss,RTFDB.get(na));
                }
            } 

            if (!failled){
                clipboard=null;//component cannot be duplicated            
            
                //Adds in a branch
                if (addInChild){
                    n.add(gc,child);
                }
                //Adds in a leaf
                else {
                    Node n2=new Node();
                    n2.add(gc,child);
                    n.modify(s,n2);
                    n=n2;
                }
                skeleton.addRecursivelyInRegister(gc.getName(),new Integer(gc.ID),s,n);
            
            
                
    	        tree.addRecursivelyInTree(treePath,gc.getName(),child);
    	        updateChildFrame(treePath);

                if (!isRoot(treePath)) {
                    GenericComponent gc2=skeleton.toParentNode(s,parentS).getComponent(s);
                    if (gc2 instanceof CompositeComponent) ((CompositeComponent)gc2).setComposite(true);
                    updateParentFrame(treePath);

    	            restoreChildrenCoherence(s,parentS);

               }   
               if (auto) autoPlace(gc,n);
               attributesPanel.displayAttributes(currentComponent);
               
               graphicToolBar.unsetClipboard();
               
               //mark parent task as dirty TRUE if it is not the root
        		markTaskDirty(s,true); 

            }
        }
        

        
    	FileManager.MODIFIED=true;                 
        return gc;
    }    

    public static void printFrame(){
    	JOptionPane.showMessageDialog(MainFrame.mainFrame,"Use 'Export HTML' to print the complete model","Information",JOptionPane.INFORMATION_MESSAGE);
    	JInternalFrame frame=desktop.getSelectedFrame();
    	if (frame!=null){
            final GraphicPanel comp=(GraphicPanel)((JScrollPane)frame.getContentPane().getComponent(0)).getViewport().getView();    	
    	    // A Thread is required, otherwise the main frame won't be
    	    //repainted since it waits for the end of the print dialog
    	    (new Thread(){
    	    	public void run(){
                    PrinterJob printJob=PrinterJob.getPrinterJob();
                    printJob.setPrintable(comp);
                    if (printJob.printDialog()) {
                        try {
                            printJob.print();
                        } catch (Exception ex) {ex.printStackTrace();}
                    }
                }
            }).start();
        }
    }

    // modify itself for a duplicated task among a group of the same duplicated tasks
    private static void editModifyItself(String oldName, Integer id2, String newName) {
        //correct only the oldName with ID = id2 in tree to newName
        TreeMap parentTreeMap = (TreeMap)skeleton.nodeRegister.get(oldName);
        Set keys = parentTreeMap.keySet();
        TreePath t;

        for (Iterator it=keys.iterator();it.hasNext();) {
            String tmpParentName = (String)(it.next());
            Node tmpParentNode = (Node)parentTreeMap.get(tmpParentName);

            for (Iterator itID = tmpParentNode.getIDIterator(oldName);itID.hasNext();) {
                Integer currentID = (Integer)(itID.next());
                
                if (currentID.equals(id2)) {
                    //t contains all nodes from its parent to oldName
                    t = fetchTreePath(oldName,tmpParentName,tree,currentID);
                
                    //remove oldName from tree
                    tree.removeInTree(t);
                
                    //get node corresponding to oldName in skeleton
                    Node tmpCurrentNode = skeleton.toChildNode(oldName,tmpParentName,currentID);
                    int index = skeleton.getPositionForDuplicatedTasks(oldName,tmpParentName,currentID);
                
                    tree.addRecursivelyInTree(truncTreePath(t),newName,tmpCurrentNode,index-1);
                }
            }
        }
        
        //step2: update the frames
        /*ComponentInternalFrame frame = (ComponentInternalFrame)desktop.fetchFrame(oldName);
        if (frame!=null) {
            frame.name=newName;
            frame.setTitle(newName);
            if (frame.gpanel!=null) frame.gpanel.name = newName;
        }*/
            
        //step3: update the names.
        skeleton.modifyItself_UpdateName(oldName,id2,newName);
        
        //RTFDB.put(newName,RTFDB.remove(oldName));
        RTFDB.put(newName,RTFDB.get(oldName));
        //shijian 25-9-2001
        RTFDB.changeName(newName,oldName);

    }

    private static void editModifyOthers(String oldName, Integer id2, String newName) {
        //correct all oldName in tree to newName
        TreeMap parentTreeMap = (TreeMap)skeleton.nodeRegister.get(oldName);
        Set keys = parentTreeMap.keySet();
        TreePath t;

        for (Iterator it=keys.iterator();it.hasNext();) {
            String tmpParentName = (String)(it.next());
            Node tmpParentNode = (Node)parentTreeMap.get(tmpParentName);

            for (Iterator itID = tmpParentNode.getIDIterator(oldName);itID.hasNext();) {
                Integer currentID = (Integer)(itID.next());
                
                //t contains all nodes from its parent to oldName
                t = fetchTreePath(oldName,tmpParentName,tree,currentID);
            
                //remove oldName from tree
                tree.removeInTree(t);
            
                //get node corresponding to oldName in skeleton
                Node tmpCurrentNode = skeleton.toChildNode(oldName,tmpParentName,currentID);
                int index = skeleton.getPositionForDuplicatedTasks(oldName,tmpParentName,currentID);
            
                tree.addRecursivelyInTree(truncTreePath(t),newName,tmpCurrentNode,index-1);
            }
        }
        
        //step2: update the frames
        ComponentInternalFrame frame = (ComponentInternalFrame)desktop.fetchFrame(oldName);
        if (frame!=null) {
            frame.name=newName;
            frame.setTitle(newName);
            if (frame.gpanel!=null) frame.gpanel.name = newName;
        }
        
        //step3: update the names.
        skeleton.updateName(oldName,newName);
        RTFDB.put(newName,RTFDB.remove(oldName));
		//shijian 25-9-2001
        RTFDBM.changeName(newName,oldName);
       	RTFDBM.remove(oldName);
    }
    
    public synchronized static void edit() {
    	
        if (currentComponent!=null) {
    	
           final GenericComponent comp = currentComponent;
            
    	    final String oldName = comp.getName();
            
            //TreePath treePath = Manager.fetchTreePath(oldName,Manager.tree);
            Integer id2 = new Integer(comp.ID);
            String parentName = skeleton.toParentName(oldName,id2);
            //System.out.println("edit : "+parentName);
            TreePath treePath = Manager.fetchTreePath(oldName,parentName,Manager.tree,id2);
            
    	    boolean abort = true;
    	    boolean modifyItselfFromOtherComponents = true;
            
            MainFrame.mainFrame.repaint();
            EditionDialog dialog = new EditionDialog(comp);

   	    	abort=dialog.isAborted();
               
            //System.out.println("abort = "+abort);
               
   	    	modifyItselfFromOtherComponents = dialog.willModifyItself();

            if (!abort){
           		String newName = comp.getName();
           		
           		id2 = new Integer(comp.ID);
                                                 
                //During the edition if the name has changed,
                //an incoherence has appeared since the component
                //is still registered to the old name.
                //updateName will restore the coherence.
                    
                //step1: update the tree --- remove oldName from tree, append newName to tree
           		//(If do it later, we won't be able to spot the nodes to update)
           		
           		//get all parent task names of oldName into modif[]
   	       		/*String [] parentNames = skeleton.toUpdate(oldName);
		        TreePath t;
    	        Node n;
				for (int i=0;i<parentNames.length;i++) {
					//t contains all nodes from its parent modif[i] to oldName
					t=fetchTreePath(oldName,parentNames[i],tree);
					
					//remove oldName from tree
                    tree.removeInTree(t);
                    
                    //get node corresponding to oldName in skeleton
                    n=skeleton.toChildNode(oldName,parentNames[i]);
                    
    	            tree.addRecursivelyInTree(truncTreePath(t),newName,n);
   	            }*/
   	            
                //System.out.println("modifyItselfFromOtherComponents = "+modifyItselfFromOtherComponents);
                
                int numDuplicatedTasks = skeleton.getNumDuplicatedTasks(oldName);
        
                if (!oldName.equals(newName)) {
                    if (modifyItselfFromOtherComponents && (numDuplicatedTasks > 1))
                        editModifyItself(oldName,id2,newName);
                    else
                        editModifyOthers(oldName,id2,newName);
                }
    	            
   	            TreePath parentTreePath = truncTreePath(treePath);
    	        
   	            //step3: restore the coherence of the components
   	            parentName = treePathToString(parentTreePath);
                //System.out.println("edit : "+parentName);

                if (modifyItselfFromOtherComponents) 
                    restoreChildrenCoherenceFromExisting(comp.getName(),parentName,id2);
   	            else {
                    // modify others
                    if (oldName.equals(newName)) {
                        synchronizeCoreFields(comp.getName(),parentName,id2);
                    }
                    else {
                        restoreChildrenCoherence(comp.getName(),parentName,id2,true);
                        
                        checkIfCloseFrame(comp);
                    }
                }
    	        
   	            //synchronize tree structure with that of skeleton
    	    	synchronizeTree(newName);

    	    	//select the corresponding node in tree
    	    	selectNode(fetchTreePath(comp.getName(),parentName,tree,id2));
    	    	
    	    	//display attributes of current task selected
   	            if (currentComponent==comp) attributesPanel.displayAttributes(comp);
    	            
   	            // set Task.dirty = true
   	            if (comp instanceof Task) ((Task)comp).dirty =true;
			}    	            
        }
    }
    
    private static void checkIfCloseFrame(GenericComponent comp) {
        if (comp instanceof Task) {
            Task task = (Task) comp;
            
            if (!task.composite) {
                // remove name frame if it exists
                desktop.deleteFrame(task.name);
            }
        }
    }

    public static void synchronizeTree(String name) {
   		TreeMap parentTreeMap = (TreeMap)skeleton.nodeRegister.get(name);
   		Set keys = parentTreeMap.keySet();
    	TreePath t;

        for (Iterator it=keys.iterator();it.hasNext();) {
        	String tmpParentName = (String)(it.next());
	        Node tmpParentNode = (Node)parentTreeMap.get(tmpParentName);

        	for (Iterator itID = tmpParentNode.getIDIterator(name);itID.hasNext();) {
		    	Integer currentID = (Integer)(itID.next());
                
				//t contains all nodes from its parent to name
				t = fetchTreePath(name,tmpParentName,tree,currentID);
			
				//remove name from tree
    	        tree.removeInTree(t);
            
        	    //get node corresponding to name in skeleton
            	Node tmpCurrentNode = skeleton.toChildNode(name,tmpParentName,currentID);
            	int index = skeleton.getPositionForDuplicatedTasks(name,tmpParentName,currentID);
            
	            tree.addRecursivelyInTree(truncTreePath(t),name,tmpCurrentNode,index-1);
	    	}
        }
    }
    
    // copy all fields of task of (name,parentName) to the fields of the same duplicated tasks of the other parents
    public static void restoreAttributesCoherence(String name,String parentName) {
    	Object o = skeleton.nodeRegister.get(name);
    	
    	if (o instanceof TreeMap) {
    	    TreeMap t=(TreeMap)o;
    	    
    	    Set keys = t.keySet();
    	    GenericComponent [] tmpCurrentComponents = new GenericComponent[keys.size()];
    	    Node [] tmpParentNodes = new Node[keys.size()];
    	    
    	    int i=0;
    	    int index=0;
    	    for (Iterator it=keys.iterator();it.hasNext();i++) {
    	        String tmpParentName = (String)(it.next());
    	        
    	        tmpParentNodes[i] = (Node)t.get(tmpParentName);
    	        
    	        tmpCurrentComponents[i] = tmpParentNodes[i].getComponent(name);
    	        
    	        if (tmpParentName.equals(parentName)) {
    	             index=i;
    	        }
    	    }
    	    
    	    Field [] originalFields = getFieldsToClone(tmpCurrentComponents[index]);
    	    Field [] fields;
            TreePath treePath;
            
            for (i=0; i<tmpParentNodes.length; i++) if (i!=index) {
    	        // field coherence    	    
    	        fields = getFieldsToClone(tmpCurrentComponents[i]);
    	        String type;
    	        
    	        for (int j=0; j<fields.length; j++) {
                    try {
    	                if (tmpCurrentComponents[i] instanceof CompositeComponent) {
    	                    type = fields[j].getType().getName();
    	                    
    	                    if (type.equals("java.lang.String")) {
   	                        	fields[j].set(tmpCurrentComponents[i],originalFields[j].get(tmpCurrentComponents[index]));
    	                    }
    	                    else if (type.equals("int")) {
   	                        	fields[j].setInt(tmpCurrentComponents[i],originalFields[j].getInt(tmpCurrentComponents[index]));
    	                    }
    	                    else if (type.equals("boolean")) {
   	                        	fields[j].setBoolean(tmpCurrentComponents[i],originalFields[j].getBoolean(tmpCurrentComponents[index]));
   	                    	}
   	                	}
                    }
                    catch (Exception e) {
                    	System.err.println("getField error");
                    }
                }
    	            	        
                tmpCurrentComponents[i].repaint();
    	    }
        }
    }

    public static void synchronizeCoreFields(String name,String parentName,Integer id2) {
        TreeMap t = (TreeMap)skeleton.nodeRegister.get(name);
        
        if (t == null) return;
        
        //get all parent nodes of name
        Set keys = t.keySet();
        Node [] tmpParentNodes = new Node[keys.size()];
        
        int i=0;
        int index=0;
        for (Iterator it=keys.iterator();it.hasNext();i++) {
            String tmpParentName = (String)(it.next());
            
            tmpParentNodes[i] = (Node)t.get(tmpParentName);
            
            if (tmpParentName.equals(parentName))
                index=i;
        }
        
        // get fields of current component to clone from
        GenericComponent currentComponent = tmpParentNodes[index].getComponent(name,id2);
        Field [] originalFields = getFieldsToClone(currentComponent);

        Field [] fields;
        TreePath treePath;
        
        for (i=0; i<tmpParentNodes.length; i++) {
            for (Iterator itCurrentID = tmpParentNodes[i].getIDIterator(name);itCurrentID.hasNext();) {
                Integer currentID = (Integer)(itCurrentID.next());

                if (!currentID.equals(id2)) {
                    // clone fields of the other duplicated tasks
                    GenericComponent tmpCurrentComponent = tmpParentNodes[i].getComponent(name,currentID);
                    fields = getFieldsToClone(tmpCurrentComponent);
                    
                    String type;
                    
                    for (int j=0; j<fields.length; j++) {
                        try {
                            if (tmpCurrentComponent instanceof CompositeComponent) {
                                String fieldName = fields[j].getName();
                                //String fieldValue = fields[j].get(currentComponent).toString();
                                //System.out.println("j = "+j+" --- field : "+fieldName+", value = "+fieldValue);
                                
                                if (isCoreField(fieldName)) {
                                    type = fields[j].getType().getName();
                                    
                                    if (type.equals("java.lang.String")) {
                                           fields[j].set(tmpCurrentComponent,originalFields[j].get(currentComponent));
                                    }
                                    else if (type.equals("int")) {
                                           fields[j].setInt(tmpCurrentComponent,originalFields[j].getInt(currentComponent));
                                    }
                                    else if (type.equals("boolean")) {
                                           fields[j].setBoolean(tmpCurrentComponent,originalFields[j].getBoolean(currentComponent));
                                    }
                                }
                            }
                        }
                        catch (Exception e) {
                            System.err.println("getField error");
                        }
                    }
                                    
                    tmpCurrentComponent.repaint();
                }
            }
        }
    }
    
    /*
        possible fields : 
        
        semantics, composite, mandatory, style, minCard, maxCard
        precondition, postcondition, feedback, terminal, dirty
    */
    private static boolean isCoreField(String fieldName) {
        boolean result = false;
        
        if (fieldName.equals("semantics")) result = true;
        if (fieldName.equals("style")) result = true;
        if (fieldName.equals("composite")) result = true;
        
        return result;
    }
    
    public static void restoreAttributesCoherence(String name,String parentName,Integer id2) {
    	Object o = skeleton.nodeRegister.get(name);
    	
    	if (o instanceof TreeMap) {
    	    TreeMap t = (TreeMap)o;

    	    //get all parent nodes of name
    	    Set keys = t.keySet();
    	    Node [] tmpParentNodes = new Node[keys.size()];
    	    
    	    int i=0;
    	    int index=0;
    	    for (Iterator it=keys.iterator();it.hasNext();i++) {
    	        String tmpParentName = (String)(it.next());
    	        
    	        tmpParentNodes[i] = (Node)t.get(tmpParentName);
    	        
    	        if (tmpParentName.equals(parentName))
    	        	index=i;
    	    }
    	    
    	    // get fields of current component to clone from
    	    GenericComponent currentComponent = tmpParentNodes[index].getComponent(name,id2);
    	    Field [] originalFields = getFieldsToClone(currentComponent);

    	    Field [] fields;
            TreePath treePath;
            
            for (i=0; i<tmpParentNodes.length; i++) {
        		for (Iterator itCurrentID = tmpParentNodes[i].getIDIterator(name);itCurrentID.hasNext();) {
	    			Integer currentID = (Integer)(itCurrentID.next());

	    			if (!currentID.equals(id2)) {
		    	        // clone fields of the other duplicated tasks
	    				GenericComponent tmpCurrentComponent = tmpParentNodes[i].getComponent(name,currentID);
		    	        fields = getFieldsToClone(tmpCurrentComponent);
		    	        
		    	        String type;
		    	        
		    	        for (int j=0; j<fields.length; j++) {
		                    try {
		    	                if (tmpCurrentComponent instanceof CompositeComponent) {
		    	                    type = fields[j].getType().getName();
		    	                    
		    	                    if (type.equals("java.lang.String")) {
		   	                        	fields[j].set(tmpCurrentComponent,originalFields[j].get(currentComponent));
		    	                    }
		    	                    else if (type.equals("int")) {
		   	                        	fields[j].setInt(tmpCurrentComponent,originalFields[j].getInt(currentComponent));
		    	                    }
		    	                    else if (type.equals("boolean")) {
		   	                        	fields[j].setBoolean(tmpCurrentComponent,originalFields[j].getBoolean(currentComponent));
		   	                    	}
		   	                	}
		                    }
		                    catch (Exception e) {
		                    	System.err.println("getField error");
		                    }
		                }
		    	            	        
		                tmpCurrentComponent.repaint();
	    			}
        		}
    	    }
        }
    }

    public static void restoreAttributesCoherenceFromExisting(String name,String parentName,Integer id2) {
    	Object o = skeleton.nodeRegister.get(name);
    	
    	if (o instanceof TreeMap) {
    	    TreeMap t = (TreeMap)o;
    	    
    	    //get all parent nodes of name
    	    Set keys = t.keySet();
    	    Node [] tmpParentNodes = new Node[keys.size()];
    	    
    	    int i=0;
    	    int index=0;
    	    for (Iterator it=keys.iterator();it.hasNext();i++) {
    	        String tmpParentName = (String)(it.next());
    	        
    	        tmpParentNodes[i] = (Node)t.get(tmpParentName);
    	        
    	        if (tmpParentName.equals(parentName))
    	        	index=i;
    	    }
    	    
    	    Field [] fields;
            TreePath treePath;
            
            for (i=0; i<tmpParentNodes.length; i++) {
        		for (Iterator itCurrentID = tmpParentNodes[i].getIDIterator(name);itCurrentID.hasNext();) {
	    			Integer currentID = (Integer)(itCurrentID.next());

	    			if (!currentID.equals(id2)) {
			    	    // get fields of other duplicated component to clone from
			    	    GenericComponent otherComponent = tmpParentNodes[i].getComponent(name,currentID);
			    	    Field [] otherFields = getFieldsToClone(otherComponent);
			    	    
		    	        // clone fields to the current duplicated task
	    				GenericComponent tmpCurrentComponent = tmpParentNodes[index].getComponent(name,id2);
		    	        fields = getFieldsToClone(tmpCurrentComponent);
		    	        
		    	        String type;
		    	        for (int j=0;j<fields.length;j++) {
		                    try {
		    	                if (tmpCurrentComponent instanceof CompositeComponent) {
		    	                    type = fields[j].getType().getName();
		    	                    
		    	                    if (type.equals("java.lang.String")) {
		   	                        	fields[j].set(tmpCurrentComponent,otherFields[j].get(otherComponent));
		    	                    }
		    	                    else if (type.equals("int")) {
		   	                        	fields[j].setInt(tmpCurrentComponent,otherFields[j].getInt(otherComponent));
		    	                    }
		    	                    else if (type.equals("boolean")) {
		   	                        	fields[j].setBoolean(tmpCurrentComponent,otherFields[j].getBoolean(otherComponent));
		   	                    	}
		   	                	}
		                    }
		                    catch (Exception e) {
		                    	System.err.println("getField error");
		                    }
		                }
		    	            	        
		                tmpCurrentComponent.repaint();
		                
		                i = tmpParentNodes.length;
		                
		                break;
	    			}
        		}
    	    }
        }
    }

    //synchronize everything of the same duplicated tasks : 
    //to make all duplicated tasks of name point to the same decomposition, same fields of (name,parentName)
    //update tree to reflect the new structure of duplicated tasks pointing to the same decomposition
    public static void restoreChildrenCoherence(String name,String parentName) {
    	TreeMap t = (TreeMap)skeleton.nodeRegister.get(name);
    	
    	if (t != null) {
    	    Set keys = t.keySet();
    	    
    	    //current components of name
    	    //GenericComponent [] currentComponents=new GenericComponent[keys.size()];
    	    
    	    Node [] parentNodes=new Node[keys.size()];
    	    String [] parentNames=new String[keys.size()];
    	    
    	    int i=0;
    	    int index=0;
    	    for (Iterator it=keys.iterator();it.hasNext();i++){
    	        String s=(String)(it.next());
    	        parentNames[i]=s;
    	        parentNodes[i]=(Node)t.get(s);
    	        //currentComponents[i]=parentNodes[i].getComponent(name);
    	        if (s.equals(parentName)) {
    	             index=i;
    	        }
    	    }
    	    
            TreePath treePath;
            Node n;
            
            //current decomposition of name
            Node currentNode = parentNodes[index].getChild(name);
            
            for (i=0;i<parentNodes.length;i++) if (i!=index) {
            	//update all other duplicated tasks to point to the same decomposition tree
                parentNodes[i].modify(name,currentNode);

				treePath=fetchTreePath(name,parentNames[i],tree);
                
				//remove name within names[i] in tree
				tree.removeInTree(treePath);
                
				//n = node of name within names[i]
                n=skeleton.toChildNode(name,parentNames[i]);
                
			    //add name to parentTreePath as well as its tree structure similar to currentNode
    	        tree.addRecursivelyInTree(truncTreePath(treePath),name,n);
            }
            
		    // copy all fields of task of (name,parentName) to the fields of the same duplicated tasks of the other parents
            restoreAttributesCoherence(name,parentName);
        }
    }

    public static void restoreChildrenCoherence(String name,String parentName,Integer id2,boolean changeAttributeFlag) {
    	TreeMap t = (TreeMap)skeleton.nodeRegister.get(name);
    	
    	if (t != null) {
    		// get parentNames array & parentNodes array
    	    Set keys = t.keySet();
    	    
    	    Node [] parentNodes=new Node[keys.size()];
    	    String [] parentNames=new String[keys.size()];
    	    
    	    int i=0;
    	    int index=0;
    	    for (Iterator it=keys.iterator();it.hasNext();i++) {
    	        String s=(String)(it.next());
    	        parentNames[i]=s;
    	        parentNodes[i]=(Node)t.get(s);
    	        if (s.equals(parentName)) {
    	             index=i;
    	        }
    	    }
    	    
            TreePath treePath;
            Node n,currentNode;
            
            if (!parentNodes[index].hasChild(name,id2)) return;	//for deleted node
            
            //get current decomposition of name for other duplicated task to match with
            currentNode = parentNodes[index].getChild(name,id2);
            
            for (i=0;i<parentNodes.length;i++) {
        		for (Iterator itCurrentID = parentNodes[i].getIDIterator(name);itCurrentID.hasNext();) {
	    			Integer currentID = (Integer)(itCurrentID.next());

	    			if (!currentID.equals(id2)) {
		            	//update all other duplicated tasks to point to the same decomposition tree
		                parentNodes[i].modify(name,currentNode,currentID);
		
						treePath = fetchTreePath(name,parentNames[i],tree,currentID);
		                
						//remove name within names[i] in tree
						tree.removeInTree(treePath);
		                
						//n = node of name within names[i]
		                n = skeleton.toChildNode(name,parentNames[i],currentID);
		            	int index1 = skeleton.getPositionForDuplicatedTasks(name,parentNames[i],currentID);
		                
					    //add name to parentTreePath as well as its tree structure similar to currentNode
		    	        tree.addRecursivelyInTree(truncTreePath(treePath),name,n,index1-1);
	    			}
	        	}
            }
            
		    // copy all fields of task of (name,parentName) to the fields of the same duplicated tasks of the other parents
            if (changeAttributeFlag) restoreAttributesCoherence(name,parentName,id2);
        }
    }
    
    public static void debug() {
        skeleton.printRegister();
    }

    public static void restoreChildrenCoherenceFromExisting(String name,String parentName,Integer id2) {
    	TreeMap t = (TreeMap)skeleton.nodeRegister.get(name);
    	if (t != null) {
    		// get parentNames array & parentNodes array
    	    Set keys = t.keySet();
    	    
    	    Node [] parentNodes = new Node[keys.size()];
    	    String [] parentNames = new String[keys.size()];
    	    
    	    int i = 0;
    	    int index = 0;
    	    for (Iterator it=keys.iterator();it.hasNext();i++) {
    	        String s = (String)(it.next());
    	        
    	        parentNames[i] = s;
    	        parentNodes[i] = (Node)t.get(s);
    	        
    	        if (s.equals(parentName))
    	        	index=i;
    	    }

            for (i=0;i<parentNodes.length;i++) {
        		for (Iterator itCurrentID = parentNodes[i].getIDIterator(name);itCurrentID.hasNext();) {
	    			Integer currentID = (Integer)(itCurrentID.next());

	    			if (!currentID.equals(id2)) {
	    				Node currentNode = parentNodes[index].getChild(name,id2);
	    				
			            //get decomposition of other duplicated task to copy from
		    	        Node otherNode = parentNodes[i].getChild(name,currentID);
		            
		            	//update current duplicated task to point to the same decomposition tree
		                parentNodes[index].modify(name,otherNode,id2);
		
						TreePath treePath = fetchTreePath(name,parentNames[index],tree,id2);
						
						//remove name within names[index] in tree
		                tree.removeInTree(treePath);
		                
						//n = node of name within names[index]
		                Node n = skeleton.toChildNode(name,parentNames[index],id2);
		            	int index1 = skeleton.getPositionForDuplicatedTasks(name,parentNames[index],id2);
		                
					    //add name to parentTreePath as well as its tree structure similar to currentNode
		    	        tree.addRecursivelyInTree(truncTreePath(treePath),name,n,index1-1);

                        //close the frame if it is open
                        closeFrame(name);

                        //skeleton.printRegister();
                        
                        //remove unreferenced names in nodeRegister
                        TreeMap validNames = new TreeMap();
                        getAllValidNames(skeleton.root,validNames);
                        
                        deleteUnreferencedNames(currentNode,validNames);

                        //skeleton.printRegister();
                        
                        //to get out of for-loop
		    	        i = parentNodes.length;
		    	        
		    	        break;
	    			}
        		}
            }
            
		    // copy all fields of the same duplicated task of other parent to that of the task of (name,parentName)
            restoreAttributesCoherenceFromExisting(name,parentName,id2);
        }	
    }
    
    private static void getAllValidNames(Node node,TreeMap validNames) {
        for (Iterator i=(node.keySet()).iterator();i.hasNext();) {
            String name = (String)(i.next());
            
            addName_to_ValidNames(name,validNames);

            for (Iterator itID = node.getIDIterator(name);itID.hasNext();) {
                Integer id2 = (Integer)(itID.next());
                
                Node child = (node.getCouple(name,id2)).node;
                if (child!=null) getAllValidNames(child,validNames);
            }
        }
    }

    private static void addName_to_ValidNames(String name,TreeMap validNames) {
        if (validNames.containsKey(name)) return;

        validNames.put(name,null);
    }
    
    private static void deleteUnreferencedNames(Node node,TreeMap validNames) {
	    Set keys = node.keySet();
	    
	    if (keys.isEmpty()) return;
	    
	    for (Iterator it=keys.iterator();it.hasNext();) {
	        String name = (String)(it.next());
	        
	        deleteUnreferencedNames(name,validNames);
	        
    		for (Iterator itID = node.getIDIterator(name);itID.hasNext();) {
    			Integer id2 = (Integer)(itID.next());
    			
    			Node childNode = node.getChild(name,id2);
    			
    			if (childNode.size() > 0) deleteUnreferencedNames(childNode,validNames);
    		}
	    }
    }
    
    private static void deleteUnreferencedNames(String name,TreeMap validNames) {
        if (validNames.containsKey(name)) return;
        
        skeleton.nodeRegister.remove(name);
    }

    private static Field [] getFieldsToClone(GenericComponent gc) {
    	Class cl = gc.getClass();
    	
    	Object [] obj = gc.getCloneFields();
    	
    	Field [] fields = new Field[obj.length];
    	
    	for (int i=0; i<obj.length; i++) {
            try {
    			fields[i]=cl.getField((String)obj[i]);
            }
            catch (Exception e) {
            	System.err.println("getField error");
            }
        }
        
        return fields;    	
    }
    
    //----------------------------------------------------------------
    //                      Selection methods
    //----------------------------------------------------------------
    
    /**
     * Selects a GenericComponent.
     * If it is the root, deselect and highlight the root.
     */
/*    public static void select(String treePath){
    	String s=treePathToString(treePath);
    	else if (isInTree(s)) select(toParentNode(s).getComponent(s));
    }*/    
    
    /**
     * Select a GenericComponent in its frame. Then update the tree
     * (The node of the concerning this element is highlighted)
     * Do nothing if the component is not in the tree.
     */
    public static void select(TreePath treePath) {
    	String s=treePathToString(treePath);
    	if (skeleton.isRoot(s)) {
    	    if (currentComponent!=null){
    	    	currentComponent.setSelected(false);
    	    	currentComponent.repaint();
    	    }
    	    Manager.selectNode(fetchTreePath(skeleton.ROOT_STRING,null,tree));
    	    //editor.name=skeleton.ROOT_STRING;
            //editor.load(RTFDB.getDocument(skeleton.ROOT_STRING));
    	    currentComponent=null;
    	}
    	else {
    	    String parentS=treePathToString(truncTreePath(treePath));
    	    GenericComponent c=skeleton.stringToGenericComponent(s,parentS);
    	    if (!((c.isSelected())||(c==currentComponent))){
                if (currentComponent!=null) {
            	    currentComponent.setSelected(false);
                    currentComponent.repaint();
                }
                c.setSelected(true);
                c.repaint();
                //Update the tree
                selectNode(treePath);
                
                if (guiEnableFlag) {
                    attributesPanel.displayAttributes(c);
                    editor.name=c.getName();
                    editor.load(RTFDB.getDocument(c.getName()));
                    //shijian 25-9-2001
                    editor.load(c.getName());
                }
                
                currentComponent=c;
            }
        }
        
        //shijian 2001-3-22
    	menu.setOptions(currentComponent);
  }

    public static void select(GenericComponent gcSel,TreePath treePath,Integer id2) {
    	String name = treePathToString(treePath);
    	
    	//shijian 2001-3-12
    /*	
    	if (skeleton.isRoot(name)) {
    	    if (currentComponent!=null){
    	    	currentComponent.setSelected(false);
    	    	currentComponent.repaint();
    	    }
    	    Manager.selectNode(fetchTreePath(skeleton.ROOT_STRING,null,tree));
    	    //editor.name=skeleton.ROOT_STRING;
            //editor.load(RTFDB.getDocument(skeleton.ROOT_STRING));
    	    currentComponent=null;
    	}
    	else {
    */	    //String parentName = treePathToString(truncTreePath(treePath));
    	    
    	    //GenericComponent c = skeleton.stringToGenericComponent(name,parentName,id2);
            //GenericComponent c = tmpGetComponent(name,parentName,id2);
            GenericComponent c = gcSel;
            
    	    if (!((c.isSelected())||(c==currentComponent))) {
                if (currentComponent!=null) {
            	    currentComponent.setSelected(false);
                    currentComponent.repaint();
                }
                
                c.setSelected(true);
                c.repaint();
                
                //c.displayInfo();
                //displayTreePath(treePath);              //by Thomas
                
                //Update the tree
                selectNode(treePath);

                if (guiEnableFlag) {
                    attributesPanel.displayAttributes(c);
                    editor.name=c.getName();
                    editor.load(RTFDB.getDocument(c.getName())); 
                    //shijian
                    editor.load(c.getName());    
                }
                
                currentComponent=c;
            }
            
         	//shijian 2001-3-22
    		menu.setOptions(currentComponent);
      // }
    }
    
    public static void select(TreePath treePath,Integer id2) {
        GenericComponent gcSel = null;
        
        String name = treePathToString(treePath);
        
        if (!skeleton.isRoot(name)) {
            String parentName = treePathToString(truncTreePath(treePath));
            
            gcSel = getComponent(name,parentName,id2);
        }
        
        select(gcSel,treePath,id2);
    }
    
    private static GenericComponent getComponent(String name,String parentName,Integer id2) {
        Node firstCurrentNode = skeleton.toChildNode(parentName);
        GenericComponent result = firstCurrentNode.getComponent(name,id2);
        return result;
    }


    public static void displayTreePath(TreePath treePath) {
    	int nb = treePath.getPathCount();
    	Object [] objects = new Object[nb];
    	objects = treePath.getPath();
    	
    	String name;
    	DefaultMutableTreeNode node;
    	System.out.print("displayTreePath : ");
    	for (int i=0; i<nb; i++) {
    		node = (DefaultMutableTreeNode)objects[i];
    		name = (String)node.getUserObject();
    		System.out.print(name+", ");
    	}
    	System.out.println("");
    }
    
    /**
     * Deselect and chose the parent a default position in the tree.
     */
    public static void deselect(GraphicPanel p){
    	//System.out.println("deselect!");
        if (currentComponent!=null){
            currentComponent.setSelected(false);
            currentComponent.repaint();
            currentComponent=null;
        }
        Component current=p;
        while (!(current instanceof JInternalFrame)) current=current.getParent();
    	String s=((ComponentInternalFrame)current).getName();
        selectNode(s);
        attributesPanel.displayAttributes(null);
        editor.name=null;
        editor.reset();
    	//System.out.println("Selection of: "+fetchTreePath(s,tree));        
    }

    /**
     * Deselect.
     */
    protected static void deselect(){
    	select(fetchTreePath(skeleton.ROOT_STRING,tree));
    }

    /**
     * Selected the node matching c in MainTree
     */
    /*public static void selectNode(GenericComponent c){
    	selectNode(c.getName());
    }*/
    
    /**
     * Selected the node matching s in MainTree
     */
    public static void selectNode(String s){
    	if (skeleton.isInTree(s)) tree.setSelectionPath(fetchTreePath(s,tree));
    	
    	//shijian 2001-3-22
    	menu.setOptions(null);

    }

    /**
     * Selected the node matching s in MainTree
     */
    public static void selectNode(TreePath t){
    	tree.setSelectionPath(t);
    	
    	//shijian 2001-3-22
    	menu.setOptions(null);

    }

    //Thomas : 
    // display tree paths of tmpTaskName
    // which tmpTaskName is in the nodeRegister of skeleton
    private static int displayTaskAndTreePath_WithFindNext(String tmpTaskName) {
    	String name;
		String [] options={"Ok","Cancel"};
        int c;
		
    	Set keys = ((TreeMap)skeleton.nodeRegister.get(tmpTaskName)).keySet();
		
        for (Iterator i=keys.iterator();i.hasNext();) {
            name=(String)i.next();
            //Manager.select(Manager.fetchTreePath(searchName,name,Manager.tree));
            select(fetchTreePath(tmpTaskName,name,Manager.tree));

            //String mesg =   "Task Name: "+ searchName+ "  Parent Name: " +  name;
	        String mesg =   "Task Name : \"" + tmpTaskName + 
    	        "\"\nParent Task Name : \"" + name + "\"";
        	JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);

            if (i.hasNext()) {
            	c=JOptionPane.showOptionDialog(MainFrame.mainFrame,
            		"Select next component ?","Search",
	            	JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,
    	        	null,options,options[0]);
                        
        	    if (c!=0) return c;
            }
        }
        
        return 0;
    }
    
    //Thomas : 
    // display all the tasks and their tree paths for searchTaskName
    // which searchTaskName may have '*' for wild-card search
    private static void displayAllTaskAndTreePath(String searchTaskName) {
    	int i = searchName.indexOf('*');
    	
    	if (i<0) {
			displayTaskAndTreePath_WithFindNext(searchTaskName);
    	}
   		else {
			String [] options={"Ok","Cancel"};
	    	String tmpTaskName;
    		int c,iReturnValue;
    		boolean first = true;

	    	for (Iterator itTaskName = skeleton.taskNameIterator();itTaskName.hasNext();) {
		       	tmpTaskName = (String)(itTaskName.next());
		       	
		       	if (skeleton.string_wide_card_search(tmpTaskName,searchTaskName)) {
		       		if (first) first = false;
		       		else {
			       		c=JOptionPane.showOptionDialog(MainFrame.mainFrame,
    	        			"Select next component ?","Search",
			            	JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,
    			        	null,options,options[0]);
                        
        			    if (c!=0) return;
		       		}
		       		
		       		iReturnValue = displayTaskAndTreePath_WithFindNext(tmpTaskName);
		       		if (iReturnValue != 0) return;     // return if user clicks 'Cancel'
		       	}
			}
   		}
    }

    //Thomas
    public static void search() {
    	String [] options={"Ok","Cancel"};

    	JPanel panel=new JPanel();
    	panel.setLayout(new GridLayout(2,2,10,10));
    	panel.add(new JLabel("Name"));
    	JTextField tname=new JTextField(searchName);
    	panel.add(tname);
    	panel.add(new JLabel("(Expansion name)"));
    	JTextField tparentName=new JTextField(searchParentName);
    	panel.add(tparentName);

    	int choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,panel,
                "Search",JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,
                null,options,options[0]);

        if (choice==0) {
            searchName=tname.getText();
            searchParentName=tparentName.getText();

            if (searchName.equals("")) 
                JOptionPane.showMessageDialog(MainFrame.mainFrame,"Invalid name!");
            //Thomas
            //else if (!skeleton.isInTree(searchName))     
            else if (!skeleton.isInTree_wild_card_search(searchName))     
                    JOptionPane.showMessageDialog(MainFrame.mainFrame,
                    	"Task \""+searchName+"\" not found!");
            else if (skeleton.isRoot(searchName)) 
                    select(fetchTreePath(skeleton.ROOT_STRING,tree));
            else if (searchParentName.equals(""))
            {
            	//Thomas
            	displayAllTaskAndTreePath(searchName);
            } 
            else if (!skeleton.isInTree(searchParentName)) 
                    JOptionPane.showMessageDialog(MainFrame.mainFrame,
                                   searchParentName+" not found!");
            else {
            	TreeMap t=(TreeMap)skeleton.nodeRegister.get(searchName);
            	if (t.containsKey(searchParentName)) 
            	    Manager.select(Manager.fetchTreePath(searchName,searchParentName,Manager.tree));
            	else JOptionPane.showMessageDialog(MainFrame.mainFrame,"No "+searchName+" in "+searchParentName+"!");
            }

        }
    	
    }

    /**
     * Opens a frame for a composite GenericComponent
     */
    protected static void openComposite(GenericComponent c,String parentName) {
    	if (c instanceof CompositeComponent) {
    		CompositeComponent cc = (CompositeComponent)c;
    		
    		String name = cc.getName();
           	Integer id2 = new Integer(cc.ID);
    		
            if ((cc.isComposite()) && skeleton.isInTree(name)) {
                TreePath treePath = fetchTreePath(name,parentName,tree,id2);

                tree.expandPath(treePath);
                
                openChildFrame(treePath);
            }
        }
    }
 
    /**
     * Opens the child frame if this frame is found
     */
    //tape_recorder
    protected static void openChildFrame(TreePath treePath) {
        if (!guiEnableFlag) return;
        
    	String name = treePathToString(treePath);
    	
    	if (skeleton.isInTree(name)) {
    		//get all GenericComponents in the decomposition window of name
    	    GenericComponent [] gctab = fetchComponents(treePath);
    	    
    	    desktop.openFrame(name,gctab);
    	}
    }

    /**
     * Opens the parent frame if this frame is found
     */
    //tape_recorder
    protected static void openParentFrame(TreePath treePath) {
        if (!guiEnableFlag) return;
        
    	String s=treePathToString(treePath);
    	if (skeleton.isInTree(s)){
    	    treePath=truncTreePath(treePath);
    	    s=treePathToString(treePath);
    	    GenericComponent [] gctab=fetchComponents(treePath);
            
    	    desktop.openFrame(s,gctab);
    	}
    }
    
    
    /**
     * Update the child frame if not empty. Destroys it else.
     */
    //tape_recorder
    protected static void updateChildFrame(TreePath treePath){
        if (!guiEnableFlag) return;
        
    	String s=treePathToString(treePath);
    	if (skeleton.isInTree(s)){
    	    GenericComponent [] gctab=fetchComponents(treePath);
    	    if ((gctab==null)&&(!(skeleton.isRoot(s)))) deleteFrame(s);
    	    else desktop.updateFrame(s,gctab);
    	}
    }
    
    /**
     * Update the parent frame if not empty. Destroys it else (if it is not
     * the root frame).
     */
    //tape_recorder
    protected static void updateParentFrame(TreePath treePath) {
        if (!guiEnableFlag) return;
        
    	treePath = truncTreePath(treePath);
    	
    	String s = treePathToString(treePath);
    	
    	if (skeleton.isInTree(s)) {
    		//fetch all the GenericComponents of s
    	    GenericComponent [] gctab=fetchComponents(treePath);
    	    
    	    if ((gctab==null)&&(!(skeleton.isRoot(s)))) {
    	    	// remove frame if empty
    	    	deleteFrame(s);
    	    }
    	    else {
    	    	//redisplay the current frame
    	    	desktop.updateFrame(s,gctab);
    	    }
    	}
    }
    
    /**
     * Disposes a frame.
     */	
    //tape_recorder
    protected static void deleteFrame(String name) {
        if (!guiEnableFlag) return;
        
    	if (skeleton.isInTree(name))
    		desktop.deleteFrame(name);
    }
    
    /**
     * close a frame.
     */	
    //tape_recorder
    protected static void closeFrame(String name) {
        if (!guiEnableFlag) return;
        
    	if (skeleton.isInTree(name)) {
    		desktop.closeFrame(name);
    	}
    }
    









//--------------------------------------------------------------
//--------------------------------------------------------------
//--------------------------------------------------------------
//--------------------   ManagerToolKit    ---------------------
//--------------------------------------------------------------
//--------------------------------------------------------------
//--------------------------------------------------------------










    //---------------------------------------------------------------
    //               GenericComponents Layout
    //---------------------------------------------------------------
    /**
     * Check if the component's area intersects with the area of other 
     * components of the same branch. 
     */
    /*protected static boolean intersection(GenericComponent gc,Node n){
    	//Node n=toParentNode(gc);
    	boolean result=false;
    	Set keys=n.getKeys();
        for(Iterator it=keys.iterator();it.hasNext();){
            GenericComponent gc2=n.getComponent((String)(it.next()));
    	    if (gc2!=gc) if (gc2.intersection(gc)){
    	    	result=true;
    	    	break;
    	    }
    	}
    	return result;	
    }*/            


    protected static void autoPlaceAll(){
    	
    }


    protected static void autoPlace(String name,String parentName){
    	autoPlace(skeleton.stringToGenericComponent(name,parentName),skeleton.toParentNode(name,parentName));
    }
    
    /**
     * Automaticly place a component in a frame so that it could not
     * overlap with other component.
     */
    protected static void autoPlace(GenericComponent gc,Node n){
    	int maxWidth=ComponentInternalFrame.GRAPHICPANEL_WIDTH;
    	final int GAP_X=10;
    	final int GAP_Y=10;
    	
    	LinkableComponent lc;
    	
    	// find a free space
    	int maxX=0;
    	int maxY=0;
    	int maxmaxY=0;
    	GenericComponent maxgc=null;
    	int tempx,tempy;
    	
    	//Node n=toParentNode(gc);
    	if (n.size()>1){
    	    Set keys=n.keySet();
    	    GenericComponent gc2;
            for(Iterator it=keys.iterator();it.hasNext();){
                gc2=n.getComponent((String)(it.next()));
    	        if (gc2!=gc){
    	            if (gc2 instanceof LinkableComponent){
    	                lc=(LinkableComponent)gc2;
    	    	        tempx=gc2.getX()+(int)Math.round(lc.giveWidth()*lc.u);
    	    	        tempy=gc2.getY()+gc2.getHeight();
    	            	
    	            } else {
    	    	        tempx=gc2.getX()+gc2.getWidth();
    	    	        tempy=gc2.getY()+gc2.getHeight();
    	    	    }
    	    	    
    	    	    if ((tempy>maxY)||((tempy==maxY)&&(tempx>maxX))){
    	    	        maxY=tempy;
    	    	        maxX=tempx;
    	    	        maxgc=gc2;
    	    	    }
    	        }
    	    }
    	
    	    // A posible position has been found
    	    //maxX=gc2.getX+gc2.getWidth(); already done
    	    maxmaxY=maxY;
    	    maxY=maxgc.getY();
    	
    	    // Second verification:
            for(Iterator it=keys.iterator();it.hasNext();){
                gc2=n.getComponent((String)(it.next()));
    	        if (gc2!=gc){
    	            if (gc2 instanceof LinkableComponent){
    	                lc=(LinkableComponent)gc2;
    	    	        tempx=gc2.getX()+(int)Math.round(lc.giveWidth()*lc.u);
    	    	        tempy=gc2.getY()+gc2.getHeight();
    	            	
    	            } else {
    	    	        tempx=gc2.getX()+gc2.getWidth();
    	    	        tempy=gc2.getY()+gc2.getHeight();
    	    	    }
    	    	
    	    	    if ((tempx>maxX)&&(tempy>maxY)){
    	    	        maxY=tempy;
    	    	    }
    	        }
    	    }
    	}
    	
    	
    	GraphicPanel gp=(GraphicPanel)gc.getParent();
    	
    	int maxFrameWidth=(gp==null)?(ComponentInternalFrame.GRAPHICPANEL_WIDTH):(gp.getWidth());
    	int maxFrameHeight=(gp==null)?(ComponentInternalFrame.GRAPHICPANEL_HEIGHT):(gp.getHeight());
        
    	
    	//necessary true
    	if (gc instanceof LinkableComponent){
    	    lc=(LinkableComponent)gc;
            if (maxFrameWidth<gc.WIDTH) maxFrameWidth=gc.WIDTH;
            if ((maxX+gc.WIDTH)<=maxFrameWidth)
    	        gc.setLocation(maxX+GAP_X/*+(int)Math.round((lc.giveWidth()-lc.w0)*lc.u)*/,maxY);
    	    else gc.setLocation(GAP_X/*+(int)Math.round((lc.giveWidth()-lc.w0)*lc.u)*/,maxmaxY+GAP_Y);
    	    lc.backupX=lc.getX();
    	    lc.backupY=lc.getY();
    	} else {
            if (maxFrameWidth<gc.WIDTH) maxFrameWidth=gc.WIDTH;
            if ((maxX+gc.WIDTH)<=maxFrameWidth)
    	        gc.setLocation(maxX+GAP_X,maxY);
    	    else gc.setLocation(GAP_X,maxmaxY+GAP_Y);
    		
    	}

        if ((gp!=null)&&((gc.getY()+gc.getHeight())>=maxFrameHeight)){
            gp.setPreferredSize(new Dimension(maxFrameWidth,gc.getY()+gc.getHeight()));
            gp.revalidate();
        }

    }
    
    //----------------------------------------------------------------
    //           From the TreePath to the GenericComponent
    //----------------------------------------------------------------
    
    /**
     * Converts a TreePath to a String (which is the name of a 
     * GenericComponent).
     */
    public static String treePathToString(TreePath treePath) {
    	/*System.out.println("inside treePathToString()");
  
    	String mesg =   "Component Name: "+ (String)(((DefaultMutableTreeNode)(treePath.getLastPathComponent())).getUserObject());  
        System.out.println(mesg);*/

        //JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);
        return (String)(((DefaultMutableTreeNode)(treePath.getLastPathComponent())).getUserObject());    	
    		
    }
    
    /**
     * Converts a TreePath to a String (which is the name of a 
     * GenericComponent)
     */
    public static String treePathToString(TreePath treePath,int i){
    		String mesg =   "Component Name: "+i+ (String)(((DefaultMutableTreeNode)(treePath.getLastPathComponent())).getUserObject());  
        System.out.println(mesg);

    		//JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);

        return (String)(((DefaultMutableTreeNode)(treePath.getPathComponent(i))).getUserObject());    	
    }
        
    /**
     * Check in the register if the Treepath leads to a leaf.
     */
    public static boolean isLeaf(TreePath treePath){
    	return !skeleton.hasChildNode(treePathToString(treePath));
    }

    /**
     * True if the TreePath leads to the root.
     */
    public static boolean isRoot(TreePath treePath){
    	return (skeleton.isRoot(treePathToString(treePath)));
    }

    /**
     * Returns all the GenericComponents in a given branch. 
     * Null if the node has no branch (leaf) or if the last component is not is the tree.
     */
    public static GenericComponent [] fetchComponents(TreePath treePath) {
    	String name1 = treePathToString(treePath);
    	
    	if (skeleton.hasChildNode(name1)) {
    	    Node firstCurrentNode = skeleton.toChildNode(name1);
    	    
    	    if (firstCurrentNode.isEmpty()) return null;
    	    else {
    	        /*Set keys = firstCurrentNode.keySet();
    	        GenericComponent [] result = new GenericComponent[keys.size()];
    	        
    	        int count = 0;
                for(Iterator it = keys.iterator();it.hasNext();)
	            	result[count++] = firstCurrentNode.getComponent((String)(it.next()));*/
	            	
	            int numComponents = firstCurrentNode.getNumCouples();
    	        GenericComponent [] result = new GenericComponent[numComponents];

    	        Set keys = firstCurrentNode.keySet();
    	        int count = 0;
    	        String name;
    	        Integer childID;
    	        
                for (Iterator it = keys.iterator();it.hasNext();) {
                	name = (String)it.next();
                	
			        for (Iterator itID = firstCurrentNode.getIDIterator(name);itID.hasNext();) {
	    		    	childID = (Integer)itID.next();

				        result[count++] = firstCurrentNode.getComponent(name,childID);
			        }
                }
	            	
	        	return result;
    	    }
    	}
    	else return null; // Nothing inside this component
    }	

  
    //---------------------------------------------------------------
    //               From a GenericComponent to a TreePath
    //---------------------------------------------------------------
  
    /**
     * Return the position in the JTree of a GenericComponent,
     * null if the component is not in the tree.
     */
    /*public static TreePath fetchTreePath(GenericComponent c){
	return fetchTreePath(c.getName());
    }*/

    /**
     * Return the position in the JTree of a GenericComponent,
     * null if the component is not in the tree.     
     *
     * return nodes array from parentS to c given tree
     *
     */
    public static TreePath fetchTreePath(String taskName,String parentS,MainTree tree) {
    	if (skeleton.isInTree(taskName)) {
    	    DefaultMutableTreeNode [] tab;
    	    
    	    if (skeleton.isRoot(taskName)){
                tab = new DefaultMutableTreeNode[1];                
                tab[0] = (DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();      
            } else {
                // Create a String Stack
                Stack s = new Stack();
                
                s.push(taskName);
                s.push(parentS);
                
                String name = taskName;
                String parentName = parentS;
                TreeMap t;
                while (!parentName.equals(skeleton.ROOT_STRING)) {
    	            t = (TreeMap)skeleton.nodeRegister.get(parentName);
    	            name = parentName;
    	            parentName = (String)t.firstKey();
                    s.push(parentName);
                }
                //The Stack is now filled
            
                tab = new DefaultMutableTreeNode[s.size()];                
                DefaultMutableTreeNode jcurrent = 
                	(DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();
        
                String rootString = (String)s.pop();        // take out the ROOT_STRING "/"
                tab[0]=jcurrent;
                for (int i=1;i<tab.length;i++) {
                    String ref = (String)s.pop();

                    int count = 0;
                    for (Enumeration e = jcurrent.children();e.hasMoreElements();) {
             	        String temp = (String)((DefaultMutableTreeNode)(e.nextElement())).getUserObject();
             	        
             	        if (ref.equals(temp))
             	  	    	break;
             	        count++;
                    }

                    jcurrent = (DefaultMutableTreeNode)jcurrent.getChildAt(count);
                    
                    tab[i] = jcurrent;             
                } 
            }
            return (new TreePath(tab)); 
        }
        else return null;           	
    }

    public static TreePath fetchTreePath(String taskName,String parentS,MainTree tree,Integer id2) {
    	if (skeleton.isInTree(taskName)) {
    	    DefaultMutableTreeNode [] tab;
    	    
    	    if (skeleton.isRoot(taskName)){
                tab = new DefaultMutableTreeNode[1];                
                tab[0] = (DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();      
            } else {
                // Create a String Stack
                Stack s = new Stack();
                
                s.push(taskName);
                s.push(parentS);
                
                String name = taskName;
                String parentName = parentS;
                TreeMap t;
                while (!parentName.equals(skeleton.ROOT_STRING)) {
    	            t = (TreeMap)skeleton.nodeRegister.get(parentName);
    	            name = parentName;
    	            parentName = (String)t.firstKey();
                    s.push(parentName);
                }
                //The Stack is now filled
                
                int positionForDuplicatedTasks = skeleton.getPositionForDuplicatedTasks(taskName,parentS,id2);
            
                tab = new DefaultMutableTreeNode[s.size()];                
                DefaultMutableTreeNode jcurrent = 
                	(DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();
        
                String rootString = (String)s.pop();   // take out the ROOT_STRING "/" which corresponds to jcurrent
                tab[0]=jcurrent;
                
                for (int i=1;i<tab.length;i++) {
                    String ref = (String)s.pop();

                    //find index (stores in count) within jcurrent which points at ref
                    int count = 0;
                    for (Enumeration e = jcurrent.children();e.hasMoreElements();) {
             	        String temp = (String)((DefaultMutableTreeNode)(e.nextElement())).getUserObject();
             	        
             	        if (i == (tab.length-1)) {
             	        	// last node corresponding to taskName : 
             	        	// need to point to corresponding duplicated task
             	        	if (ref.equals(temp)) {
             	        		positionForDuplicatedTasks--;
             	        		if (positionForDuplicatedTasks == 0)
             	        			break;
             	        	}
             	        }
             	        else {
             	        	// same as before
             	        	if (ref.equals(temp))
             	  	    		break;
             	        }
             	        
             	        count++;
                    }

                    jcurrent = (DefaultMutableTreeNode)jcurrent.getChildAt(count);
                    
                    tab[i] = jcurrent;             
                } 
            }
            return (new TreePath(tab)); 
        }
        else return null;           	
    }

    /**
     * Return the position in the JTree of a GenericComponent,
     * null if the component is not in the tree.     
     */
    public static TreePath fetchTreePath(String c,MainTree tree) {
    	if (skeleton.isInTree(c)){
    	    DefaultMutableTreeNode [] tab;
    	    if (skeleton.isRoot(c)){
                tab=new DefaultMutableTreeNode[1];                
                tab[0]=(DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();      
            } else {
                // Create a String Stack
                Stack s=new Stack();
                s.push(c);
                String name=c;
                TreeMap t;
                while (!name.equals(skeleton.ROOT_STRING)) {
    	            t=(TreeMap)skeleton.nodeRegister.get(name);
    	            name=(String)t.firstKey();
                    s.push(name);
                }
                //The Stack is now filled
                //System.out.println("fetchTreePath --> "+s);
            
                tab=new DefaultMutableTreeNode[s.size()];                
                DefaultMutableTreeNode jcurrent=(DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();
        
                s.pop();        
                tab[0]=jcurrent;
                for (int i=1;i<tab.length;i++) {
                    //System.out.println("tour: "+i);
                    String ref=(String)s.pop();              
                    int count=0;
                    for (Enumeration e=jcurrent.children();e.hasMoreElements();){
             	        String temp=(String)((DefaultMutableTreeNode)(e.nextElement())).getUserObject();
             	        //System.out.println("ref="+ref+"   temp="+temp);
             	        if (ref.equals(temp))
             	  	    break;
             	        count++;
                    }
                    jcurrent=(DefaultMutableTreeNode)jcurrent.getChildAt(count);
                    tab[i]=jcurrent;             
                } 
            }
            return (new TreePath(tab)); 
        } else return null;           	
    }

    /**
     * Truncate the last object from the treePath.
     */
    public static TreePath truncTreePath(TreePath treePath){
    	int nb=treePath.getPathCount();
    	if (nb>1){
            Object [] o=treePath.getPath();
            Object [] o2=new Object[nb-1];
            for (int i=0;i<nb-1;i++) o2[i]=o[i];
            return (new TreePath(o2));
        }
    	else return null;
    }



    //Composite component fix 8-19-99
    public static void openAllFramesInternaly(){
    	openFramesInternaly(skeleton.ROOT_STRING,skeleton.root);
    }

    private static void openFramesInternaly(String s,Node node){
        Set set=node.keySet();
        GenericComponent [] tab=new GenericComponent[set.size()];
        LinkedList children=new LinkedList();
        int count=0;
        String name;
        int childCount=0;
        Node child;
        for (Iterator i=set.iterator();i.hasNext();count++){
            name=(String)i.next();
            tab[count]=node.getComponent(name);
            if (node.hasBranch(name)) {
            	children.add(name);
            	children.add(node.getChild(name));
            	childCount++;
            }
        }
        desktop.openFrame(s,tab);
        for (int i=0;i<childCount;i++){
            name=(String)children.removeFirst();
            child=(Node)children.removeFirst();
            openFramesInternaly(name,child);
        }
    }

    public static void openAllInvisibleFramesInternaly(){
    	openInvisibleFramesInternaly(skeleton.ROOT_STRING,skeleton.root);
    }

    private static void openInvisibleFramesInternaly(String s,Node node){
        Set set=node.keySet();
        GenericComponent [] tab=new GenericComponent[set.size()];
        LinkedList children=new LinkedList();
        int count=0;
        String name;
        int childCount=0;
        Node child;
        for (Iterator i=set.iterator();i.hasNext();count++){
            name=(String)i.next();
            tab[count]=node.getComponent(name);
            if (node.hasBranch(name)) {
            	children.add(name);
            	children.add(node.getChild(name));
            	childCount++;
            }
        }
        desktop.openInvisibleFrame(s,tab);
        for (int i=0;i<childCount;i++){
            name=(String)children.removeFirst();
            child=(Node)children.removeFirst();
            openInvisibleFramesInternaly(name,child);
        }
    }

    //tape_recorder
    public static boolean fileSaved() {
        if (FileManager.MODIFIED) {
            int choice;
            
            if (guiEnableFlag) {
                //String name=(String)alist.getSelectedValue();                
                String [] options={"Yes","No","Cancel"};
                choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,
                    "Save changes made to '"+FileManager.FILE_NAME+"' ?","Warning",
                    JOptionPane.YES_NO_CANCEL_OPTION,JOptionPane.WARNING_MESSAGE,null,
                    options,options[0]);
            }
            else
                choice = 0;
            
            if (choice==0) {
            	//save();
            	//return true;
            	return save();
            }
            else if (choice==1) {
            	FileManager.MODIFIED=false; 
				return true;
	    	}
            else return false;
         }
         else return true;
	}

    public static boolean fileSavedForXSL() {
        if (FileManager.MODIFIED) {
            String [] options={"Yes","No","Cancel"};
            int choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,
                "To generate HTML from XSL, the changes must be saved in XML first.\n\n"+
                "Save changes made to '"+FileManager.FILE_NAME+"' ?","Warning",
                JOptionPane.YES_NO_CANCEL_OPTION,JOptionPane.WARNING_MESSAGE,null,
                options,options[0]);
            
            if (choice==0) {
                return save();
            }
            else return false;
         }
         else return true;
    }
        
    public static   TreeMap getTaskAttributesBool() {
     	return taskAttributesBool;
  	}
     
        
     public static void setHTML()
     {
     	HTMLReportSettingDialog dialog = new HTMLReportSettingDialog(Manager.getTaskAttributesBool());
     	
     }
     
     public static void LGlogin()
     {
     	System.out.println ( "selected LG login:");
     	
     }

     public static void LGhelp  ()
     {
     	// System.out.println ( "selected LG Help");
         String helpInfor = "There is no reponse from the server. \n"+
                           "Please start the Language Generation server first!!!";


         final JFileChooser fc=new JFileChooser(fileManager.getFolder());
         fc.addChoosableFileFilter(new LGFilter());
         fc.setFileView(new LGFileView());
         if (fileManager.CURRENT_EXP != null) fc.setSelectedFile(fileManager.CURRENT_EXP);
         String approveButtonText="Generate";
         int returnVal=fc.showDialog(MainFrame.mainFrame,approveButtonText);
								//MainFrame.mainFrame);
         if (returnVal==JFileChooser.APPROVE_OPTION) {
             File f=fc.getSelectedFile();
             
             //FOLDER = f.getParent();
             //FILE_NAME = f.getName();  
             fileManager.CURRENT_EXP =f;          
             
             javax.swing.filechooser.FileFilter ff=fc.getFileFilter();
             if (ff instanceof LGFilter)
             {
             
                try
                {

                   //Properties props= new Properties();
                  /* String key = "file.separator";
                   String value = "/";
                   System.setProperty( key,  value) ;
                  */

                   LGServer lgServer= new LGServer();
                   lgServer.connect(lgServer.getLGServerName(), lgServer.getDEFAULT_portNumber() );

                   String fullPathName = fileManager.CURRENT_EXP.getCanonicalPath();
                   fullPathName = relpaceBackSlashWithForwardSlash(fullPathName);


                   //JOptionPane.showMessageDialog(MainFrame.mainFrame,fullPathName );
             
                   lgServer.generateOLP(fullPathName);
                } catch (UnknownHostException e)
                {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);
                } catch (IOException e)
                {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);
                } catch (InterruptedException e)
                {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);}


             }
         }

     
     
      }


     protected static String relpaceBackSlashWithForwardSlash(String s){
           
          int m = s.length();
          if (m == 0) return  s;

          StringBuffer sb=new StringBuffer("");
          for (int i = 0; i<m;i++ )
          {
              if (s.charAt(i) == '\\')  sb.append('/');
              else sb.append(s.charAt(i));

          }


          return sb.toString();

     }

      //exportGenerateLG()

    public static void exportGenerateLG(){
    	if (fileManager.exportGenerateLG()) {  
	    	//System.out.println ( fileManager.FILE_NAME);
	        System.out.println ( fileManager.CURRENT_EXP.getAbsolutePath());
	
	        String helpInfor = "There is no reponse from the server. \n"+
	                           "Please start the Language Generation server first!!!";
	                           
	       try  
	       {
	
	          LGServer lgServer= new LGServer();
	          lgServer.connect(lgServer.getLGServerName(), lgServer.getDEFAULT_portNumber() );
	          String fullPathName = fileManager.CURRENT_EXP.getCanonicalPath();
	          
	          fullPathName = relpaceBackSlashWithForwardSlash(fullPathName);
	      
	          //JOptionPane.showMessageDialog(MainFrame.mainFrame,fullPathName ); 
	      
	          lgServer.generateOLP(fullPathName);
	       } catch (UnknownHostException e)
	       {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);
	       } catch (IOException e)
	       {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);  
	       } catch (InterruptedException e)
	       {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);}
	       
	       
	        // code to add for text view - kvlinden, 22feb00 
       		//     probably should check the feedback from generateOLP() before doing this...
       		String fileroot = fileManager.CURRENT_EXP.getAbsolutePath();
       		desktop.openTVFrame("TV", 
			   fileroot.substring(0, fileroot.lastIndexOf('.')) + ".html");

    	}

    }
    

    public static void setLGServerName(){
        MainFrame.mainFrame.repaint();
        LGserverDialog dialog=new LGserverDialog();


   }
   
    public static void markTaskDirty(String taskName, boolean b) {
		if (Manager.skeleton.isInRegister(taskName)){
        	Node n=Manager.skeleton.getFirstNode(taskName);
           	GenericComponent geC = n.getComponent(taskName);
           	if (geC instanceof Task) {
              	((Task)geC).dirty=b;
                 //System.out.println(" This rthe task name: "+ geC.getName());
             }
         }   
    }
    
   public static void openHTMLView() {
        fileManager.openHTMLView();
   }

   public static void openHelpContents() {
        fileManager.openHelpContents();
   }
   
   
   	/**
	* return a reference of the XMamager xDm (domain model Xmanager)
	*/
	public static XManager getXDM(){
		return xDm;
	}//getXDM()
	
	/**
	* set the XMamager xDm (domain model Xmanager) to aX
	*/
	public static void setXDM(XManager aX){
		xDm = aX;
	}//setXDM()
	
	//Shijian
	//2001-2-12
    public static void newECon(){
    	xDm.getDmManager().newECon();
    }
    
  	//Shijian 2001-2-12
    public static void newACon(){
    	xDm.getDmManager().newACon();
    }
    
  	//Shijian 2001-2-12
    public static void newEIns(){
    	xDm.getDmManager().newEIns();
    }
    
  	//Shijian 2001-2-12
    public static void newAIns(){
    	xDm.getDmManager().newAIns();
    }
    
  	//Shijian 2001-2-12
    public static void newERels(){
    	xDm.getDmManager().newERels();
    }
    
  	//Shijian 2001-2-12
    public static void newARels(){
    	xDm.getDmManager().newARels();
    }
    
  	//Shijian 2001-2-12
    public static void editDM(){
    	xDm.getDmManager().editDM();
    }
    
  	//Shijian 2001-2-12
    public static void createDMAll(){
    	xDm.getDmManager().createDMAll();
    }
    
  	//Shijian 2001-2-12
    public static void createDMIfNil(){
    	xDm.getDmManager().createDMIfNil();
    }
    
  	//Shijian 2001-2-12
    public static void markDirty(){
    	xDm.getDmManager().markDirty();
    }
    
  	//Shijian 2001-2-12
    public static void markClean(){
    	xDm.getDmManager().markClean();
    }
    
  	//Shijian 2001-2-12
    public static void clearDMAll(){
    	xDm.getDmManager().clearDMAll();
    }
    
	//shijian 2001-2-13
  public static Collection getAllTask(){
  	SortArrayList sv = new SortArrayList (new GCCompare());
  	
    Set compSet=new TreeSet();
  	Set set=Manager.skeleton.nodeRegister.keySet();
  	GenericComponent gc;
  	String name;
  	for (Iterator i=set.iterator();i.hasNext();){
          String pName= (String) i.next();
  	    gc=Manager.skeleton.stringToFirstGenericComponent(pName);   
  	    name=gc.getName();
          
   	    if (!compSet.contains(name)){
  	    	compSet.add(name);
   	    	if ( gc instanceof Task) {
				sv.add(gc);
   	    	}
  	    }
  	}
  	
	sv.sort(); 
	return Collections.unmodifiableCollection(sv);
  	
  }
	
  //shijian 2001-3-28
  public static Collection getAllLink(){
  	ArrayList sv = new ArrayList ();
  	
    Set compSet=new TreeSet();
  	Set set=Manager.skeleton.nodeRegister.keySet();
  	GenericComponent gc;
  	String name;
  	for (Iterator i=set.iterator();i.hasNext();){
          String pName= (String) i.next();
  	    gc=Manager.skeleton.stringToFirstGenericComponent(pName);   
  	    name=gc.getName();
          
   	    if (!compSet.contains(name)){
  	    	compSet.add(name);
   	    	if ( gc instanceof Link) {
				sv.add(gc);
   	    	}
  	    }
  	}
  	
	return Collections.unmodifiableCollection(sv);
  	
  }
  
  //shijian 2001-3-28
  public static Collection getAllBoolConnector(){
  	ArrayList sv = new ArrayList ();
  	
    Set compSet=new TreeSet();
  	Set set=Manager.skeleton.nodeRegister.keySet();
  	GenericComponent gc;
  	String name;
  	for (Iterator i=set.iterator();i.hasNext();){
          String pName= (String) i.next();
  	    gc=Manager.skeleton.stringToFirstGenericComponent(pName);   
  	    name=gc.getName();
          
   	    if (!compSet.contains(name)){
  	    	compSet.add(name);
   	    	if ( gc instanceof BooleanConnector) {
				sv.add(gc);
   	    	}
  	    }
  	}
  	
	return Collections.unmodifiableCollection(sv);
  	
  }
  
  	//Shijian 2001-2-20
    // remove semantics (set semantics to nil "")
    // ta is a collection of tasks
    public static void removeSemantics(Collection ta){
    	
		Iterator it = ta.iterator();
		Task t;
		while (it.hasNext()) {
			t= (Task)it.next();
			t.setSemantics("");	
		}
    }
    
  	//Shijian 2001-3-28
    // remove Action Instance refereneces for 
    // semantics, precondition, and feedback 
    // ta is a collection of tasks
    public static void removeTaskDomain(Collection ta){
    	
		Iterator it = ta.iterator();
		Task t;
		while (it.hasNext()) {
			t= (Task)it.next();
			t.setSemantics("");	
			t.setPreconDM("");	
			t.setFeedbackDM("");	
		}
    }
    
  	//Shijian 2001-3-28
    // remove Action Instance refereneces for 
    // link precondition  
    // ls is a collection of links
    public static void removeLinkDomain(Collection ls){
    	
		Iterator it = ls.iterator();
		Link l;
		while (it.hasNext()) {
			l= (Link)it.next();
			l.setPreconDM("");	
		}
    }
    
  	//Shijian 2001-3-28
    public static void inherentParentActor(Task t, Task parent){
    	String actor = parent.getActor();
    	if (actor != null && actor != ""){
    		t.setActor(actor);
    	}
    	
    	return;
    }
    
  	//Shijian 2001-4-17
    public static void findPredecessorComponents(LinkableComponent lc){
    	
    	//first find linked components
    	findLinkedComponents(lc);
    	
    	//now find all parents
    	String name = lc.getName();
    	Set se = skeleton.getAllParents(name);
    	if (se == null) return;
    	
    	Iterator it = se.iterator();
    	
    	GenericComponent gcTemp;
    	String parentName;
    	while (it.hasNext()){
    		parentName = (String) it.next();
    		//System.out.println("(parent name): " + parentName);
    		if (!skeleton.isRoot(parentName)){
	
				GenericComponent [] gcs = skeleton.getComponents(parentName);
				int size = gcs.length;
	
	    		if (size >0){
					for (int i=0;i<size;i++) {
						gcTemp = gcs[i];
	   	    			addPredecessor(gcTemp);	   	    			
	   	    			//find parent's parent
	   	    			findPredecessorComponents((LinkableComponent)gcTemp);
					}
		        	
		        }
    		}
    	}
    	return;
    }
    
  	//Shijian 2001-4-17
    private static void findLinkedComponents(LinkableComponent lc){
    	Vector links = lc.getLinks();
    	int size = links.size();
    	Link l;
    	LinkableComponent lc1;
        for (int i=size-1;i>=0;i--) {
    	    l=(Link)links.elementAt(i);
    	    if ((l.getSecondLC()).equals(lc)){
     	    	lc1=l.getFirstLC();
     	    	
   	    		addPredecessor(l);
   	    		if (! isPredecessor(lc1)){ // stop after one loop if it is circular
	     	    	addPredecessor(lc1);
	    			//System.out.println("predecessor:(linked) " + lc1.getName());
	     	    	findLinkedComponents(lc1);
   	    		}
   	    	}	
        }
    	return;
    }
    
  	//Shijian 2001-4-17
    public static void resetPredecessorStore(){
    	_predecessorComponents.clear();
    	return;
    }
    
  	//Shijian 2001-4-17
    public static Collection getAllPredecessors(){
		_predecessorComponents.sort(); 
		return Collections.unmodifiableCollection(_predecessorComponents);
    }
    
  	//Shijian 2001-4-17
    public static void addPredecessor(GenericComponent gc){
		_predecessorComponents.add(gc); 
		return;
    }
  	//Shijian 2001-4-17
    public static void printPredecessors(){
    	Collection col = getAllPredecessors();
    	Iterator it = col.iterator();
    	GenericComponent gc;
    	while (it.hasNext()){
    		gc = (GenericComponent) it.next();
    		System.out.println("predecessor: " + gc.getName());
    	}
		return;
    }
    
  	//Shijian 2001-4-18
    public static boolean isPredecessor(GenericComponent gc){
    	
    	return _predecessorComponents.contains(gc);
    }
    
  	//Shijian 2001-4-18
    public static void resetSuccessorStore(){
    	_successorComponents.clear();
    	return;
    }
    
  	//Shijian 2001-4-18
    public static boolean isSuccessor(GenericComponent gc){
    	
    	return _successorComponents.contains(gc);
    }
    
  	//Shijian 2001-4-18
    public static void addSuccessor(GenericComponent gc){
		_successorComponents.add(gc); 
		return;
    }
  	//Shijian 2001-4-18
    public static void printSuccessors(){
    	Collection col = getAllSuccessors();
    	Iterator it = col.iterator();
    	GenericComponent gc;
    	while (it.hasNext()){
    		gc = (GenericComponent) it.next();
    		System.out.println("Successor: " + gc.getName());
    	}
		return;
    }
    
  	//Shijian 2001-4-18
    public static Collection getAllSuccessors(){
		return Collections.unmodifiableCollection(_successorComponents);
    }
    	
  	//Shijian 2001-4-18
    private static void findChildrenComponents(LinkableComponent lc){
    	
    	//findSiblingComponents(lc);
    	
    	Node nodeParent = skeleton.getFirstNode(lc.getName());
    	Couple c=nodeParent.getCouple(lc.getName());
    	Node node = c.node;
    	
    	if (node == null) return;
    	
    	Set keys=node.keySet();
    	LinkableComponent lc1;
    	String childName;
   	
    	if (keys.size() <= 0) return;
    	
    	for (Iterator it=keys.iterator();it.hasNext();){
            childName=(String)it.next();
    	    c=node.getCouple(childName);
    	    
   	    	if (c.object instanceof LinkableComponent){
    	    	lc1=(LinkableComponent)c.object;
    	    	if (isFirstComponent(lc1)){
	   	    		if (! isSuccessor(lc1)){ 
		     	    	addSuccessor(lc1);
	 	    			findSuccessorComponents(lc1);
	   	    		}
    	    	}
   	    	}
   	    	
    	}
    	return;
    }
    
  	//Shijian 2001-4-18
    public static void findSuccessorComponents(LinkableComponent lc){
    	findChildrenComponents(lc);

    	Vector links = lc.getLinks();
    	int size = links.size();
    	Link l;
    	LinkableComponent lc2;
        for (int i=size-1;i>=0;i--) {
    	    l=(Link)links.elementAt(i);
    	    if ((l.getFirstLC()).equals(lc)){
     	    	lc2=l.getSecondLC();
     	    	
   	    		addSuccessor(l);
   	    		if (! isSuccessor(lc2)){ // stop after one loop if it is circular
	     	    	addSuccessor(lc2);
	    			//System.out.println("child:(linked) " + lc2.getName());
	     	    	findSuccessorComponents(lc2);
	     	    	findChildrenComponents(lc2);
   	    		}
   	    	}	
        }
    	return;
    }
    
    private static boolean isFirstComponent(LinkableComponent lc){
    	boolean result=true;
    	int nb=lc.linkList.size();
    	Link l;
    	for (int i=0;i<nb;i++){
    	    l=(Link)lc.linkList.elementAt(i);
    	    if (l.lc2==lc) {
    	    	result=false;
    	    	break;
    	    }
    	}
    	return result;
    }
    		
    
  	//Shijian 2001-4-20
    public static void findPrecComLink(Link l){
    	LinkableComponent lc=l.getFirstLC();
		if (! isPredecessor(lc)){ 
	    	addPredecessor(lc);
	    	findPredecessorComponents(lc);
		}
    }
    
  	//Shijian 2001-4-20
    public static void findPrecComs(GenericComponent gc){
    	
    	if (gc instanceof LinkableComponent){
    		LinkableComponent lc=(LinkableComponent)gc;
    		findPredecessorComponents(lc);
    	}else if (gc instanceof Link){
    		Link l = (Link) gc;
    		findPrecComLink(l);
    	}
    	
    	return;
    }
    
  	//Shijian 2001-4-20
    public static void findSuccComs(GenericComponent gc){
    	
    	if (gc instanceof LinkableComponent){
    		LinkableComponent lc=(LinkableComponent)gc;
    		findSuccessorComponents(lc);
    	}else if (gc instanceof Link){
    		Link l = (Link) gc;
    		findSuccComLink(l);
    	}
    	
    	return;
    }
    
  	//Shijian 2001-4-20
    public static void findSuccComLink(Link l){
    	LinkableComponent lc=l.getSecondLC();
		if (! isSuccessor(lc)){ 
	    	addSuccessor(lc);
	    	findSuccessorComponents(lc);
		}
    }
    
  	//Shijian 2001-4-20
    // return true, if any of the component in col is either 
    //a predecessor or successor of gc
    public static boolean isRelated(GenericComponent gc, Collection col){
    	
    	if (gc == null) return false;
    	
		//find predecessors
    	resetPredecessorStore();
		findPrecComs(gc);
		printPredecessors();
		//find successors
		resetSuccessorStore();
		findSuccComs(gc);
		printSuccessors();
		
		Iterator it = col.iterator();
		while (it.hasNext()) {
			gc= (GenericComponent)it.next();
			if ( isPredecessor(gc) || isSuccessor(gc))
				return true;	
		}
		
		return false;

    }
    
}