/*
 * Report.java
 *
 *  iReport  --  Visual designer for generating JasperReports Documents
 *  Copyright (C) 2002  Giulio Toffoli gt@businesslogic.it
 *
*  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.Styl
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Giulio Toffoli
 *  Via T.Aspetti, 233
 *  35100 Padova ITALY
 *  gt@businesslogic.it
 *
 * Created on 10 febbraio 2003, 19.32
 * 
 * Updated by Robert Lamping:
 * dtd updated with the new package path net/sf/  etc...
 * Added Try catch to catch a missing dtd.
 * Changed Mainframe.openFile to catch this exception and stop opening a file in case of an exception.
 */

package it.businesslogic.ireport;

//import java.util.*;
import it.businesslogic.ireport.crosstab.CrosstabParameter;
import it.businesslogic.ireport.gui.event.ReportDocumentStatusChangedEvent;
import it.businesslogic.ireport.gui.event.ReportSubDatasetChangedEvent;
import java.io.ByteArrayInputStream;
import java.util.Vector;
import java.util.Iterator;
import java.util.Properties;
import java.util.Enumeration;

//import it.businesslogic.ireport.util.*;
import it.businesslogic.ireport.util.Misc;
import it.businesslogic.ireport.util.PageSize;
import it.businesslogic.ireport.gui.JReportFrame;
import it.businesslogic.ireport.chart.*;
import it.businesslogic.ireport.crosstab.CrosstabCell;
import it.businesslogic.ireport.crosstab.CrosstabColumnGroup;
import it.businesslogic.ireport.crosstab.CrosstabGroup;
import it.businesslogic.ireport.crosstab.CrosstabRowGroup;
import it.businesslogic.ireport.crosstab.Measure;
import it.businesslogic.ireport.gui.event.StyleChangedEvent;
import it.businesslogic.ireport.gui.event.SubDatasetObjectChangedListener;


import org.apache.xerces.parsers.DOMParser;

//import org.w3c.dom.*;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.File;
import java.io.PrintWriter;

/**
 *
 * @author  Administrator
 */
public class Report extends SubDataset implements SubDatasetObjectChangedListener {
    
    public static int SCRIPTLET_IREPORT_INTERNAL_HANDLING = 1;
    public static int SCRIPTLET_NOT_USED = 0;
    public static int SCRIPTLET_CLASSIC_HANDLING = 2;
    
    private int nextGroupId = 0;
    
    private IReportFont defaultFont = new IReportFont();
    
    private boolean readOnly = false;
    
    private int height = 0;
    
    private int width = 0;
        
    private Vector elements = new Vector();
    
    private Vector bands = new Vector();
    
    private Vector imports = new Vector();
    
    private String filename = "";
    
    private Vector subDatasets = new Vector();
    
    private String encoding = "UTF-8";
    
    private int columnCount = 1;
    
    private String printOrder = "Vertical";
    
    private String orientation = "Portrait";
    
    private String whenNoDataType = "NoPages";
    
    private int columnWidth = 535;
    
    private int columnSpacing = 0 ;
    
    private int leftMargin = 20;
    
    private int rightMargin = 20;
    
    private int topMargin = 30;
    
    private int bottomMargin = 30;
    
    private boolean isTitleNewPage = false;
    
    private boolean isSummaryNewPage = false;
    
    private long loadTime = 0;
    
    private Vector fonts = new Vector();
    
    private Vector styles = new Vector();
    
    private JReportFrame reportFrame;
    
    private String reportFormat;
    
    static int untitledId = 1;
    
    private int reportChanges = 1; // By default, a report is changed...
    
    private boolean floatColumnFooter = false;
    
    private boolean ignorePagination = false;  
    
    /** used to tell the report when outputting to XML that it needs to set isCode="true" in expressions */
    protected boolean usingMultiLineExpressions = false;
    
    private String language = "java";
    
    private ScriptletCode scripletCode;
    
    private int scriptletHandling = 2;

     private java.util.HashMap proposedValues = null;
     
     private boolean loadingFile = false;
          
    /** Creates a new instance of Report */
    
    public Report() {
        super();
        setName("Untitled_report_" + untitledId);
        untitledId++;
        
        proposedValues = new java.util.HashMap();
        // Add basic variables...
        
        
        getKeywordLookup().addKeyword("$R{*}");
        
        //addParameter(new JRParameter("COLUMN_COUNT", "", ));
        
        bands.addElement( new Band(this,"background",0) );
        bands.addElement( new Band(this,"title", 50));
        bands.addElement( new Band(this,"pageHeader", 50) );
        bands.addElement( new Band(this,"columnHeader",30) );
        bands.addElement( new Band(this,"detail",100));
        bands.addElement( new Band(this,"columnFooter",30) );
        bands.addElement( new Band(this,"pageFooter",50));
        bands.addElement( new Band(this,"lastPageFooter",50));
        bands.addElement( new Band(this,"summary",50) );
        
        //addImport("it.businesslogic.ireport.IReportScriptlet");
        addImport("java.util.*");
        addImport("net.sf.jasperreports.engine.*");
        addImport("net.sf.jasperreports.engine.data.*");
        
        try {
            scripletCode = new ScriptletCode(ScriptletCode.class.getClassLoader().getResourceAsStream("scriptlet_template.jav"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        
        // Set the user option default...
        this.setLanguage( it.businesslogic.ireport.gui.MainFrame.getMainInstance().getProperties().getProperty("DefaultScriptingLanguage","java") );
    
        this.addSubDatasetObjectChangedListener(this);
    }

    /** Creates a new instance of Report reading it by a file...*/
    public Report(String xmlFile) throws Exception {

        this();
        
        // Set the real default...
        this.setLanguage("java");
        untitledId--;

        //reset bands, prevents page height overflow for unused bands
        for(int i = 0; i < bands.size(); i++) {
            ((Band)bands.elementAt(i)).setHeight(0);
        }
        
        try {

                
                java.io.InputStream input_source = null;

                
                if (xmlFile.toLowerCase().endsWith(".jasper")) {

                    java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();                
                    // 1. We havo to load the design...
                    net.sf.jasperreports.engine.JasperReport jreport = net.sf.jasperreports.engine.JasperManager.loadReport(xmlFile);
                    net.sf.jasperreports.engine.JasperCompileManager.writeReportToXmlStream(jreport, bos);
                    input_source = new ByteArrayInputStream(bos.toByteArray());

                } else {

                    //  Create a Xerces DOM Parser
                    //  Parse the Document
                    //  and traverse the DOM

                    this.setFilename(xmlFile);
                    checkReadOnlyFlag();

                    // set load time...
                    this.setLoadTime( Misc.getLastWriteTime( xmlFile ));

                    File ffile = new File(xmlFile);
                    if (ffile.exists())
                    {
                        input_source = new java.io.FileInputStream(ffile);

                    } else {

                        input_source = this.getClass().getClassLoader().getResourceAsStream(xmlFile);
                    }
                    
                    // Change to the file directory...
                    
                }
                
                
                
                DOMParser parser = new DOMParser();
                
                parser.setEntityResolver( new org.xml.sax.EntityResolver() {
                    
                    /* Code by Teodor Danciu */
                    public org.xml.sax.InputSource resolveEntity( String publicId, String systemId )
                           throws SAXException, IOException
                    {
                        org.xml.sax.InputSource inputSource = null;
                        
                        //System.out.println("Resolving : " + publicId + " " + systemId);
                        
                        if (systemId != null) {
                            String dtd = null;
                            
                            if ( systemId.equals("http://jasperreports.sourceforge.net/dtds/jasperreport.dtd") ||
                            systemId.equals("http://www.jasperreports.com/dtds/jasperreport.dtd") ) {
                                //dtd = "dori/jasper/engine/dtds/jasperreport.dtd";
                                dtd = "net/sf/jasperreports/engine/dtds/jasperreport.dtd";
                               
                            } else if (
                            systemId.equals("http://jasperreports.sourceforge.net/dtds/jasperprint.dtd") ||
                            systemId.equals("http://www.jasperreports.com/dtds/jasperprint.dtd") ) {
                                dtd = "net/sf/jasperreports/engine/dtds/jasperprint.dtd";
                            } else {
                                
                                return new org.xml.sax.InputSource(systemId);
                            }


                            ClassLoader classLoader = this.getClass().getClassLoader();
                            java.net.URL url = null;

                            if (classLoader != null) {
                                url = classLoader.getResource(dtd);
                                if (url == null) {
                                    classLoader = this.getClass().getClassLoader();
                                }

                            } else {
                                // url is certainly null
                                // classLoader stays null
                            }


                            java.io.InputStream is = classLoader.getResourceAsStream(dtd);
                            if (is != null) {
                                java.io.InputStreamReader isr = new java.io.InputStreamReader(is);
                                inputSource = new org.xml.sax.InputSource(isr);
                            } else {
                                // dtd could not be found
                                // this error occurs e.g. when the package name / path changes to this dtd
                                // the error will be caught by MainFrame.openFile() en the report file won't open
                                throw new java.io.IOException( "iReport Internal error in report.java: Could not find: " + dtd + "\n" );
                            }
                        }
                        return inputSource;
                        
                    }
                });
                /* End Code by Teodor Danciu */
                
                    //String f = new java.io.File(xmlFile).toURI().toString();
                    org.xml.sax.InputSource input_sss  = new org.xml.sax.InputSource( input_source );
                    input_sss.setSystemId("file:///" + this.getFilename());
                    
                    parser.parse( input_sss );
                    
                    //System.out.println(parser.getFeature("http://apache.org/xml/features/dom/create-entity-ref-nodes"));

                    Document document = parser.getDocument();
                    this.setEncoding(Misc.nvl(input_sss.getEncoding(),"UTF-8"));    
                    
                    traverse(document.getDocumentElement());

            

            /* Begin Code by Robert Lamping
             * 2 July 2004
             * Now height and width are known and a format can be guessed.
             * using PageSize.deductPageFormat();
             */
            
            this.setReportFormat( PageSize.deductPageFormat( this.getWidth(), this.getHeight()) );
            
            
            for (int i = 0; i < getGroups().size(); i++) {
                it.businesslogic.ireport.Group grp = (it.businesslogic.ireport.Group)getGroups().elementAt(i);
                addGroup(grp,false);
            }
            
            /*
            for (int i=0; i<getBands().size(); ++i)
            {
                Band b = (Band)getBands().elementAt(i);
                this.elementGroupResort( b );
            }
             */
            
            // Translate coords to iReport coord system...
            for (int i =0; i < elements.size(); ++i) {
                ReportElement re = (ReportElement)elements.elementAt(i);
        
                
                if (re.getParentElement() != null)
                {
                    re.trasform(new java.awt.Point((int)re.getParentElement().getPosition().getX(), (int)re.getParentElement().getPosition().getY()), TransformationType.TRANSFORMATION_MOVE);
                }
                else
                {
                    re.trasform(new java.awt.Point(this.getLeftMargin()+10, this.getBandYLocation(re.getBand())+10), TransformationType.TRANSFORMATION_MOVE);
                }
            }
            
            
            
            
            // Scriptlet loading....
            
            // Process custom properties (ireport.* properties).
            // We cut out ireport properties...
            //System.out.println("Analizing properties...");
            //System.out.println("Possible file: "+this.getScriptletFileName());

            if (this.getScriptletFileName() != null)
            {
                this.setScriptletHandling( this.SCRIPTLET_CLASSIC_HANDLING);
            }
            
            for (int pk= 0; pk < this.getJRproperties().size(); ++pk) {
                JRProperty prop = (JRProperty)getJRproperties().elementAt( pk );
                
                //System.out.println(""+prop.getName());
                
                if (prop.getName().equals("ireport.scriptlethandling")) {
                    if (prop.getValue().equals("0")) {
                        this.setScriptletHandling(0);
                    } else if (prop.getValue().equals("1")) {
                        this.setScriptletHandling( this.SCRIPTLET_IREPORT_INTERNAL_HANDLING );
                        // Try to load the source file...
                        File scriptletFile = new File(this.getScriptletFileName());
                        if (scriptletFile.exists()) {
                            scripletCode = new ScriptletCode(this.getScriptletFileName());
                            //System.out.println("Caricato scriptlet");
                        }
                    }
                }
                
                if (prop.getName().equals("ireport.encoding")) {
                    this.setEncoding(prop.getValue());
                }
                
                if (prop.getValue().startsWith("ireport.")) {
                    getJRproperties().remove( prop );
                    pk--;
                }
            }
            
            if (this.getScriptletHandling() == 2 &&
            	(getScriptletClass() == null || getScriptletClass().equals("")) )
            	{
            		this.setScriptletHandling(0);
            	}
            
            // } catch (SAXException e) {
            //            System.err.println(e);
        } catch (IOException e) {
            System.err.println(e);
            throw e ; 
            
        } catch (net.sf.jasperreports.engine.JRException e) {
            System.err.println(e);
            
        } catch (Exception e) {
            System.err.println(e);
            e.printStackTrace();
        }
        
        // Set the report status to Unchanged...
        // This will thrown an ReportStateChanged
        this.setReportChanges( 0 );
        
    }
    
    //  Traverse DOM Tree.  Print out Element Names
    private void traverse(Node node) {
        
        boolean seeInside = false;
        if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("jasperReport")) {

            seeInside = true;
            // Find encoding...
            NamedNodeMap nnm = node.getAttributes();
            
            this.setName((( nnm.getNamedItem("name") != null) ? nnm.getNamedItem("name").getNodeValue() : ""));
            
            if ( nnm.getNamedItem("columnCount") != null) {
                this.setColumnCount( Integer.parseInt(nnm.getNamedItem("columnCount").getNodeValue()));
            }
            if ( nnm.getNamedItem("printOrder") != null) {
                this.setPrintOrder( nnm.getNamedItem("printOrder").getNodeValue());
            }
            if ( nnm.getNamedItem("orientation") != null) {
                this.setOrientation( nnm.getNamedItem("orientation").getNodeValue());
            }
            if ( nnm.getNamedItem("scriptletClass") != null) {
                this.setScriptletClass( nnm.getNamedItem("scriptletClass").getNodeValue());
            }
            if ( nnm.getNamedItem("resourceBundle") != null) {
                this.setResourceBundleBaseName( nnm.getNamedItem("resourceBundle").getNodeValue());
            }
            if ( nnm.getNamedItem("pageWidth") != null) {
                this.setWidth( Integer.parseInt(nnm.getNamedItem("pageWidth").getNodeValue()));
            }
            if ( nnm.getNamedItem("pageHeight") != null) {
                this.setHeight( Integer.parseInt(nnm.getNamedItem("pageHeight").getNodeValue()));
            }
            if ( nnm.getNamedItem("columnWidth") != null) {
                this.setColumnWidth( Integer.parseInt(nnm.getNamedItem("columnWidth").getNodeValue()));
            }
            if ( nnm.getNamedItem("columnSpacing") != null) {
                this.setColumnSpacing( Integer.parseInt(nnm.getNamedItem("columnSpacing").getNodeValue()));
            }
            if ( nnm.getNamedItem("leftMargin") != null) {
                this.setLeftMargin( Integer.parseInt(nnm.getNamedItem("leftMargin").getNodeValue()));
            }
            if ( nnm.getNamedItem("rightMargin") != null) {
                this.setRightMargin( Integer.parseInt(nnm.getNamedItem("rightMargin").getNodeValue()));
            }
            if ( nnm.getNamedItem("topMargin") != null) {
                this.setTopMargin( Integer.parseInt(nnm.getNamedItem("topMargin").getNodeValue()));
            }
            if ( nnm.getNamedItem("bottomMargin") != null) {
                this.setBottomMargin( Integer.parseInt(nnm.getNamedItem("bottomMargin").getNodeValue()));
            }
            if ( nnm.getNamedItem("whenNoDataType") != null) {
                this.setWhenNoDataType( nnm.getNamedItem("whenNoDataType").getNodeValue());
            }
            if ( nnm.getNamedItem("isTitleNewPage") != null) {
                this.setIsTitleNewPage(nnm.getNamedItem("isTitleNewPage").getNodeValue().equalsIgnoreCase("true") );
            }
            if ( nnm.getNamedItem("isSummaryNewPage") != null) {
                this.setIsSummaryNewPage(  nnm.getNamedItem("isSummaryNewPage").getNodeValue().equalsIgnoreCase("true"));
            }
            
            if ( nnm.getNamedItem("isFloatColumnFooter") != null) {
                this.setFloatColumnFooter(nnm.getNamedItem("isFloatColumnFooter").getNodeValue().equalsIgnoreCase("true") );
            }
            
            if ( nnm.getNamedItem("language") != null) {
                this.setLanguage( nnm.getNamedItem("language").getNodeValue());
            }
            
            if ( nnm.getNamedItem("whenResourceMissingType") != null) {
                this.setWhenResourceMissingType( nnm.getNamedItem("whenResourceMissingType").getNodeValue());
            }
            
            if ( nnm.getNamedItem("isIgnorePagination") != null) {
                this.setIgnorePagination( nnm.getNamedItem("isIgnorePagination").getNodeValue().equalsIgnoreCase("true"));
            }
            
                    
            
        } else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("property")) {

            // Load report property...
            it.businesslogic.ireport.JRProperty property = readPropertyElement(node);
            if (property.getName() != null && property.getName().length() != 0) {
                    addJRProperty( property );
            }
        } else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("import")) {

            // Load report IMPORT...
            NamedNodeMap nnm = node.getAttributes();
            if ( nnm.getNamedItem("value") != null) {
                addImport( nnm.getNamedItem("value").getNodeValue() );
            }            
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("reportFont")) {
            
            // Load report font...
            boolean isDefaultFont = false;
            IReportFont font = new IReportFont();
            
            NamedNodeMap nnm = node.getAttributes();
            
            for (int kkk=0; kkk<nnm.getLength(); ++kkk)
            {
                //System.out.println( + " " + );

                String propName = nnm.item(kkk).getNodeName();
                String propValue = nnm.item(kkk).getNodeValue();
                if (propName != null && propValue != null)
                {
                    if (propName.equals("name"))
                        font.setReportFont(propValue);
                    if (propName.equals("isDefault"))
                    {
                        isDefaultFont = propValue.equals("true");
                        font.setDefaultFont(isDefaultFont);
                    }
                    if (propName.equals("fontName"))
                        font.setFontName(propValue);
                    else if (propName.equals("pdfFontName"))
                        font.setPDFFontName(propValue);
                    else if (propName.equals("size"))
                        font.setFontSize( Integer.parseInt(""+propValue) );
                    else if (propName.equals("isBold"))
                        font.setBold( (new String(""+propValue)).equalsIgnoreCase("true") );
                    else if (propName.equals("isItalic"))
                        font.setItalic( (new String(""+propValue)).equalsIgnoreCase("true") );
                    else if (propName.equals("isUnderline"))
                        font.setUnderline( (new String(""+propValue)).equalsIgnoreCase("true") );
                    else if (propName.equals("isStrikeThrough"))
                        font.setStrikeTrought( (new String(""+propValue)).equalsIgnoreCase("true") );
                    else if (propName.equals("isPdfEmbedded"))
                        font.setPdfEmbedded((new String(""+propValue)).equalsIgnoreCase("true") );
                    else if (propName.equals("pdfEncoding"))
                        font.setPdfEncoding( ""+propValue );
                }
            }
 
            
            if (isDefaultFont){
                defaultFont = (IReportFont) font.clone();
            }
            
            fonts.addElement( font );
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("style")) {
            
            Style style = readStyle(node);
            styles.addElement( style );
            
            // Update Styles parents...
            for (int i=0; i<getStyles().size(); ++i)
            {
               Style s = (Style)getStyles().elementAt(i);
               if (s.getAttribute(s.ATTRIBUTE_style) != null && !(s.getAttribute(s.ATTRIBUTE_style) instanceof Style))
               {
                   for (int j=0; j<getStyles().size(); ++j)
                   {
                        Style sparent = (Style)getStyles().elementAt(j);
                        if (sparent.getName().equals( s.getAttribute(s.ATTRIBUTE_style)+""))
                        {
                            s.getAttributes().put(s.ATTRIBUTE_style, sparent);
                        }
                   }
               }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("parameter")) {
            
            // Load parameter...
            it.businesslogic.ireport.JRParameter parameter = readParameterElement(node);
                        
            if (parameter.getName() != null && parameter.getName().length() != 0) {
                this.addParameter( parameter );
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("queryString")) {
            // Load queryString
            NamedNodeMap nnm = node.getAttributes();
            if ( nnm.getNamedItem("language") != null) {
                this.setQueryLanguage( nnm.getNamedItem("language").getNodeValue());
            }
            
            this.setQuery( readPCDATA(node) );
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("field")) {
            // Load field
            it.businesslogic.ireport.JRField field = readFieldElement(node);

            if (field.getName() != null && field.getName().length() != 0) {
                this.addField( field );
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("variable")) {
            // Load variable
            it.businesslogic.ireport.JRVariable variable = readVariableElement( node );
            
            if (variable.getName() != null && variable.getName().length() != 0) {
                this.addVariable( variable );
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("subDataset")) {
            // Load field
            it.businesslogic.ireport.SubDataset subDataset = new it.businesslogic.ireport.SubDataset();
            
            NamedNodeMap nnm = node.getAttributes();
            if ( nnm.getNamedItem("scriptletClass") != null) {
                subDataset.setScriptletClass( nnm.getNamedItem("scriptletClass").getNodeValue());
            }
            if ( nnm.getNamedItem("resourceBundle") != null) {
                subDataset.setResourceBundleBaseName( nnm.getNamedItem("resourceBundle").getNodeValue());
            }
            if ( nnm.getNamedItem("whenResourceMissingType") != null) {
                subDataset.setWhenResourceMissingType( nnm.getNamedItem("whenResourceMissingType").getNodeValue());
            }
            subDataset.setName((( nnm.getNamedItem("name") != null) ? nnm.getNamedItem("name").getNodeValue() : "SubDataset"));
            
            NodeList children = node.getChildNodes();
            if (children != null) {
                for (int k=0; k< children.getLength(); k++) {
                    Node nodeChild = (Node)children.item(k);
                    if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("property")) {
                        // Take the CDATA...
                        it.businesslogic.ireport.JRProperty property = readPropertyElement(nodeChild);
                        if (property.getName() != null && property.getName().length() != 0) {
                                subDataset.addJRProperty( property );
                        }
                    }
                    else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("parameter")) {
                        // Take the CDATA...
                        it.businesslogic.ireport.JRParameter parameter = readParameterElement(nodeChild);
                        if (parameter.getName() != null && parameter.getName().length() != 0) {
                                subDataset.addParameter( parameter );
                        }
                    }
                    else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("field")) {
                        // Take the CDATA...
                        it.businesslogic.ireport.JRField field = readFieldElement(nodeChild);

                        if (field.getName() != null && field.getName().length() != 0) {
                                subDataset.addField( field );
                        }
                    }
                    else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("variable")) {
                        // Take the CDATA...
                        it.businesslogic.ireport.JRVariable variable = readVariableElement(nodeChild);
                        if (variable.getName() != null && variable.getName().length() != 0) {
                                subDataset.addVariable( variable );
                        }
                    }
                    else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("queryString")) {
                        // Take the CDATA...
                        NamedNodeMap nnmChild = nodeChild.getAttributes();
                        if ( nnmChild.getNamedItem("language") != null) {
                            subDataset.setQueryLanguage( nnmChild.getNamedItem("language").getNodeValue());
                        }
                        subDataset.setQuery( readPCDATA(nodeChild) );
                    }
                    else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("group")) {
                        // Take the CDATA...
                        it.businesslogic.ireport.Group group = readGroupElement(subDataset, nodeChild, false);
                        subDataset.getGroups().add(group);
                    }
                }
            }
            
            addSubDataset(subDataset );
            
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("group")) {
            // Load group
            
            it.businesslogic.ireport.Group group = readGroupElement(this, node, true);
            if (group.getName() != null && group.getName().length() != 0) {
                getGroups().addElement(group); // We don't use here addGroup method!
            }            
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("background")) {
            // Load background band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("background");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("title")) {
            // Load title band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("title");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("pageHeader")) {
            // Load pageHeader band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("pageHeader");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("columnHeader")) {
            // Load columnHeader band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("columnHeader");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("detail")) {
            // Load detail band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("detail");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("columnFooter")) {
            // Load columnFooter band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("columnFooter");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("pageFooter")) {
            // Load pageFooter band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("pageFooter");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("lastPageFooter")) {
            // Load title band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("lastPageFooter");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("summary")) {
            // Load summary band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("summary");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    
                    readBandElements(bandNode,b);
                }
            }
        }
        else
        {
            if (node.getNodeType() == node.ENTITY_REFERENCE_NODE)
            {
                seeInside = true;
            }
        }
        
        if (seeInside)
        {
            NodeList children = node.getChildNodes();
            if (children != null) {
                for (int i=0; i< children.getLength(); i++)
                    traverse(children.item(i));
            }
        }
        
    }
    
    private void readBandElements(Node bandNode, Band band) {
            readBandElements("", bandNode, band, null,null,null);
    }
    
     private void readBandElements(String parentElementGroup, Node bandNode, Band band, ReportElement parent) {
            readBandElements(parentElementGroup, bandNode, band, parent,null,null);
    }
    
    public String createChildGroup(String parentElementGroup)
    {
        nextGroupId++;
        if (parentElementGroup.length() > 0 ) parentElementGroup += ".";
        return parentElementGroup + nextGroupId;
    }
    
    private it.businesslogic.ireport.JRParameter readParameterElement(Node parameterNode)
    {
        // Load parameter...
        it.businesslogic.ireport.JRParameter parameter = new it.businesslogic.ireport.JRParameter("","java.lang.String",true,"");

        NamedNodeMap nnm = parameterNode.getAttributes();
        if ( nnm.getNamedItem("name") != null) {
            parameter.setName( nnm.getNamedItem("name").getNodeValue());
        }
        if ( nnm.getNamedItem("class") != null) {
            parameter.setClassType( nnm.getNamedItem("class").getNodeValue() );
        }
        if ( nnm.getNamedItem("isForPrompting") != null) {
            parameter.setIsForPrompting( nnm.getNamedItem("isForPrompting").getNodeValue().equalsIgnoreCase("true") );
        }

        // Check for description and expression...
        NodeList children = parameterNode.getChildNodes();
        if (children != null) {
            for (int k=0; k< children.getLength(); k++) {
                Node nodeChild = (Node)children.item(k);
                if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("parameterDescription")) {
                    // Take the CDATA...

                    NodeList list_child = nodeChild.getChildNodes();
                    for (int ck = 0; ck< list_child.getLength(); ck++) {
                        Node child_child = (Node)list_child.item(ck);
                        if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                        child_child.getNodeType() == Node.TEXT_NODE) {
                            parameter.setDescription( child_child.getNodeValue() );
                        }
                    }
                } else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("defaultValueExpression")) {
                    // Take the CDATA...
                    NodeList list_child = nodeChild.getChildNodes();
                    for (int ck = 0; ck < list_child.getLength(); ck++) {
                        Node child_child = (Node)list_child.item(ck);
                        if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                        child_child.getNodeType() == Node.TEXT_NODE) {
                            parameter.setDefaultValueExpression( child_child.getNodeValue() );
                        }
                    }
                }
            }
        }
        
        return parameter;
    }
    
    private it.businesslogic.ireport.JRField readFieldElement(Node fieldNode)
    {
            it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField("","java.lang.String");
            field.setDescription("");
            
            NamedNodeMap nnm = fieldNode.getAttributes();
            if ( nnm.getNamedItem("name") != null) {
                field.setName( nnm.getNamedItem("name").getNodeValue());
            }
            if ( nnm.getNamedItem("class") != null) {
                field.setClassType( nnm.getNamedItem("class").getNodeValue() );
            }
            
            NodeList children = fieldNode.getChildNodes();
            if (children != null) {
                for (int k=0; k< children.getLength(); k++) {
                    Node nodeChild = (Node)children.item(k);
                    
                    if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("fieldDescription")) {
                        // Take the CDATA...
                        NodeList list_child = nodeChild.getChildNodes();
                        
                        for (int ck=0; ck< list_child.getLength(); ck++) {
                            
                            Node child_child = (Node)list_child.item(ck);
                            if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                            child_child.getNodeType() == Node.TEXT_NODE) {
                                field.setDescription( child_child.getNodeValue() );
                            }
                        }
                    }
                }
                
            }
            
            return field;
    }
    
    private it.businesslogic.ireport.JRProperty readPropertyElement(Node propertyNode)
    {
            // Load report property...
            JRProperty property = new JRProperty();
            NamedNodeMap nnm = propertyNode.getAttributes();
            if ( nnm.getNamedItem("name") != null) {
                property.setName( nnm.getNamedItem("name").getNodeValue());
            }
            if ( nnm.getNamedItem("value") != null) {
                property.setValue( nnm.getNamedItem("value").getNodeValue());
            }
            
            return property;
    }
    
    private it.businesslogic.ireport.JRVariable readVariableElement(Node variableNode)
    {
        // Load variable
            it.businesslogic.ireport.JRVariable variable = new it.businesslogic.ireport.JRVariable("",false);
            variable.setResetType("Report"); //Default value...
            variable.setResetGroup(""); //Default value...
            
            variable.setIncrementType("None"); //Default value...
            variable.setIncrementGroup(""); //Default value...
            
            variable.setCalculation("Nothing"); //Default value...
            
            NamedNodeMap nnm = variableNode.getAttributes();
            if ( nnm.getNamedItem("name") != null) {
                variable.setName( nnm.getNamedItem("name").getNodeValue());
            }
            if ( nnm.getNamedItem("class") != null) {
                variable.setClassType( nnm.getNamedItem("class").getNodeValue() );
            }
            if ( nnm.getNamedItem("resetType") != null) {
                variable.setResetType( nnm.getNamedItem("resetType").getNodeValue() );
            }
            if ( nnm.getNamedItem("resetGroup") != null) {
                variable.setResetGroup( nnm.getNamedItem("resetGroup").getNodeValue() );
            }
            if ( nnm.getNamedItem("calculation") != null) {
                variable.setCalculation( nnm.getNamedItem("calculation").getNodeValue() );
            }
            if ( nnm.getNamedItem("incrementerFactoryClass") != null) {
                variable.setIncrementerFactoryClass( nnm.getNamedItem("incrementerFactoryClass").getNodeValue() );
            }
            if ( nnm.getNamedItem("incrementType") != null) {
                variable.setIncrementType( nnm.getNamedItem("incrementType").getNodeValue());
            }
            if ( nnm.getNamedItem("incrementGroup") != null) {
                variable.setIncrementGroup( nnm.getNamedItem("incrementGroup").getNodeValue());
            }
            
            // Check for description and expression...
            NodeList children = variableNode.getChildNodes();
            if (children != null) {
                for (int k=0; k< children.getLength(); k++) {
                    Node nodeChild = (Node)children.item(k);
                    if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("variableExpression")) {
                        // Take the CDATA...
                        NodeList list_child = nodeChild.getChildNodes();
                        for (int ck=0; ck< list_child.getLength(); ck++) {
                            Node child_child = (Node)list_child.item(ck);
                            if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                            child_child.getNodeType() == Node.TEXT_NODE) {
                                variable.setExpression( child_child.getNodeValue() );
                            }
                        }
                    }
                    else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("initialValueExpression")) {
                        // Take the CDATA...
                        NodeList list_child = nodeChild.getChildNodes();
                        for (int ck=0; ck< list_child.getLength(); ck++) {
                            Node child_child = (Node)list_child.item(ck);
                            if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                            child_child.getNodeType() == Node.TEXT_NODE) {
                                variable.setInitialValueExpression( child_child.getNodeValue() );
                            }
                        }
                    }
                }
            }    
            
            return variable;
    }
    
    private it.businesslogic.ireport.crosstab.Measure readMeasureElement(Node measureNode)
    {
        // Load variable
            it.businesslogic.ireport.crosstab.Measure measure = new it.businesslogic.ireport.crosstab.Measure("");
            
            NamedNodeMap nnm = measureNode.getAttributes();
            if ( nnm.getNamedItem("name") != null) {
                measure.setName( nnm.getNamedItem("name").getNodeValue());
            }
            if ( nnm.getNamedItem("class") != null) {
                measure.setClassType( nnm.getNamedItem("class").getNodeValue() );
            }
            if ( nnm.getNamedItem("calculation") != null) {
                measure.setCalculation( nnm.getNamedItem("calculation").getNodeValue() );
            }
            if ( nnm.getNamedItem("incrementerFactoryClass") != null) {
                measure.setIncrementerFactoryClass( nnm.getNamedItem("incrementerFactoryClass").getNodeValue() );
            }
            if ( nnm.getNamedItem("percentageOf") != null) {
                measure.setPercentageOf( nnm.getNamedItem("percentageOf").getNodeValue());
            }
            if ( nnm.getNamedItem("percentageCalculatorClass") != null) {
                measure.setPercentageCalculatorClass( nnm.getNamedItem("percentageCalculatorClass").getNodeValue());
            }
            
            // Check for description and expression...
            NodeList children = measureNode.getChildNodes();
            if (children != null) {
                for (int k=0; k< children.getLength(); k++) {
                    Node nodeChild = (Node)children.item(k);
                    if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("measureExpression")) {
                        measure.setExpression(readPCDATA(nodeChild));
                    }
                }
            }    
            
            return measure;
    }
    
    
        
    
    
    private it.businesslogic.ireport.Style readStyle(Node styleNode)
    {
        return readStyle(styleNode, null);
    }   
    
    /**
     * If a ConditionedStyle, the style is interpreted like part of the tag conditionalStyle
     */
    private it.businesslogic.ireport.Style readStyle(Node styleNode, ConditionedStyle cStyle)
    {
        Style style = new Style();
        if (cStyle != null) style = cStyle;
        NamedNodeMap nnm = styleNode.getAttributes();
                
        for (int i=0; i<Style.JRXMLStyleAttributes.length; ++i)
        {
             if ( nnm.getNamedItem(Style.JRXMLStyleAttributes[i]) != null) {
                style.getAttributes().put(Style.JRXMLStyleAttributes[i], nnm.getNamedItem(Style.JRXMLStyleAttributes[i]).getNodeValue());
             }
        }
        
        //conditionalStyle
        // Check for description and expression...
        NodeList children = styleNode.getChildNodes();
        if (children != null) {
            for (int k=0; k< children.getLength(); k++) {
                Node nodeChild = (Node)children.item(k);
                if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("conditionalStyle")) {
                    ConditionedStyle childStyle = readConditionalStyle(nodeChild);
                    style.getConditionedStyles().add(childStyle);
                }
            }
        }
            
        return style;
    }
    
    /**
     * If a ConditionedStyle, the style is interpreted like part of the tag conditionalStyle
     */
    private it.businesslogic.ireport.ConditionedStyle readConditionalStyle(Node styleNode)
    {
        ConditionedStyle style = new ConditionedStyle();
        
        //conditionalStyle
        // Check for description and expression...
        NodeList children = styleNode.getChildNodes();
        if (children != null) {
            for (int k=0; k< children.getLength(); k++) {
                Node nodeChild = (Node)children.item(k);
                if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("conditionExpression")) {
                    style.setCondition(readPCDATA(nodeChild));
                }
                else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("style")) {
                    style = (ConditionedStyle)readStyle(nodeChild, style);
                }
            }
        }
            
        return style;
    }
    
    private it.businesslogic.ireport.Group readGroupElement(SubDataset ds, Node groupNode, boolean fullRead)
    {
        NamedNodeMap nnm = groupNode.getAttributes();
        it.businesslogic.ireport.Group group = new it.businesslogic.ireport.Group(ds, ""+nnm.getNamedItem("name").getNodeValue());

        if ( nnm.getNamedItem("isStartNewColumn") != null) group.setIsStartNewColumn( nnm.getNamedItem("isStartNewColumn").getNodeValue().equals("true") );
        if ( nnm.getNamedItem("isStartNewPage") != null) group.setIsStartNewPage( nnm.getNamedItem("isStartNewPage").getNodeValue().equals("true") );
        if ( nnm.getNamedItem("isResetPageNumber") != null) group.setIsResetPageNumber( nnm.getNamedItem("isResetPageNumber").getNodeValue().equals("true") );
        if ( nnm.getNamedItem("isReprintHeaderOnEachPage") != null) group.setIsReprintHeaderOnEachPage( nnm.getNamedItem("isReprintHeaderOnEachPage").getNodeValue().equals("true") );
        if ( nnm.getNamedItem("minHeightToStartNewPage") != null) group.setMinHeightToStartNewPage( Integer.parseInt(nnm.getNamedItem("minHeightToStartNewPage").getNodeValue()));

        // Looking for header, footer and expression...
        NodeList children = groupNode.getChildNodes();
        if (children != null) {
            for (int k=0; k< children.getLength(); k++) {
                Node nodeChild = (Node)children.item(k);
                if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("groupExpression")) {
                    // Take the CDATA...
                    NodeList list_child = nodeChild.getChildNodes();
                    for (int ck=0; ck< list_child.getLength(); ck++) {
                        Node child_child = (Node)list_child.item(ck);
                        if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                        child_child.getNodeType() == Node.TEXT_NODE) {
                            group.setGroupExpression( child_child.getNodeValue() );
                        }
                    }
                }
                else if (fullRead && nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("groupHeader")) {
                    // Take the band...
                    NodeList list_child = nodeChild.getChildNodes();
                    for (int ck=0; ck< list_child.getLength(); ck++) {
                        Node bandNode = (Node)list_child.item(ck);
                        if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                            // Read the band...
                            NamedNodeMap bandAttributes = bandNode.getAttributes();
                            if ( bandAttributes.getNamedItem("height") != null) group.getGroupHeader().setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                            if ( bandAttributes.getNamedItem("isSplitAllowed") != null) group.getGroupHeader().setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                            readBandElements(bandNode,group.getGroupHeader());
                        }
                    }
                }
                else if (fullRead && nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("groupFooter")) {
                    // Take the band...
                    NodeList list_child = nodeChild.getChildNodes();
                    for (int ck=0; ck< list_child.getLength(); ck++) {
                        Node bandNode = (Node)list_child.item(ck);
                        if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                            // Read the band...
                            NamedNodeMap bandAttributes = bandNode.getAttributes();
                            if ( bandAttributes.getNamedItem("height") != null) group.getGroupFooter().setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                            if ( bandAttributes.getNamedItem("isSplitAllowed") != null) group.getGroupFooter().setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                            readBandElements(bandNode,group.getGroupFooter());
                        }
                    }
                }
            }
        }

        return group;
    }
    
    
    private void readBandElements(String parentElementGroup, Node bandNode, Band band, ReportElement parentElement, CrosstabReportElement crosstabReportElement, CrosstabCell cell) {
        
        ReportElement rElement = null;
        Style defualtStyle = this.getDefaultStyle();
        
        NodeList list_child = bandNode.getChildNodes();
        for (int ck=0; ck< list_child.getLength(); ck++) {
            Node child = (Node)list_child.item(ck);
            if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("printWhenExpression")) {
                // Read the band...
                //NamedNodeMap bandAttributes = bandNode.getAttributes();
                //if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                // Take subelements and lloking for the expression...
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                    child_child.getNodeType() == Node.TEXT_NODE) {
                        band.setPrintWhenExpression(child_child.getNodeValue());
                    }
                }
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("staticText")) {
                StaticTextReportElement re = new StaticTextReportElement(0,0,0,0);
                re.setIReportFont(defaultFont);
                
                if (defualtStyle != null) { re.setStyle(defualtStyle); re.setStyle(null); }
                re.setBand(band);
                re.setCell( cell );
                re.setElementGroup(parentElementGroup);
                re.setParentElement(parentElement);
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("textElement")) {
                        readXMLTextElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("text")) {
                        re.setText( readPCDATA(child_child, false) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("box")) {
                        readBoxElement(child_child,re);
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                //elements.addElement(re);
                rElement = re;
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("image")) {
                ImageReportElement re = new ImageReportElement(0,0,0,0);
                if (defualtStyle != null) { re.setStyle(defualtStyle); re.setStyle(null); }
                re.setBand(band);
                re.setCell( cell );
                re.setElementGroup(parentElementGroup);
                re.setParentElement(parentElement);
                NamedNodeMap nodeAttributes = child.getAttributes();
                if (nodeAttributes.getNamedItem("isUsingCache") != null)
                    re.setIsUsingCache( (""+nodeAttributes.getNamedItem("isUsingCache").getNodeValue()).equals("true") );
                if (nodeAttributes.getNamedItem("isLazy") != null)
                    re.setIsLazy( (""+nodeAttributes.getNamedItem("isLazy").getNodeValue()).equals("true") );
                if (nodeAttributes.getNamedItem("onErrorType") != null)
                    re.setOnErrorType(""+nodeAttributes.getNamedItem("onErrorType").getNodeValue());
                if (nodeAttributes.getNamedItem("scaleImage") != null)
                    re.setScaleImage(""+nodeAttributes.getNamedItem("scaleImage").getNodeValue());
                if (nodeAttributes.getNamedItem("vAlign") != null)
                    re.setVerticalAlignment( ""+nodeAttributes.getNamedItem("vAlign").getNodeValue());
                if (nodeAttributes.getNamedItem("hAlign") != null)
                    re.setHorizontalAlignment(""+nodeAttributes.getNamedItem("hAlign").getNodeValue());
                if (nodeAttributes.getNamedItem("evaluationTime") != null)
                    re.setEvaluationTime( ""+nodeAttributes.getNamedItem("evaluationTime").getNodeValue());
                if (nodeAttributes.getNamedItem("evaluationGroup") != null)
                    re.setEvaluationGroup( ""+nodeAttributes.getNamedItem("evaluationGroup").getNodeValue());
                if (nodeAttributes.getNamedItem("hyperlinkType") != null)
                    re.setHyperlinkType(""+nodeAttributes.getNamedItem("hyperlinkType").getNodeValue());
                if (nodeAttributes.getNamedItem("hyperlinkTarget") != null)
                    re.setHyperlinkTarget(""+nodeAttributes.getNamedItem("hyperlinkTarget").getNodeValue());
                if (nodeAttributes.getNamedItem("bookmarkLevel") != null)
                    re.setBookmarkLevel( Integer.parseInt( nodeAttributes.getNamedItem("bookmarkLevel").getNodeValue() ) );
                
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }		// Element properties...
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("graphicElement")) {
                        if (subNodeAttributes.getNamedItem("pen") != null) {
                            re.setGraphicElementPen( ""+subNodeAttributes.getNamedItem("pen").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("fill") != null) {
                            re.setPropertyValue(GraphicReportElement.FILL, ""+subNodeAttributes.getNamedItem("fill").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("stretchType") != null) {
                            re.setStretchType(""+subNodeAttributes.getNamedItem("stretchType").getNodeValue());
                        }
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("imageExpression")) {
                        if (subNodeAttributes.getNamedItem("class") != null) {
                            re.setImageClass(""+subNodeAttributes.getNamedItem("class").getNodeValue());
                        }
                        re.setImageExpression( readPCDATA(child_child));
                        re.setReportDirectory(new java.io.File(this.filename).getParentFile());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("anchorNameExpression")) {
                        re.setAnchorNameExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkAnchorExpression")) {
                        re.setHyperlinkAnchorExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkPageExpression")) {
                        re.setHyperlinkPageExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkReferenceExpression")) {
                        re.setHyperlinkReferenceExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("box")) {
                        readBoxElement(child_child,re);
                    }
                }
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                
                if (re.getImageExpression().indexOf("it.businesslogic.ireport.chart.DefaultChartFactory.drawChart(") >= 0) {
                    ChartReportElement chart = new ChartReportElement( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    chart.setBand( re.getBand() );
                    chart.setElementGroup( re.getElementGroup());
                    chart.setParentElement( re.getParentElement());
                    chart.setHyperlinkReferenceExpression( re.getHyperlinkReferenceExpression());
                    chart.setHyperlinkPageExpression( re.getHyperlinkPageExpression());
                    chart.setHyperlinkAnchorExpression( re.getHyperlinkAnchorExpression());
                    chart.setHyperlinkType( re.getHyperlinkType());
                    chart.setBgcolor( re.getBgcolor());
                    chart.setEvaluationGroup( re.getEvaluationGroup());
                    chart.setEvaluationTime( re.getEvaluationTime());
                    chart.setFgcolor( re.getFgcolor());
                    chart.setFill( re.getFill());
                    //chart.setGraphicElementPen( re.getGraphicElementPen());
                    chart.setHorizontalAlignment( re.getHorizontalAlignment());
                    chart.setImageClass( re.getImageClass());
                    chart.setImageExpression( re.getImageExpression());
                    chart.setName( re.getName());
                    chart.setPositionType( re.getPositionType());
                    chart.setPrintWhenExpression( re.getPrintWhenExpression() );
                    chart.setPrintWhenGroupChanges( re.getPrintWhenGroupChanges());
                    chart.setScaleImage( re.getScaleImage());
                    chart.setStretchType( re.getStretchType());
                    chart.setTransparent( re.getTransparent());
                    chart.setVerticalAlignment( re.getVerticalAlignment());
                    chart.parseProperties( this.getJRproperties() );
                    re = chart;
                }
                
                if (re.getImageExpression().indexOf("it.businesslogic.ireport.barcode.BcImage.getBarcodeImage(") >= 0) {
                    BarcodeReportElement bc = new BarcodeReportElement( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    bc.setBand( re.getBand() );
                    bc.setCell( cell );
                    bc.setElementGroup( re.getElementGroup());
                    bc.setParentElement( re.getParentElement());
                    bc.setHyperlinkReferenceExpression( re.getHyperlinkReferenceExpression());
                    bc.setHyperlinkPageExpression( re.getHyperlinkPageExpression());
                    bc.setHyperlinkAnchorExpression( re.getHyperlinkAnchorExpression());
                    bc.setHyperlinkType( re.getHyperlinkType());
                    bc.setBgcolor( re.getBgcolor());
                    bc.setEvaluationGroup( re.getEvaluationGroup());
                    bc.setEvaluationTime( re.getEvaluationTime());
                    bc.setFgcolor( re.getFgcolor());
                    bc.setFill( re.getFill());
                    //bc.setGraphicElementPen( re.getGraphicElementPen());
                    bc.setHorizontalAlignment( re.getHorizontalAlignment());
                    bc.setImageClass( re.getImageClass());
                    bc.setImageExpression( re.getImageExpression());
                    bc.setName( re.getName());
                    bc.setPositionType( re.getPositionType());
                    bc.setPrintWhenExpression( re.getPrintWhenExpression() );
                    bc.setPrintWhenGroupChanges( re.getPrintWhenGroupChanges());
                    bc.setScaleImage( re.getScaleImage());
                    bc.setStretchType( re.getStretchType());
                    bc.setTransparent( re.getTransparent());
                    bc.setVerticalAlignment( re.getVerticalAlignment());
                    
                    re = bc;
                }
                
                //elements.addElement(re);
                rElement = re;
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("rectangle")) {
                RectangleReportElement re = new RectangleReportElement(0,0,0,0);
                if (defualtStyle != null) { re.setStyle(defualtStyle); re.setStyle(null); }
                re.setBand(band);
                re.setCell( cell );
                re.setElementGroup(parentElementGroup);
                re.setParentElement(parentElement);
                NamedNodeMap nodeAttributes = child.getAttributes();
                /* CompatibilitySupport.saveRoundedRectangle */
                if (nodeAttributes.getNamedItem("radius") != null)
                    re.setRadius( Integer.parseInt( (""+nodeAttributes.getNamedItem("radius").getNodeValue())) );
                // Element properties...
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }		// Element properties...
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("graphicElement")) {
                        if (subNodeAttributes.getNamedItem("pen") != null) {
                            re.setGraphicElementPen( ""+subNodeAttributes.getNamedItem("pen").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("fill") != null) {
                            re.setPropertyValue(GraphicReportElement.FILL, ""+subNodeAttributes.getNamedItem("fill").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("stretchType") != null) {
                            re.setStretchType(""+subNodeAttributes.getNamedItem("stretchType").getNodeValue());
                        }
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                
                //elements.addElement(re);
                rElement = re;
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("line")) {
                LineReportElement re = new LineReportElement(0,0,0,0);
                if (defualtStyle != null) { re.setStyle(defualtStyle); re.setStyle(null); }
                re.setBand(band);
                re.setCell( cell );
                re.setElementGroup(parentElementGroup);
                re.setParentElement(parentElement);
                NamedNodeMap nodeAttributes = child.getAttributes();
                /* CompatibilitySupport.saveRoundedRectangle */
                if (nodeAttributes.getNamedItem("direction") != null)
                    re.setDirection( ""+nodeAttributes.getNamedItem("direction").getNodeValue() );
                
                // Element properties...
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }		// Element properties...
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("graphicElement")) {
                        if (subNodeAttributes.getNamedItem("pen") != null) {
                            re.setGraphicElementPen( ""+subNodeAttributes.getNamedItem("pen").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("fill") != null) {
                            re.setPropertyValue(GraphicReportElement.FILL, ""+subNodeAttributes.getNamedItem("fill").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("stretchType") != null) {
                            re.setStretchType(""+subNodeAttributes.getNamedItem("stretchType").getNodeValue());
                        }
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                //elements.addElement(re);
                rElement = re;
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("ellipse")) {
                EllipseReportElement re = new EllipseReportElement(0,0,0,0);
                if (defualtStyle != null) { re.setStyle(defualtStyle); re.setStyle(null); }
                re.setBand(band);
                re.setCell( cell );
                re.setElementGroup(parentElementGroup);
                re.setParentElement(parentElement);
                NamedNodeMap nodeAttributes = child.getAttributes();
                /* CompatibilitySupport.saveRoundedRectangle */
                //if (nodeAttributes.getNamedItem("direction") != null)
                //	re.setDirection( ""+nodeAttributes.getNamedItem("direction").getNodeValue() );
                
                // Element properties...
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }		// Element properties...
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("graphicElement")) {
                        if (subNodeAttributes.getNamedItem("pen") != null) {
                            re.setGraphicElementPen( ""+subNodeAttributes.getNamedItem("pen").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("fill") != null) {
                            re.setPropertyValue(GraphicReportElement.FILL, ""+subNodeAttributes.getNamedItem("fill").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("stretchType") != null) {
                            re.setStretchType(""+subNodeAttributes.getNamedItem("stretchType").getNodeValue());
                        }
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                //elements.addElement(re);
                rElement = re;
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("textField")) {
                TextFieldReportElement re = new TextFieldReportElement(0,0,0,0);
                
                re.setIReportFont(defaultFont);
                if (defualtStyle != null) { re.setStyle(defualtStyle); re.setStyle(null); }
                re.setBand(band);
                re.setCell( cell );
                re.setElementGroup(parentElementGroup);
                re.setParentElement(parentElement);
                NamedNodeMap nodeAttributes = child.getAttributes();
                /* CompatibilitySupport.saveRoundedRectangle */
                if (nodeAttributes.getNamedItem("evaluationTime") != null)
                    re.setEvaluationTime( ""+nodeAttributes.getNamedItem("evaluationTime").getNodeValue() );
                if (nodeAttributes.getNamedItem("evaluationGroup") != null)
                    re.setGroup( ""+nodeAttributes.getNamedItem("evaluationGroup").getNodeValue() );
                if (nodeAttributes.getNamedItem("isStretchWithOverflow") != null)
                    re.setStretchWithOverflow( nodeAttributes.getNamedItem("isStretchWithOverflow").getNodeValue().equals("true"));
                if (nodeAttributes.getNamedItem("isBlankWhenNull") != null)
                    re.setBlankWhenNull(nodeAttributes.getNamedItem("isBlankWhenNull").getNodeValue().equals("true") );
                if (nodeAttributes.getNamedItem("pattern") != null)
                    re.setPattern( ""+nodeAttributes.getNamedItem("pattern").getNodeValue() );
                if (nodeAttributes.getNamedItem("hyperlinkType") != null)
                    re.setHyperlinkType( ""+nodeAttributes.getNamedItem("hyperlinkType").getNodeValue() );
                if (nodeAttributes.getNamedItem("hyperlinkTarget") != null)
                    re.setHyperlinkTarget( ""+nodeAttributes.getNamedItem("hyperlinkTarget").getNodeValue() );
                
                
                if (nodeAttributes.getNamedItem("bookmarkLevel") != null)
                    re.setBookmarkLevel( Integer.parseInt( nodeAttributes.getNamedItem("bookmarkLevel").getNodeValue() ) );
                
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("textElement")) {
                        readXMLTextElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("textFieldExpression")) {
                        if (subNodeAttributes.getNamedItem("class") != null) {
                            re.setClassExpression(""+subNodeAttributes.getNamedItem("class").getNodeValue());
                        }
                        re.setText( readPCDATA(child_child).trim());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("anchorNameExpression")) {
                        re.setAnchorNameExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkAnchorExpression")) {
                        re.setHyperlinkAnchorExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkPageExpression")) {
                        re.setHyperlinkPageExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkReferenceExpression")) {
                        re.setHyperlinkReferenceExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("box")) {
                        readBoxElement(child_child,re);
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                //elements.addElement(re);
                rElement = re;
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("frame")) {
                FrameReportElement re = new FrameReportElement(0,0,0,0);
                if (defualtStyle != null) { re.setStyle(defualtStyle); re.setStyle(null); }
                re.setBand(band);
                re.setCell( cell );
                re.setElementGroup(parentElementGroup);
                re.setParentElement(parentElement);
                NamedNodeMap nodeAttributes = child.getAttributes();
                
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("box")) {
                        readBoxElement(child_child,re);
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                rElement = re;
                
                if (crosstabReportElement != null)
                {
                    crosstabReportElement.getElements().addElement( rElement );
                }
                else
                {
                    elements.addElement(rElement);
                }
                
                readBandElements("", child,band, re, crosstabReportElement, cell);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("elementGroup")) {
                String newgroup = createChildGroup(parentElementGroup);
                readBandElements(newgroup, child,band, parentElement, crosstabReportElement, cell);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("subreport")) {
                SubReportElement re = new SubReportElement(0,0,0,0);
                if (defualtStyle != null) { re.setStyle(defualtStyle); re.setStyle(null); }
                re.setBand(band);
                re.setElementGroup(parentElementGroup);
                re.setParentElement(parentElement);
                NamedNodeMap nodeAttributes = child.getAttributes();
                if (nodeAttributes.getNamedItem("isUsingCache") != null)
                    re.setIsUsingCache(nodeAttributes.getNamedItem("isUsingCache").getNodeValue().equals("true") );
                
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("parametersMapExpression")) {
                        re.setParametersMapExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("returnValue")) {
                        it.businesslogic.ireport.JRSubreportReturnValue returnValue = new it.businesslogic.ireport.JRSubreportReturnValue();
                        
                        if (subNodeAttributes.getNamedItem("subreportVariable") != null) {
                            returnValue.setSubreportVariable( ""+subNodeAttributes.getNamedItem("subreportVariable").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("toVariable") != null) {
                            returnValue.setToVariable( ""+subNodeAttributes.getNamedItem("toVariable").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("calculation") != null) {
                            returnValue.setCalculation( ""+subNodeAttributes.getNamedItem("calculation").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("incrementerFactoryClass") != null) {
                            returnValue.setIncrementFactoryClass( ""+subNodeAttributes.getNamedItem("incrementerFactoryClass").getNodeValue());
                        }
                        re.getReturnValues().addElement(returnValue );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("subreportParameter")) {
                        String name = "";
                        if (subNodeAttributes.getNamedItem("name") != null) {
                            name = ""+subNodeAttributes.getNamedItem("name").getNodeValue();
                        }
                        // Find expression in childs......
                        String expression = "";
                        NodeList childsOfChildOfChild = child_child.getChildNodes();
                        for (int c_count_2=0; c_count_2< childsOfChildOfChild.getLength(); c_count_2++) {
                            Node child_child_child = (Node)childsOfChildOfChild.item(c_count_2);
                            if (child_child_child.getNodeType() == Node.ELEMENT_NODE && child_child_child.getNodeName().equals("subreportParameterExpression")) {
                                expression = readPCDATA(child_child_child);
                                break;
                            }
                        }
                        re.getSubreportParameters().addElement( new it.businesslogic.ireport.JRSubreportParameter( name, expression));
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("connectionExpression")) {
                        re.setConnectionExpression( readPCDATA(child_child));
                        re.setUseConnection(true);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("dataSourceExpression")) {
                        re.setDataSourceExpression(readPCDATA(child_child));
                        re.setUseConnection(false);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("subreportExpression")) {
                        re.setSubreportExpression(readPCDATA(child_child));
                        if (subNodeAttributes.getNamedItem("class") != null) {
                            re.setSubreportExpressionClass(""+subNodeAttributes.getNamedItem("class").getNodeValue());
                        }
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                //elements.addElement(re);
                rElement = re;
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("pieChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("pie3DChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("barChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("bar3DChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("xyBarChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("stackedBarChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("stackedBar3DChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("lineChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("xyLineChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("areaChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("xyAreaChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("scatterChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("bubbleChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("timeSeriesChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("highLowChart") ||
                     child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("candlestickChart") ) {
                ChartReportElement2 re = new ChartReportElement2(0,0,0,0);
                if (defualtStyle != null) { re.setStyle(defualtStyle); re.setStyle(null); }
                re.setBand(band);
                re.setElementGroup(parentElementGroup);
                re.setParentElement(parentElement);
                
                
                if ( child.getNodeName().equals("pieChart") ) { re.setChart( new it.businesslogic.ireport.chart.PieChart()); }
                else if ( child.getNodeName().equals("pie3DChart") ) { re.setChart( new it.businesslogic.ireport.chart.Pie3DChart()); }
                else if ( child.getNodeName().equals("barChart") ) { re.setChart( new it.businesslogic.ireport.chart.BarChart()); }
                else if ( child.getNodeName().equals("bar3DChart") ) { re.setChart( new it.businesslogic.ireport.chart.Bar3DChart()); }
                else if ( child.getNodeName().equals("xyBarChart") ) { re.setChart( new it.businesslogic.ireport.chart.XYBarChart()); }
                else if ( child.getNodeName().equals("stackedBarChart") ) { re.setChart( new it.businesslogic.ireport.chart.StackedBarChart()); }
                else if ( child.getNodeName().equals("stackedBar3DChart") ) { re.setChart( new it.businesslogic.ireport.chart.StackedBar3DChart()); }
                else if ( child.getNodeName().equals("lineChart") ) { re.setChart( new it.businesslogic.ireport.chart.LineChart()); }
                else if ( child.getNodeName().equals("xyLineChart") ) { re.setChart( new it.businesslogic.ireport.chart.XYLineChart()); }
                else if ( child.getNodeName().equals("areaChart") ) { re.setChart( new it.businesslogic.ireport.chart.AreaChart()); }
                else if ( child.getNodeName().equals("xyAreaChart") ) { re.setChart( new it.businesslogic.ireport.chart.XYAreaChart()); }
                else if ( child.getNodeName().equals("scatterChart") ) { re.setChart( new it.businesslogic.ireport.chart.ScatterChart()); }
                else if ( child.getNodeName().equals("bubbleChart") ) { re.setChart( new it.businesslogic.ireport.chart.BubbleChart()); }
                else if ( child.getNodeName().equals("timeSeriesChart") ) { re.setChart( new it.businesslogic.ireport.chart.TimeSeriesChart()); }
                else if ( child.getNodeName().equals("highLowChart") ) { re.setChart( new it.businesslogic.ireport.chart.HighLowChart()); }
                else if ( child.getNodeName().equals("candlestickChart") ) { re.setChart( new it.businesslogic.ireport.chart.CandlestickChart()); }
   
                // Element properties...
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("chart")) {
                        readChartElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("pieDataset")) {
                        readPieDataset(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("categoryDataset")) {
                        readCategoryDataset(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("timePeriodDataset")) {
                        readTimePeriodDataset(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("timeSeriesDataset")) {
                        readTimeSeriesDataset(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("xyDataset")) {
                        readXYDataset(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("xyzDataset")) {
                        readXYZDataset(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("highLowDataset")) {
                        readHighLowDataset(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("piePlot")) {
                        readPiePlot(child_child, (PiePlot)re.getChart().getPlot());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("pie3DPlot")) {
                        readPie3DPlot(child_child, (Pie3DPlot)re.getChart().getPlot());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("barPlot")) {
                        readBarPlot(child_child, (BarPlot)re.getChart().getPlot());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("bar3DPlot")) {
                        readBar3DPlot(child_child, (Bar3DPlot)re.getChart().getPlot());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("linePlot")) {
                        readLinePlot(child_child, (LinePlot)re.getChart().getPlot());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("areaPlot")) {
                        readAreaPlot(child_child, (AreaPlot)re.getChart().getPlot());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("scatterPlot")) {
                        readScatterPlot(child_child, (ScatterPlot)re.getChart().getPlot());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("bubblePlot")) {
                        readBubblePlot(child_child, (BubblePlot)re.getChart().getPlot());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("timeSeriesPlot")) {
                        readTimeSeriesPlot(child_child, (TimeSeriesPlot)re.getChart().getPlot());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("highLowPlot")) {
                        readHighLowPlot(child_child, (HighLowPlot)re.getChart().getPlot());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("candlestickPlot")) {
                        readCandlestickPlot(child_child, (CandlestickPlot)re.getChart().getPlot());
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                //elements.addElement(re);
                rElement = re;
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("crosstab")) {
                CrosstabReportElement re = new CrosstabReportElement(0,0,0,0);
                if (defualtStyle != null) { re.setStyle(defualtStyle); re.setStyle(null); }
                re.setBand(band);
                re.setElementGroup(parentElementGroup);
                re.setParentElement(parentElement);
                re.setReport(this);
                NamedNodeMap nodeAttributes = child.getAttributes();
                
                if (nodeAttributes.getNamedItem("isRepeatColumnHeaders") != null)
                    re.setRepeatColumnHeaders(nodeAttributes.getNamedItem("isRepeatColumnHeaders").getNodeValue().equals("true") );
                
                if (nodeAttributes.getNamedItem("isRepeatRowHeaders") != null)
                    re.setRepeatRowHeaders(nodeAttributes.getNamedItem("isRepeatRowHeaders").getNodeValue().equals("true") );
                
                if (nodeAttributes.getNamedItem("isRepeatRowHeaders") != null)
                {
                    try {
                        int columnBreakOffset = Integer.parseInt(nodeAttributes.getNamedItem("columnBreakOffset").getNodeValue() );
                        re.setColumnBreakOffset( columnBreakOffset );
                    } catch (Exception ex)
                    {
                        System.out.println("Invalid columnBreakOffset, using default");
                    }
                }
                
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("parametersMapExpression")) {
                        re.setParametersMapExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("crosstabParameter")) {
                        String name = "";
                        String clazz = "";
                        if (subNodeAttributes.getNamedItem("name") != null) {
                            name = ""+subNodeAttributes.getNamedItem("name").getNodeValue();
                        }
                        CrosstabParameter cp = new CrosstabParameter(name);
                        if (subNodeAttributes.getNamedItem("class") != null) {
                            clazz = ""+subNodeAttributes.getNamedItem("class").getNodeValue();
                            cp.setClassType(clazz);
                        }
                        
                        // Find expression in childs......
                        String expression = "";
                        NodeList childsOfChildOfChild = child_child.getChildNodes();
                        for (int c_count_2=0; c_count_2< childsOfChildOfChild.getLength(); c_count_2++) {
                            Node child_child_child = (Node)childsOfChildOfChild.item(c_count_2);
                            if (child_child_child.getNodeType() == Node.ELEMENT_NODE && child_child_child.getNodeName().equals("parameterValueExpression")) {
                                expression = readPCDATA(child_child_child);
                                cp.setParameterValueExpression( expression );
                                break;
                            }
                        }
                        
                        re.getCrosstabParameters().addElement( cp );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("crosstabDataset")) {
                    
                        re.setUseDataset( true );
                        if (subNodeAttributes.getNamedItem("isDataPreSorted") != null) {
                            re.setPreSorted( subNodeAttributes.getNamedItem("isDataPreSorted").getNodeValue().equals("true") );
                            
                        }
                        
                        NodeList childsOfChildOfChild = child_child.getChildNodes();
                        for (int c_count_2=0; c_count_2< childsOfChildOfChild.getLength(); c_count_2++) {
                            Node child_child_child = (Node)childsOfChildOfChild.item(c_count_2);
                            if (child_child_child.getNodeType() == Node.ELEMENT_NODE && child_child_child.getNodeName().equals("dataset")) {
                                readDataset(child_child_child, re.getDataset());
                                break;
                            }
                        }
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("rowGroup")) {
                        readCrosstabRowGroup(child_child, re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("columnGroup")) {
                        readCrosstabColumnGroup(child_child, re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("measure")) {
                        Measure measure = readMeasureElement(child_child);
                        re.getMeasures().add(measure);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("crosstabCell")) {
                        it.businesslogic.ireport.crosstab.CrosstabCell detailCell = new it.businesslogic.ireport.crosstab.CrosstabCell();
                        readCellContents(child_child, detailCell, re);
                        detailCell.setType( detailCell.DETAIL_CELL );
                        detailCell.setParent(re);
                        re.getCells().add( detailCell );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("whenNoDataCell")) {
                        it.businesslogic.ireport.crosstab.CrosstabCell detailCell = new it.businesslogic.ireport.crosstab.CrosstabCell();
                        readCellContents(child_child, detailCell, re);
                        detailCell.setType( detailCell.NODATA_CELL );
                        detailCell.setParent(re);
                        re.getCells().add( detailCell );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("crosstabHeaderCell")) {
                        it.businesslogic.ireport.crosstab.CrosstabCell detailCell = new it.businesslogic.ireport.crosstab.CrosstabCell();
                        readCellContents(child_child, detailCell, re);
                        detailCell.setType( detailCell.CT_HEADER_CELL );
                        detailCell.setParent(re);
                        re.getCells().add( detailCell );
                    }
                    
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                rElement = re;
            }
            
            
            //System.out.println(""+child.getNodeName());
            if (rElement != null && !(rElement instanceof FrameReportElement))
            {
                if (crosstabReportElement != null)
                {
                    crosstabReportElement.getElements().addElement( rElement );
                }
                else
                {
                    elements.addElement(rElement);
                }
            }
            rElement = null;
        }
        
    }
    
    private void readCrosstabRowGroup(Node rowGroupXmlNode, CrosstabReportElement re)
    {
        CrosstabRowGroup group = new CrosstabRowGroup();
        
        
        NamedNodeMap nodeAttributes = rowGroupXmlNode.getAttributes();
        
        if (nodeAttributes.getNamedItem("name") != null)
            group.setName( nodeAttributes.getNamedItem("name").getNodeValue() );
        
        if (nodeAttributes.getNamedItem("width") != null)
        {
           try {  group.setWidth( Integer.parseInt( nodeAttributes.getNamedItem("width").getNodeValue() )); } catch (Exception ex){
            System.out.println("Invalid width for crosstab row group " + group.getName());
           }
        }
        
        if (nodeAttributes.getNamedItem("totalPosition") != null)
            group.setTotalPosition( nodeAttributes.getNamedItem("totalPosition").getNodeValue() );
        if (nodeAttributes.getNamedItem("headerPosition") != null)
            group.setHeaderPosition( nodeAttributes.getNamedItem("headerPosition").getNodeValue() );
        
        re.getRowGroups().add(group);
        
        NodeList list_child = rowGroupXmlNode.getChildNodes();
        for (int ck=0; ck< list_child.getLength(); ck++) {
            Node child = (Node)list_child.item(ck);
            NamedNodeMap subNodeAttributes = child.getAttributes();
            if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("bucket")) {

                readBucket(child, group);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("crosstabRowHeader")) {

                it.businesslogic.ireport.crosstab.CrosstabCell cell = new it.businesslogic.ireport.crosstab.CrosstabCell();
                cell.setName(group.getName() + " header" );
                readCellContents(child, cell, re);
                group.setHeaderCell( cell );
                cell.setType( cell.HEADER_CELL );
                cell.setParent(re);
                re.getCells().add( cell );
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("crosstabTotalRowHeader")) {
                it.businesslogic.ireport.crosstab.CrosstabCell cell = new it.businesslogic.ireport.crosstab.CrosstabCell();
                cell.setName(group.getName() + " total header" );
                readCellContents(child, cell, re);
                group.setTotalCell( cell );
                cell.setType( cell.HEADER_CELL );
                cell.setParent(re);
                re.getCells().add( cell );
            }
        }
        
        if (group.getHeaderCell() == null)
        {
            it.businesslogic.ireport.crosstab.CrosstabCell cell = new it.businesslogic.ireport.crosstab.CrosstabCell();
            cell.setName(group.getName() + " header" );
            cell.setType( cell.HEADER_CELL );
            cell.setParent(re);
            cell.setWidth( group.getWidth() );
            re.getCells().add( cell );
            group.setHeaderCell( cell );
         }
        
        if (group.getTotalCell() == null)
        {
            it.businesslogic.ireport.crosstab.CrosstabCell cell = new it.businesslogic.ireport.crosstab.CrosstabCell();
            cell.setType( cell.HEADER_CELL );
            cell.setName(group.getName() + " total header" );
            cell.setParent(re);
            cell.setWidth( group.getWidth() );
            re.getCells().add( cell );
            group.setTotalCell( cell );
         }
        
        
    }
    
    private void readCrosstabColumnGroup(Node columnGroupXmlNode, CrosstabReportElement re)
    {
        CrosstabColumnGroup group = new CrosstabColumnGroup();
        
        NamedNodeMap nodeAttributes = columnGroupXmlNode.getAttributes();
        
        if (nodeAttributes.getNamedItem("name") != null)
            group.setName( nodeAttributes.getNamedItem("name").getNodeValue() );
        
        if (nodeAttributes.getNamedItem("height") != null)
        {
           try {  group.setHeight( Integer.parseInt( nodeAttributes.getNamedItem("height").getNodeValue() )); } catch (Exception ex){
            System.out.println("Invalid height for crosstab column group " + group.getName());
           }
        }
        
        if (nodeAttributes.getNamedItem("totalPosition") != null)
            group.setTotalPosition( nodeAttributes.getNamedItem("totalPosition").getNodeValue() );
        if (nodeAttributes.getNamedItem("headerPosition") != null)
            group.setHeaderPosition( nodeAttributes.getNamedItem("headerPosition").getNodeValue() );
        
        re.getColumnGroups().add(group);
        
        NodeList list_child = columnGroupXmlNode.getChildNodes();
        for (int ck=0; ck< list_child.getLength(); ck++) {
            Node child = (Node)list_child.item(ck);
            NamedNodeMap subNodeAttributes = child.getAttributes();
            if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("bucket")) {

                readBucket(child, group);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("crosstabColumnHeader")) {

                it.businesslogic.ireport.crosstab.CrosstabCell cell = new it.businesslogic.ireport.crosstab.CrosstabCell();
                cell.setName(group.getName() + " header" );
                readCellContents(child, cell, re);
                group.setHeaderCell( cell );
                cell.setType( cell.HEADER_CELL );
                cell.setParent(re);
                re.getCells().add( cell );
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("crosstabTotalColumnHeader")) {
                it.businesslogic.ireport.crosstab.CrosstabCell cell = new it.businesslogic.ireport.crosstab.CrosstabCell();
                cell.setName(group.getName() + " total header" );
                readCellContents(child, cell, re);
                group.setTotalCell( cell );
                cell.setType( cell.HEADER_CELL );
                cell.setParent(re);
                re.getCells().add( cell );
            }
            
        }
        
        if (group.getHeaderCell() == null)
        {
            it.businesslogic.ireport.crosstab.CrosstabCell cell = new it.businesslogic.ireport.crosstab.CrosstabCell();
            cell.setName(group.getName() + " header" );
            cell.setType( cell.HEADER_CELL );
            cell.setParent(re);
            cell.setHeight( group.getHeight() );
            re.getCells().add( cell );
            group.setHeaderCell( cell );
         }
        
        if (group.getTotalCell() == null)
        {
            it.businesslogic.ireport.crosstab.CrosstabCell cell = new it.businesslogic.ireport.crosstab.CrosstabCell();
            cell.setType( cell.HEADER_CELL );
            cell.setName(group.getName() + " total header" );
            cell.setParent(re);
            cell.setHeight( group.getHeight() );
            re.getCells().add( cell );
            group.setTotalCell( cell );
         }
    }
        
    private void readCellContents(Node cellConetensNode, it.businesslogic.ireport.crosstab.CrosstabCell cell, CrosstabReportElement re)
    {
        NamedNodeMap nodeAttributes = cellConetensNode.getAttributes();
        
        if (nodeAttributes.getNamedItem("width") != null)
        {
           try {  cell.setWidth( Integer.parseInt( nodeAttributes.getNamedItem("width").getNodeValue() )); } catch (Exception ex){
            System.out.println("Invalid width for crosstab cell");
           }
        }
        
        if (nodeAttributes.getNamedItem("height") != null)
        {
           try {  cell.setHeight( Integer.parseInt( nodeAttributes.getNamedItem("height").getNodeValue() )); } catch (Exception ex){
            System.out.println("Invalid height for crosstab cell");
           }
        }
        
        if (nodeAttributes.getNamedItem("rowTotalGroup") != null)
            cell.setRowTotalGroup(nodeAttributes.getNamedItem("rowTotalGroup").getNodeValue() );
        
        if (nodeAttributes.getNamedItem("columnTotalGroup") != null)
            cell.setColumnTotalGroup(nodeAttributes.getNamedItem("columnTotalGroup").getNodeValue() );
        
        
        // Look for the CellContents node...
        Node cellContentsElementNode = null;
        NodeList list_child = cellConetensNode.getChildNodes();
        for (int ck=0; ck< list_child.getLength(); ck++) {
            Node child = (Node)list_child.item(ck);
            NamedNodeMap subNodeAttributes = child.getAttributes();
            if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("cellContents")) {
                cellContentsElementNode = child;

                if (subNodeAttributes.getNamedItem("style") != null)
                {
                   String sname = subNodeAttributes.getNamedItem("style").getNodeValue();
                   for (int j=0; j<getStyles().size(); ++j)
                   {
                        Style sparent = (Style)getStyles().elementAt(j);
                        if (sparent.getName().equals( sname))
                        {
                            cell.setStyle( sparent);
                            break;
                        }
                   }
                }
                
                if (subNodeAttributes.getNamedItem("backcolor") != null)
                        cell.setBackcolor( this.decodeColor( subNodeAttributes.getNamedItem("backcolor").getNodeValue() ));
            
                if (subNodeAttributes.getNamedItem("mode") != null)
                    cell.setMode( subNodeAttributes.getNamedItem("mode").getNodeValue());
            }
        }
        
        if (cellContentsElementNode != null)
        {
            list_child = cellContentsElementNode.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node child = (Node)list_child.item(ck);
                NamedNodeMap subNodeAttributes = child.getAttributes();
                
                
                if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("box")) {
                    readBoxElement(child, cell);
                }
            }
            
        }
        readBandElements("",cellContentsElementNode,null,null,re,cell);
        
    }
    
    private void readBucket(Node bucketXmlNode, CrosstabGroup grp)
    {
        NamedNodeMap nodeAttributes = bucketXmlNode.getAttributes();
        
        if (nodeAttributes.getNamedItem("order") != null)
            grp.setBucketOrder( nodeAttributes.getNamedItem("order").getNodeValue() );
        
        NodeList list_child = bucketXmlNode.getChildNodes();
        for (int ck=0; ck< list_child.getLength(); ck++) {
            Node child = (Node)list_child.item(ck);
            NamedNodeMap subNodeAttributes = child.getAttributes();
            if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("bucketExpression")) {

                if (subNodeAttributes.getNamedItem("class") != null)
                    grp.setBucketExpressionClass( subNodeAttributes.getNamedItem("class").getNodeValue());
                
                grp.setBucketExpression(readPCDATA(child));
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("comparatorExpression")) {
                grp.setBucketComparatorExpression(readPCDATA(child));
            }
        }
    }
    
    
    private void readChartElement(Node xmlChart, ChartReportElement2 re) {
        NamedNodeMap nodeAttributes = xmlChart.getAttributes();
        
        if (nodeAttributes.getNamedItem("isShowLegend") != null)
            re.getChart().setShowLegend( nodeAttributes.getNamedItem("isShowLegend").getNodeValue().equals("true") );
        if (nodeAttributes.getNamedItem("evaluationTime") != null)
            re.setEvaluationTime( nodeAttributes.getNamedItem("evaluationTime").getNodeValue() );
        if (nodeAttributes.getNamedItem("evaluationGroup") != null)
            re.setEvaluationGroup( nodeAttributes.getNamedItem("evaluationGroup").getNodeValue() );
        if (nodeAttributes.getNamedItem("hyperlinkType") != null)
            re.setHyperlinkType( ""+nodeAttributes.getNamedItem("hyperlinkType").getNodeValue() );
        if (nodeAttributes.getNamedItem("hyperlinkTarget") != null)
            re.setHyperlinkTarget( ""+nodeAttributes.getNamedItem("hyperlinkTarget").getNodeValue() );
        if (nodeAttributes.getNamedItem("bookmarkLevel") != null)
            re.setBookmarkLevel( Integer.parseInt( nodeAttributes.getNamedItem("bookmarkLevel").getNodeValue() ) );
        if (nodeAttributes.getNamedItem("customizerClass") != null)
            re.getChart().setCustomizerClass( nodeAttributes.getNamedItem("customizerClass").getNodeValue() );
        
        NodeList childsOfChild = xmlChart.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("printWhenExpression")) {
                re.setPrintWhenExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                readXMLReportElement(child_child,  re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("box")) {
                readBoxElement(child_child,  re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("chartTitle")) {
                readChartTitleElement(child_child,  re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("chartSubtitle")) {
                readChartSubTitleElement(child_child,  re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("anchorNameExpression")) {
                re.setAnchorNameExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkAnchorExpression")) {
                re.setHyperlinkAnchorExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkPageExpression")) {
                re.setHyperlinkPageExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkReferenceExpression")) {
                re.setHyperlinkReferenceExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readChartTitleElement(Node xmlElement, ChartReportElement2 re) {
        NamedNodeMap nodeAttributes = xmlElement.getAttributes();
        
        if (nodeAttributes.getNamedItem("position") != null)
            re.getChart().getTitle().setPosition( nodeAttributes.getNamedItem("position").getNodeValue() );
        if (nodeAttributes.getNamedItem("color") != null)
            re.getChart().getTitle().setColor( decodeColor( ""+nodeAttributes.getNamedItem("color").getNodeValue()) );
        
        NodeList childsOfChild = xmlElement.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("titleExpression")) {
                re.getChart().getTitle().setTitleExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("font")) {
                re.getChart().getTitle().setFont( readFontElement(child_child) );
            }
        }
    }
  
     private IReportFont readFontElement(Node xmlElement) {

            NamedNodeMap nnm = xmlElement.getAttributes();
            IReportFont font = null;
            
            if ( nnm.getNamedItem("reportFont") != null) {
                
                font = getReportFontByName( nnm.getNamedItem("reportFont").getNodeValue() );
                if (font != null)
                {
                    font = (IReportFont) font.clone();
                    font.setReportFont( nnm.getNamedItem("reportFont").getNodeValue());
                }
            }
            
            if (font == null) 
            {
                if ( defaultFont != null)
                {
                    font = (IReportFont)defaultFont.clone();
                }
                else
                {
                    font = new IReportFont();
                }
            }
            
            //System.out.println("Working on: " + xmlReportElement);
            for (int kkk=0; kkk<nnm.getLength(); ++kkk)
            {
                //System.out.println( + " " + );

                String propName = nnm.item(kkk).getNodeName();
                String propValue = nnm.item(kkk).getNodeValue();
                if (propName != null && propValue != null)
                {
                    if (propName.equals("fontName"))
                        font.setFontName(propValue);
                    else if (propName.equals("pdfFontName"))
                        font.setPDFFontName(propValue);
                    else if (propName.equals("size"))
                        font.setFontSize( Integer.parseInt(""+propValue) );
                    else if (propName.equals("isBold"))
                        font.setBold( (new String(""+propValue)).equalsIgnoreCase("true") );
                    else if (propName.equals("isItalic"))
                        font.setItalic( (new String(""+propValue)).equalsIgnoreCase("true") );
                    else if (propName.equals("isUnderline"))
                        font.setUnderline( (new String(""+propValue)).equalsIgnoreCase("true") );
                    else if (propName.equals("isStrikeThrough"))
                        font.setStrikeTrought( (new String(""+propValue)).equalsIgnoreCase("true") );
                    else if (propName.equals("isPdfEmbedded"))
                        font.setPdfEmbedded((new String(""+propValue)).equalsIgnoreCase("true") );
                    else if (propName.equals("pdfEncoding"))
                        font.setPdfEncoding( ""+propValue );
                }
            }

            
            return font;
     }
            
    private void readDataset(Node xmlNode, ChartReportElement2 re) {
        
        readDataset(xmlNode, re.getChart().getDataset());
    }
    
    
    private void readDataset(Node xmlNode, Dataset dataset) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        if (nodeAttributes.getNamedItem("resetType") != null)
            dataset.setResetType( nodeAttributes.getNamedItem("resetType").getNodeValue() );
        if (nodeAttributes.getNamedItem("resetGroup") != null)
            dataset.setResetGroup( nodeAttributes.getNamedItem("resetGroup").getNodeValue() );
        if (nodeAttributes.getNamedItem("incrementType") != null)
            dataset.setIncrementType( nodeAttributes.getNamedItem("incrementType").getNodeValue() );
        if (nodeAttributes.getNamedItem("incrementGroup") != null)
            dataset.setIncrementGroup( nodeAttributes.getNamedItem("incrementGroup").getNodeValue() );
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            
            NamedNodeMap subNodeAttributes = child_child.getAttributes();
            
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("datasetRun")) {
            
                if (subNodeAttributes.getNamedItem("subDataset") != null)
                {
                        String name = subNodeAttributes.getNamedItem("subDataset").getNodeValue();
                        Enumeration enum_datasets = getSubDatasets().elements();
                        while (enum_datasets.hasMoreElements())
                        {
                            SubDataset subDataset = (SubDataset)enum_datasets.nextElement();
                            if  ( subDataset.getName().equals(name))
                            {
                                dataset.setSubDataset( subDataset );
                                break;
                            }
                        }
                
                        NodeList childsOfchild_child = child_child.getChildNodes();
                        for (int c_count2=0; c_count2< childsOfchild_child.getLength(); c_count2++) {
                            Node child_child2 = (Node)childsOfchild_child.item(c_count2);
                
                            NamedNodeMap subNodeAttributes2 = child_child2.getAttributes();
                            
                            if (child_child2.getNodeType() == Node.ELEMENT_NODE && child_child2.getNodeName().equals("parametersMapExpression")) {
                                dataset.setParametersMapExpression( readPCDATA(child_child2) );
                            }
                            else if (child_child2.getNodeType() == Node.ELEMENT_NODE && child_child2.getNodeName().equals("datasetParameter")) {
                                name = "";
                                if (subNodeAttributes2.getNamedItem("name") != null) {
                                    name = ""+subNodeAttributes2.getNamedItem("name").getNodeValue();
                                }
                                // Find expression in childs......
                                String expression = "";
                                NodeList childsOfChildOfChild = child_child2.getChildNodes();
                                for (int c_count_2=0; c_count_2< childsOfChildOfChild.getLength(); c_count_2++) {
                                    Node child_child_child = (Node)childsOfChildOfChild.item(c_count_2);
                                    if (child_child_child.getNodeType() == Node.ELEMENT_NODE && child_child_child.getNodeName().equals("datasetParameterExpression")) {
                                        expression = readPCDATA(child_child_child);
                                        break;
                                    }
                                }
                                dataset.getSubreportParameters().addElement( new it.businesslogic.ireport.JRSubreportParameter( name, expression));
                            }
                            else if (child_child2.getNodeType() == Node.ELEMENT_NODE && child_child2.getNodeName().equals("connectionExpression")) {
                                dataset.setConnectionExpression( readPCDATA(child_child2));
                                dataset.setUseConnection(true);
                            }
                            else if (child_child2.getNodeType() == Node.ELEMENT_NODE && child_child2.getNodeName().equals("dataSourceExpression")) {
                                dataset.setDataSourceExpression(readPCDATA(child_child2));
                                dataset.setUseConnection(false);
                            }
                        }
                }
            }
        }
    }
    
    private void readPieDataset(Node xmlNode, ChartReportElement2 re) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("dataset")) {
                readDataset(child_child, re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("keyExpression")) {
                 ((it.businesslogic.ireport.chart.PieDataset)re.getChart().getDataset()).setKeyExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueExpression")) {
                 ((it.businesslogic.ireport.chart.PieDataset)re.getChart().getDataset()).setValueExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("labelExpression")) {
                 ((it.businesslogic.ireport.chart.PieDataset)re.getChart().getDataset()).setLabelExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readCategoryDataset(Node xmlNode, ChartReportElement2 re) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        
        CategoryDataset cd = new CategoryDataset();
        re.getChart().setDataset(cd);
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("dataset")) {
                readDataset(child_child, re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("categorySeries")) {
                CategorySeries cs = readCategorySeries(child_child);
                cd.getCategorySeries().add(cs);
            }
        }
    }
    
    private void readTimePeriodDataset(Node xmlNode, ChartReportElement2 re) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        
        TimePeriodDataset cd = new TimePeriodDataset();
        re.getChart().setDataset(cd);
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("dataset")) {
                readDataset(child_child, re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("timePeriodSeries")) {
                TimePeriodSeries cs = readTimePeriodSeries(child_child);
                cd.getTimePeriodSeries().add(cs);
            }
        }
    }
    
    private void readXYDataset(Node xmlNode, ChartReportElement2 re) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        
        XYDataset cd = new XYDataset();
        re.getChart().setDataset(cd);
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("dataset")) {
                readDataset(child_child, re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("xySeries")) {
                XYSeries cs = readXYSeries(child_child);
                cd.getXYSeries().add(cs);
            }
        }
    }
    
    private void readXYZDataset(Node xmlNode, ChartReportElement2 re) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        
        XYZDataset cd = new XYZDataset();
        re.getChart().setDataset(cd);
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("dataset")) {
                readDataset(child_child, re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("xyzSeries")) {
                XYZSeries cs = readXYZSeries(child_child);
                cd.getXYZSeries().add(cs);
            }
        }
    }
    
    private void readTimeSeriesDataset(Node xmlNode, ChartReportElement2 re) {
        
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        NodeList childsOfChild = xmlNode.getChildNodes();
        
        TimeSeriesDataset cd = new TimeSeriesDataset();
        re.getChart().setDataset(cd);
        
        if (nodeAttributes.getNamedItem("timePeriod") != null)
            cd.setTimePeriod( nodeAttributes.getNamedItem("timePeriod").getNodeValue() );
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("dataset")) {
                readDataset(child_child, re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("timeSeries")) {
                TimeSeries cs = readTimeSeries(child_child);
                cd.getTimeSeries().add(cs);
            }
        }
    }
    
    private void readHighLowDataset(Node xmlNode, ChartReportElement2 re) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();

        HighLowDataset cd = new HighLowDataset();
        re.getChart().setDataset(cd);
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("dataset")) {
                readDataset(child_child, re);
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("seriesExpression")) {
                 cd.setSeriesExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("dateExpression")) {
                 cd.setDateExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("highExpression")) {
                 cd.setHighExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("lowExpression")) {
                 cd.setLowExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("openExpression")) {
                 cd.setOpenExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("closeExpression")) {
                 cd.setCloseExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("volumeExpression")) {
                 cd.setVolumeExpression( readPCDATA(child_child) );
            }
            
        }
    }
    
    private CategorySeries readCategorySeries(Node xmlNode) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        
        CategorySeries cs = new CategorySeries();
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("seriesExpression")) {
                cs.setSeriesExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("categoryExpression")) {
                cs.setCategoryExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueExpression")) {
                cs.setValueExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("labelExpression")) {
                cs.setLabelExpression( readPCDATA(child_child) );
            }
        }
        
        return cs;
    }
    
    private TimePeriodSeries readTimePeriodSeries(Node xmlNode) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        
        TimePeriodSeries cs = new TimePeriodSeries();
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("seriesExpression")) {
                cs.setSeriesExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("startDateExpression")) {
                cs.setStartDateExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("endDateExpression")) {
                cs.setEndDateExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueExpression")) {
                cs.setValueExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("labelExpression")) {
                cs.setLabelExpression( readPCDATA(child_child) );
            }
        }
        
        return cs;
    }
    
    private TimeSeries readTimeSeries(Node xmlNode) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        
        TimeSeries cs = new TimeSeries();
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("seriesExpression")) {
                cs.setSeriesExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("timePeriodExpression")) {
                cs.setTimePeriodExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueExpression")) {
                cs.setValueExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("labelExpression")) {
                cs.setLabelExpression( readPCDATA(child_child) );
            }
        }
        
        return cs;
    }
    
    private XYSeries readXYSeries(Node xmlNode) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        
        XYSeries cs = new XYSeries();
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("seriesExpression")) {
                cs.setSeriesExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("xValueExpression")) {
                cs.setXValueExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("yValueExpression")) {
                cs.setYValueExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("labelExpression")) {
                cs.setLabelExpression( readPCDATA(child_child) );
            }
        }
        
        return cs;
    }
    
    private XYZSeries readXYZSeries(Node xmlNode) {
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        
        XYZSeries cs = new XYZSeries();
        
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("seriesExpression")) {
                cs.setSeriesExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("xValueExpression")) {
                cs.setXValueExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("yValueExpression")) {
                cs.setYValueExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("zValueExpression")) {
                cs.setZValueExpression( readPCDATA(child_child) );
            }
        }
        
        return cs;
    }
    
    private void readPiePlot(Node xmlNode, PiePlot plot) {
       readPlot(xmlNode, plot);
    }
    
    private void readPie3DPlot(Node xmlNode, Pie3DPlot plot) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        if (nodeAttributes.getNamedItem("depthFactor") != null)
            plot.setDepthFactor( Double.parseDouble( nodeAttributes.getNamedItem("depthFactor").getNodeValue() ) );
        
        readPlot(xmlNode, plot);
    }
    
    private void readBarPlot(Node xmlNode, BarPlot plot) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        readPlot(xmlNode, plot);
        
        if (nodeAttributes.getNamedItem("isShowLabels") != null)
                plot.setShowLabels( nodeAttributes.getNamedItem("isShowLabels").getNodeValue().equals("true") );
        if (nodeAttributes.getNamedItem("isShowTickMarks") != null)
                plot.setShowTickMarks( nodeAttributes.getNamedItem("isShowTickMarks").getNodeValue().equals("true") );
        if (nodeAttributes.getNamedItem("isShowTickLabels") != null)
                plot.setShowTickLabels( nodeAttributes.getNamedItem("isShowTickLabels").getNodeValue().equals("true") );
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("categoryAxisLabelExpression")) {
                plot.setCategoryAxisLabelExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueAxisLabelExpression")) {
                plot.setValueAxisLabelExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readBar3DPlot(Node xmlNode, Bar3DPlot plot) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        readPlot(xmlNode, plot);
        
        if (nodeAttributes.getNamedItem("isShowLabels") != null)
                plot.setShowLabels( nodeAttributes.getNamedItem("isShowLabels").getNodeValue().equals("true") );
        if (nodeAttributes.getNamedItem("xOffset") != null)
                plot.setXOffset( Double.parseDouble( nodeAttributes.getNamedItem("xOffset").getNodeValue() ) );
        if (nodeAttributes.getNamedItem("yOffset") != null)
                plot.setYOffset( Double.parseDouble( nodeAttributes.getNamedItem("yOffset").getNodeValue() ) );
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("categoryAxisLabelExpression")) {
                plot.setCategoryAxisLabelExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueAxisLabelExpression")) {
                plot.setValueAxisLabelExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readLinePlot(Node xmlNode, LinePlot plot) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        readPlot(xmlNode, plot);
        
        if (nodeAttributes.getNamedItem("isShowLines") != null)
                plot.setShowLines( nodeAttributes.getNamedItem("isShowLines").getNodeValue().equals("true") );
        if (nodeAttributes.getNamedItem("isShowShapes") != null)
                plot.setShowShapes( nodeAttributes.getNamedItem("isShowShapes").getNodeValue().equals("true") );
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("categoryAxisLabelExpression")) {
                plot.setCategoryAxisLabelExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueAxisLabelExpression")) {
                plot.setValueAxisLabelExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readAreaPlot(Node xmlNode, AreaPlot plot) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        readPlot(xmlNode, plot);
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("categoryAxisLabelExpression")) {
                plot.setCategoryAxisLabelExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueAxisLabelExpression")) {
                plot.setValueAxisLabelExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readScatterPlot(Node xmlNode, ScatterPlot plot) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        readPlot(xmlNode, plot);
        
        if (nodeAttributes.getNamedItem("isShowLines") != null)
                plot.setShowLines( nodeAttributes.getNamedItem("isShowLines").getNodeValue().equals("true") );
        if (nodeAttributes.getNamedItem("isShowShapes") != null)
                plot.setShowShapes( nodeAttributes.getNamedItem("isShowShapes").getNodeValue().equals("true") );
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("xAxisLabelExpression")) {
                plot.setXAxisLabelExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("yAxisLabelExpression")) {
                plot.setYAxisLabelExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readBubblePlot(Node xmlNode, BubblePlot plot) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        readPlot(xmlNode, plot);
        
        if (nodeAttributes.getNamedItem("scaleType") != null)
                plot.setScaleType( nodeAttributes.getNamedItem("scaleType").getNodeValue() );
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("xAxisLabelExpression")) {
                plot.setXAxisLabelExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("yAxisLabelExpression")) {
                plot.setYAxisLabelExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readTimeSeriesPlot(Node xmlNode, TimeSeriesPlot plot) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        readPlot(xmlNode, plot);
        
        if (nodeAttributes.getNamedItem("isShowLines") != null)
                plot.setShowLines( nodeAttributes.getNamedItem("isShowLines").getNodeValue().equals("true") );
        if (nodeAttributes.getNamedItem("isShowShapes") != null)
                plot.setShowShapes( nodeAttributes.getNamedItem("isShowShapes").getNodeValue().equals("true") );
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("timeAxisLabelExpression")) {
                plot.setTimeAxisLabelExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueAxisLabelExpression")) {
                plot.setValueAxisLabelExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readHighLowPlot(Node xmlNode, HighLowPlot plot) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        readPlot(xmlNode, plot);
        
        if (nodeAttributes.getNamedItem("isShowCloseTicks") != null)
                plot.setShowCloseTicks( nodeAttributes.getNamedItem("isShowCloseTicks").getNodeValue().equals("true") );
        if (nodeAttributes.getNamedItem("isShowOpenTicks") != null)
                plot.setShowOpenTicks( nodeAttributes.getNamedItem("isShowOpenTicks").getNodeValue().equals("true") );
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("timeAxisLabelExpression")) {
                plot.setTimeAxisLabelExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueAxisLabelExpression")) {
                plot.setValueAxisLabelExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readCandlestickPlot(Node xmlNode, CandlestickPlot plot) {
        NamedNodeMap nodeAttributes = xmlNode.getAttributes();
        
        readPlot(xmlNode, plot);
        
        if (nodeAttributes.getNamedItem("isShowVolume") != null)
                plot.setShowVolume( nodeAttributes.getNamedItem("isShowVolume").getNodeValue().equals("true") );
        
        NodeList childsOfChild = xmlNode.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("timeAxisLabelExpression")) {
                plot.setTimeAxisLabelExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("valueAxisLabelExpression")) {
                plot.setValueAxisLabelExpression( readPCDATA(child_child) );
            }
        }
    }
    
    private void readPlot(Node xmlNodeParent, Plot plot) {
        NodeList childsOfChild = xmlNodeParent.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node xmlNode = (Node)childsOfChild.item(c_count);
            if (xmlNode.getNodeType() == Node.ELEMENT_NODE && xmlNode.getNodeName().equals("plot")) {

                NamedNodeMap nodeAttributes = xmlNode.getAttributes();

                if (nodeAttributes.getNamedItem("backcolor") != null)
                    plot.setBackcolor( decodeColor( ""+nodeAttributes.getNamedItem("backcolor").getNodeValue()) );

                if (nodeAttributes.getNamedItem("orientation") != null)
                    plot.setOrientation(""+nodeAttributes.getNamedItem("orientation").getNodeValue());

                if (nodeAttributes.getNamedItem("backgroundAlpha") != null)
                    plot.setBackgroundAlpha( Double.parseDouble(nodeAttributes.getNamedItem("backgroundAlpha").getNodeValue()) );

                if (nodeAttributes.getNamedItem("foregroundAlpha") != null)
                    plot.setForegroundAlpha( Double.parseDouble(nodeAttributes.getNamedItem("foregroundAlpha").getNodeValue()) );
        
                break;
           }
        }
    }
        
    private void readChartSubTitleElement(Node xmlElement, ChartReportElement2 re) {
        NamedNodeMap nodeAttributes = xmlElement.getAttributes();
        
        if (nodeAttributes.getNamedItem("color") != null)
            re.getChart().getSubTitle().setColor( decodeColor( ""+nodeAttributes.getNamedItem("color").getNodeValue()) );
        
        NodeList childsOfChild = xmlElement.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("subtitleExpression")) {
                re.getChart().getSubTitle().setTitleExpression( readPCDATA(child_child) );
            }
            else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("font")) {
                 re.getChart().getSubTitle().setFont( readFontElement(child_child) );
            }
        }
    }
    
    private void readXMLReportElement(Node xmlReportElement, ReportElement re) {
        NamedNodeMap nodeAttributes = xmlReportElement.getAttributes();
        
        if (nodeAttributes.getNamedItem("style") != null)
        {
           String sname = nodeAttributes.getNamedItem("style").getNodeValue();
           for (int j=0; j<getStyles().size(); ++j)
           {
                Style sparent = (Style)getStyles().elementAt(j);
                if (sparent.getName().equals( sname))
                {
                    re.setStyle( sparent);
                    break;
                }
           }
        }
        //if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
        if (nodeAttributes.getNamedItem("x") != null)
        {
            re.getPosition().x = Integer.parseInt(""+nodeAttributes.getNamedItem("x").getNodeValue());
            re.getRelativePosition().x = re.getPosition().x;
        }
        if (nodeAttributes.getNamedItem("y") != null)
        {
            re.getPosition().y = Integer.parseInt(""+nodeAttributes.getNamedItem("y").getNodeValue());
            re.getRelativePosition().y = re.getPosition().y;
        }
        if (nodeAttributes.getNamedItem("width") != null)
            re.setWidth( Integer.parseInt(""+nodeAttributes.getNamedItem("width").getNodeValue()) );
        if (nodeAttributes.getNamedItem("height") != null)
            re.setHeight( Integer.parseInt(""+nodeAttributes.getNamedItem("height").getNodeValue()) );
        if (nodeAttributes.getNamedItem("key") != null)
            re.setKey( ""+nodeAttributes.getNamedItem("key").getNodeValue() );
        
        if (nodeAttributes.getNamedItem("stretchType") != null)
            re.setStretchType( ""+nodeAttributes.getNamedItem("stretchType").getNodeValue() );
        
        if (nodeAttributes.getNamedItem("isPrintRepeatedValues") != null)
            re.setIsPrintRepeatedValues( (""+nodeAttributes.getNamedItem("isPrintRepeatedValues").getNodeValue()).equalsIgnoreCase("true") );
        
        if (nodeAttributes.getNamedItem("positionType") != null)
            re.setPositionType( ""+nodeAttributes.getNamedItem("positionType").getNodeValue() );
        else
            re.setPositionType( "FixRelativeToTop" );
        
        if (nodeAttributes.getNamedItem("isPrintRepeatedValues") != null)
            re.setIsPrintRepeatedValues( (""+nodeAttributes.getNamedItem("isPrintRepeatedValues").getNodeValue()).equalsIgnoreCase("true") );
        
        if (nodeAttributes.getNamedItem("isRemoveLineWhenBlank") != null)
        {
            re.setIsRemoveLineWhenBlank( (""+nodeAttributes.getNamedItem("isRemoveLineWhenBlank").getNodeValue()).equalsIgnoreCase("true") ) ;
        }
        
        if (nodeAttributes.getNamedItem("isPrintInFirstWholeBand") != null)
            re.setIsPrintInFirstWholeBand( (""+nodeAttributes.getNamedItem("isPrintInFirstWholeBand").getNodeValue()).equalsIgnoreCase("true") );
        
        if (nodeAttributes.getNamedItem("isPrintWhenDetailOverflows") != null)
            re.setIsPrintWhenDetailOverflows( (""+nodeAttributes.getNamedItem("isPrintWhenDetailOverflows").getNodeValue()).equalsIgnoreCase("true") );
        
        if (nodeAttributes.getNamedItem("printWhenGroupChanges") != null)
            re.setPrintWhenGroupChanges( ""+nodeAttributes.getNamedItem("printWhenGroupChanges").getNodeValue() );
        
        
        if (nodeAttributes.getNamedItem("forecolor") != null) {
            String color = ""+nodeAttributes.getNamedItem("forecolor").getNodeValue();
            re.setFgcolor(decodeColor(color) );
        }
        if (nodeAttributes.getNamedItem("backcolor") != null) {
            String color = ""+nodeAttributes.getNamedItem("backcolor").getNodeValue();
            re.setBgcolor(decodeColor(color) );
            
        }
        if (nodeAttributes.getNamedItem("mode") != null) {
            re.setTransparent(""+nodeAttributes.getNamedItem("mode").getNodeValue());
        }
        
        NodeList childsOfChild = xmlReportElement.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("printWhenExpression")) {
                re.setPrintWhenExpression( readPCDATA(child_child) );
            }
        }
    }
    
     private void readBoxElement(Node xmlReportElement, BoxElement re) {
        NamedNodeMap nodeAttributes = xmlReportElement.getAttributes();
        
        Box box = new Box();
        // ------- defaults --------
        if (nodeAttributes.getNamedItem("border") != null)
        {
            box.setBorder(""+nodeAttributes.getNamedItem("border").getNodeValue() );
            box.setLeftBorder(""+nodeAttributes.getNamedItem("border").getNodeValue() );
            box.setRightBorder(""+nodeAttributes.getNamedItem("border").getNodeValue() );
            box.setTopBorder(""+nodeAttributes.getNamedItem("border").getNodeValue() );
            box.setBottomBorder(""+nodeAttributes.getNamedItem("border").getNodeValue() );
        }
        
        if (nodeAttributes.getNamedItem("padding") != null)
        {
            box.setPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("padding").getNodeValue() ));
            box.setLeftPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("padding").getNodeValue() ));
            box.setRightPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("padding").getNodeValue() ));
            box.setTopPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("padding").getNodeValue() ));
            box.setBottomPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("padding").getNodeValue() ));
        }
        
        if (nodeAttributes.getNamedItem("borderColor") != null)
        {
            String color = ""+nodeAttributes.getNamedItem("borderColor").getNodeValue();
            java.awt.Color colorObj = decodeColor(color);
                
            box.setBorderColor(new java.awt.Color(colorObj.getRGB()));
            box.setLeftBorderColor(new java.awt.Color(colorObj.getRGB()));
            box.setRightBorderColor(new java.awt.Color(colorObj.getRGB()));
            box.setTopBorderColor(new java.awt.Color(colorObj.getRGB()));
            box.setBottomBorderColor(new java.awt.Color(colorObj.getRGB()));
            
        }
        // ------- top --------
        if (nodeAttributes.getNamedItem("topBorder") != null)
        {
            box.setTopBorder(""+nodeAttributes.getNamedItem("topBorder").getNodeValue() );
        }
        
         if (nodeAttributes.getNamedItem("topPadding") != null)
        {
            box.setTopPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("topPadding").getNodeValue() ));
        }
        
        if (nodeAttributes.getNamedItem("topBorderColor") != null)
        {
            String color = ""+nodeAttributes.getNamedItem("topBorderColor").getNodeValue();
            box.setTopBorderColor(decodeColor(color));
        }
        
        // ------- left --------
        if (nodeAttributes.getNamedItem("leftBorder") != null)
        {
            box.setLeftBorder(""+nodeAttributes.getNamedItem("leftBorder").getNodeValue() );
        }
        
         if (nodeAttributes.getNamedItem("leftPadding") != null)
        {
            box.setLeftPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("leftPadding").getNodeValue() ));
        }
        
        if (nodeAttributes.getNamedItem("leftBorderColor") != null)
        {
            String color = ""+nodeAttributes.getNamedItem("leftBorderColor").getNodeValue();
            box.setLeftBorderColor(decodeColor(color));
        }
        
        // ------- right --------
        if (nodeAttributes.getNamedItem("rightBorder") != null)
        {
            box.setRightBorder(""+nodeAttributes.getNamedItem("rightBorder").getNodeValue() );
        }
        
         if (nodeAttributes.getNamedItem("rightPadding") != null)
        {
            box.setRightPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("rightPadding").getNodeValue() ));
        }
        
        if (nodeAttributes.getNamedItem("rightBorderColor") != null)
        {
            String color = ""+nodeAttributes.getNamedItem("rightBorderColor").getNodeValue();
            box.setRightBorderColor(decodeColor(color));
        }
        
        // ------- bottom --------
        if (nodeAttributes.getNamedItem("bottomBorder") != null)
        {
            box.setBottomBorder(""+nodeAttributes.getNamedItem("bottomBorder").getNodeValue() );
        }
        
         if (nodeAttributes.getNamedItem("bottomPadding") != null)
        {
            box.setBottomPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("bottomPadding").getNodeValue() ));
        }
        
        if (nodeAttributes.getNamedItem("bottomBorderColor") != null)
        {
            String color = ""+nodeAttributes.getNamedItem("bottomBorderColor").getNodeValue();
            box.setBottomBorderColor(decodeColor(color));
        }
        
        if (re instanceof BoxElement) ((BoxElement)re).setBox(box);
        
    }
    
    static public String readPCDATA(Node textNode) {
        return readPCDATA(textNode,true);
    }
    
    
    static java.awt.Color decodeColor(String colorString)
    {
        java.awt.Color color = null;
        char firstChar = colorString.charAt(0);
        if (firstChar == '#')
        {
               color = new java.awt.Color(Integer.parseInt(colorString.substring(1), 16));
        }
        else if ('0' <= firstChar && firstChar <= '9')
        {
               color = new java.awt.Color(Integer.parseInt(colorString));
        }
        else
        {
                if (net.sf.jasperreports.engine.xml.JRXmlConstants.getColorMap().containsKey(colorString))
                {
                        color = (java.awt.Color)net.sf.jasperreports.engine.xml.JRXmlConstants.getColorMap().get(colorString);
                }
                else
                {
                        color = java.awt.Color.black;
                }
        }
        return color;
        
    }
    
    
    static public String readPCDATA(Node textNode, boolean trim) {
        NodeList list_child = textNode.getChildNodes();
        for (int ck=0; ck< list_child.getLength(); ck++) {
            Node child_child = (Node)list_child.item(ck);
            
            // --- start solution: if there is another node this should be the PCDATA-node
            Node ns = child_child.getNextSibling();
            if (ns != null)
            child_child = ns;
            // --- end solution

            final short nt = child_child.getNodeType();
            if ((nt == Node.CDATA_SECTION_NODE) || (nt == Node.TEXT_NODE)) {
               if (trim) return ((String)child_child.getNodeValue()).trim();
                return (String)child_child.getNodeValue();
            }
        }
        return "";
    }
    
    
    private void readXMLTextElement(Node xmlReportElement, TextReportElement re) {
        NamedNodeMap nodeAttributes = xmlReportElement.getAttributes();
        if (nodeAttributes.getNamedItem("textAlignment") != null)
            re.setAlign(""+nodeAttributes.getNamedItem("textAlignment").getNodeValue());
        
        if (nodeAttributes.getNamedItem("verticalAlignment") != null)
            re.setVerticalAlign(""+nodeAttributes.getNamedItem("verticalAlignment").getNodeValue());
        
        if (nodeAttributes.getNamedItem("lineSpacing") != null)
            re.setLineSpacing( ""+nodeAttributes.getNamedItem("lineSpacing").getNodeValue());
        
        if (nodeAttributes.getNamedItem("rotation") != null)
            re.setRotate(""+nodeAttributes.getNamedItem("rotation").getNodeValue());
        
        if (nodeAttributes.getNamedItem("isStyledText") != null)
            re.setIsStyledText( (""+nodeAttributes.getNamedItem("isStyledText").getNodeValue()).equals("true") );
        
        
        // Check for Font sub_element...
        NodeList childsOfChild = xmlReportElement.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("font")) {
                NamedNodeMap subNodeAttributes = child_child.getAttributes();
                if (subNodeAttributes.getNamedItem("reportFont") != null) {
                    
                    IReportFont baseFont = null;
                    re.setReportFont(subNodeAttributes.getNamedItem("reportFont").getNodeValue());
                    for (int fn =0; fn < this.fonts.size(); ++fn) {
                        baseFont = (IReportFont)this.fonts.elementAt(fn);
                        if (baseFont != null && baseFont.getReportFont().equals(re.getReportFont())) {
                            break;
                        }
                        else
                            baseFont = null;
                    }
                    if (baseFont != null) {
                        //re.setFontSize(baseFont.getFontSize());
                        //re.setFontName(baseFont.getFontName());
                        //re.setPDFFontName( baseFont.getPDFFontName());
                        //re.setPdfEncoding( baseFont.getPdfEncoding());
                        //re.setPdfEmbedded( baseFont.isPdfEmbedded());
                        //re.setBold(baseFont.isBold()) ;
                        //re.setItalic( baseFont.isItalic());
                        //re.setStrikeTrought(baseFont.isStrikeTrought());
                        //re.setUnderline(baseFont.isUnderline());
                    }else{
                        
                        //using default font
                        //re.setFontSize(defaultFont.getFontSize());
                        //re.setFontName(defaultFont.getFontName());
                        //re.setPDFFontName( defaultFont.getPDFFontName());
                        //re.setPdfEncoding( defaultFont.getPdfEncoding());
                        //re.setPdfEmbedded( defaultFont.isPdfEmbedded());
                        //re.setBold(defaultFont.isBold()) ;
                        //re.setItalic(defaultFont.isItalic());
                        //re.setStrikeTrought(defaultFont.isStrikeTrought());
                        //re.setUnderline(defaultFont.isUnderline());
                    }
                    
                }
                
                //System.out.println("Working on: " + xmlReportElement);
                for (int kkk=0; kkk<subNodeAttributes.getLength(); ++kkk)
                {
                    //System.out.println( + " " + );
                
                    String propName = subNodeAttributes.item(kkk).getNodeName();
                    String propValue = subNodeAttributes.item(kkk).getNodeValue();
                    if (propName != null && propValue != null)
                    {
                        if (propName.equals("fontName"))
                            re.setFontName(propValue);
                        else if (propName.equals("pdfFontName"))
                            re.setPDFFontName(propValue);
                        else if (propName.equals("size"))
                            re.setFontSize( Integer.parseInt(""+propValue) );
                        else if (propName.equals("isBold"))
                            re.setBold( (new String(""+propValue)).equalsIgnoreCase("true") );
                        else if (propName.equals("isItalic"))
                            re.setItalic( (new String(""+propValue)).equalsIgnoreCase("true") );
                        else if (propName.equals("isUnderline"))
                            re.setUnderline( (new String(""+propValue)).equalsIgnoreCase("true") );
                        else if (propName.equals("isStrikeThrough"))
                            re.setStrikeTrought( (new String(""+propValue)).equalsIgnoreCase("true") );
                        else if (propName.equals("isPdfEmbedded"))
                            re.setPdfEmbedded((new String(""+propValue)).equalsIgnoreCase("true") );
                        else if (propName.equals("pdfEncoding"))
                            re.setPdfEncoding( ""+propValue );
                    }
                }
                re.setFont(null);
            }
        }
    }
    
    private Node findNextNode(Node node) {
        int type = node.getNodeType();
        if (type == Node.ELEMENT_NODE){
            return node;
        }
        NodeList children = node.getChildNodes();
        if (children != null) {
            for (int i=0; i< children.getLength(); i++) {
                return findNextNode  (children.item(i));
            }
        }
        return null;
    }
    
    
    /** Getter for property bands.
     * @return Value of property bands.
     *
     */
    public java.util.Vector getBands() {
        return bands;
    }
    
    /** Setter for property bands.
     * @param bands New value of property bands.
     *
     */
    public void setBands(java.util.Vector bands) {
        this.bands = bands;
        incrementReportChanges();
    }
    
    /** Getter for property bottomMargin.
     * @return Value of property bottomMargin.
     *
     */
    public int getBottomMargin() {
        return bottomMargin;
    }
    
    /** Setter for property bottomMargin.
     * @param bottomMargin New value of property bottomMargin.
     *
     */
    public void setBottomMargin(int bottomMargin) {
        if (this.bottomMargin == bottomMargin) return;
        this.bottomMargin = bottomMargin;
        incrementReportChanges();
    }
    
    /** Getter for property columnCount.
     * @return Value of property columnCount.
     *
     */
    public int getColumnCount() {
        return columnCount;
    }
    
    /** Setter for property columnCount.
     * @param columnCount New value of property columnCount.
     *
     */
    public void setColumnCount(int columnCount) {
        if (this.columnCount == columnCount) return;
        this.columnCount = columnCount;
         incrementReportChanges();
    }
    
    /** Getter for property columnSpacing.
     * @return Value of property columnSpacing.
     *
     */
    public int getColumnSpacing() {
        return columnSpacing;
    }
    
    /** Setter for property columnSpacing.
     * @param columnSpacing New value of property columnSpacing.
     *
     */
    public void setColumnSpacing(int columnSpacing) {
        if (this.columnSpacing == columnSpacing) return;
        this.columnSpacing = columnSpacing;
        incrementReportChanges();
    }
    
    /** Getter for property columnWidth.
     * @return Value of property columnWidth.
     *
     */
    public int getColumnWidth() {
        return columnWidth;
    }
    
    /** Setter for property columnWidth.
     * @param columnWidth New value of property columnWidth.
     *
     */
    public void setColumnWidth(int columnWidth) {
        if (this.columnWidth == columnWidth) return;
        this.columnWidth = columnWidth;
        incrementReportChanges();
    }
    
    /** Getter for property elements.
     * @return Value of property elements.
     *
     */
    public java.util.Vector getElements() {
        return elements;
    }
    
    /** Setter for property elements.
     * @param elements New value of property elements.
     *
     */
    public void setElements(java.util.Vector elements) {
        this.elements = elements;
        incrementReportChanges();
    }
    
    /** Getter for property encoding.
     * @return Value of property encoding.
     *
     */
    public java.lang.String getEncoding() {
        return encoding;
    }
    
    /** Setter for property encoding.
     * @param encoding New value of property encoding.
     *
     */
    public void setEncoding(java.lang.String encoding) {
        if ((this.encoding == null) ? encoding == null : this.encoding.equals(encoding)) return;
        this.encoding = encoding;
        incrementReportChanges();
    }
           
    
   
    
    
    /** Getter for property filename.
     * @return Value of property filename.
     *
     */
    public java.lang.String getFilename() {
        return filename;
    }
    
    /** Setter for property filename.
     * @param filename New value of property filename.
     *
     */
    public void setFilename(java.lang.String filename) {
        this.filename = filename;
    }
    
    /** Getter for property fonts.
     * @return Value of property fonts.
     *
     */
    public java.util.Vector getFonts() {
        return fonts;
    }
    
    /** Setter for property fonts.
     * @param fonts New value of property fonts.
     *
     */
    public void setFonts(java.util.Vector fonts) {
        this.fonts = fonts;
        incrementReportChanges();
    }
    
   
    
    /** Getter for property height.
     * @return Value of property height.
     *
     */
    public int getHeight() {
        return height;
    }
    
    /** Setter for property height.
     * @param height New value of property height.
     *
     */
    public void setHeight(int height) {
        if (this.height == height) return;
        this.height = height;
        incrementReportChanges();
    }
    
    /** Getter for property isSummaryNewPage.
     * @return Value of property isSummaryNewPage.
     *
     */
    public boolean isIsSummaryNewPage() {
        return isSummaryNewPage;
    }
    
    /** Setter for property isSummaryNewPage.
     * @param isSummaryNewPage New value of property isSummaryNewPage.
     *
     */
    public void setIsSummaryNewPage(boolean isSummaryNewPage) {
        if (this.isSummaryNewPage == isSummaryNewPage) return;
        this.isSummaryNewPage = isSummaryNewPage;
        incrementReportChanges();
    }
    
    /** Getter for property isTitleNewPage.
     * @return Value of property isTitleNewPage.
     *
     */
    public boolean isIsTitleNewPage() {
        return isTitleNewPage;
    }
    
    /** Setter for property isTitleNewPage.
     * @param isTitleNewPage New value of property isTitleNewPage.
     *
     */
    public void setIsTitleNewPage(boolean isTitleNewPage) {
        if (this.isTitleNewPage == isTitleNewPage) return;
        this.isTitleNewPage = isTitleNewPage;
        incrementReportChanges();
    }
    
    /** Getter for property leftMargin.
     * @return Value of property leftMargin.
     *
     */
    public int getLeftMargin() {
        return leftMargin;
    }
    
    /** Setter for property leftMargin.
     * @param leftMargin New value of property leftMargin.
     *
     */
    public void setLeftMargin(int leftMargin) {
        if (this.leftMargin == leftMargin) return;
        this.leftMargin = leftMargin;
        incrementReportChanges();
    }
    
    /** Getter for property loadTime.
     * @return Value of property loadTime.
     *
     */
    public long getLoadTime() {
        return loadTime;
    }
    
    /** Setter for property loadTime.
     * @param loadTime New value of property loadTime.
     *
     */
    public void setLoadTime(long loadTime) {
        this.loadTime = loadTime;
    }
        
    /** Getter for property orientation.
     * @return Value of property orientation.
     *
     */
    public java.lang.String getOrientation() {
        return orientation;
    }
    
    /** Setter for property orientation.
     * @param orientation New value of property orientation.
     *
     */
    public void setOrientation(java.lang.String orientation) {
        if ((this.orientation == null) ? orientation == null : this.orientation.equals(orientation)) return;
        this.orientation = orientation;
        incrementReportChanges();
    }
           
    /** Getter for property printOrder.
     * @return Value of property printOrder.
     *
     */
    public java.lang.String getPrintOrder() {
        return printOrder;
    }
    
    /** Setter for property printOrder.
     * @param printOrder New value of property printOrder.
     *
     */
    public void setPrintOrder(java.lang.String printOrder) {
         if ((this.printOrder == null) ? printOrder == null : this.printOrder.equals(printOrder)) return;
        this.printOrder = printOrder;
        incrementReportChanges();
    }
    
    /** Getter for property rightMargin.
     * @return Value of property rightMargin.
     *
     */
    public int getRightMargin() {
        return rightMargin;
    }
    
    /** Setter for property rightMargin.
     * @param rightMargin New value of property rightMargin.
     *
     */
    public void setRightMargin(int rightMargin) {
        if (this.rightMargin == rightMargin) return;
        this.rightMargin = rightMargin;
        incrementReportChanges();
    }
    
    
    
    /** Getter for property topMargin.
     * @return Value of property topMargin.
     *
     */
    public int getTopMargin() {
        return topMargin;
    }
    
    /** Setter for property topMargin.
     * @param topMargin New value of property topMargin.
     *
     */
    public void setTopMargin(int topMargin) {
        if (this.topMargin == topMargin) return;
        this.topMargin = topMargin;
        incrementReportChanges();
    }
       
    public void addImport(String _import) {
        if (!imports.contains(_import)) { 
            this.imports.add(_import);
            incrementReportChanges();
        }
    }
      
    /** Getter for property whenNoDataType.
     * @return Value of property whenNoDataType.
     *
     */
    public java.lang.String getWhenNoDataType() {
        return whenNoDataType;
    }
    
    /** Setter for property whenNoDataType.
     * @param whenNoDataType New value of property whenNoDataType.
     *
     */
    public void setWhenNoDataType(java.lang.String whenNoDataType) {
        if ((this.whenNoDataType == null) ? whenNoDataType == null : this.whenNoDataType.equals(whenNoDataType)) return;
        this.whenNoDataType = whenNoDataType;
        incrementReportChanges();
    }
    
    /** Getter for property width.
     * @return Value of property width.
     *
     */
    public int getWidth() {
        return width;
    }
    
    /** Setter for property width.
     * @param width New value of property width.
     *
     */
    public void setWidth(int width) {
        if (this.width == width) return;
        this.width = width;
        incrementReportChanges();
    }
    
    /**
     *  This function compute the Y location of the band.
     *  In the designer panel, there is as space of 10 pixels (the space
     *  between the top border of the panel, and the begin of the
     *  virtual page) that are not added to this measure. This is
     *  important because permit to multiply this height for a
     *  zoom factor.
     *
     * @param b it.businesslogic.ireport.Band The band to compute.
     */
    public int getBandYLocation(Band b) {
        int y = topMargin;
        
        for (Iterator i = this.bands.iterator(); i.hasNext(); ) {
            Band band = (Band) i.next();
            if (band != b) {
                y += band.getHeight();
            } else {
                break;
            }
        }
        
        return y;
    }
    
    /** Getter for property reportFrame.
     * @return Value of property reportFrame.
     *
     */
    public it.businesslogic.ireport.gui.JReportFrame getReportFrame() {
        return reportFrame;
    }
    
    /** Setter for property reportFrame.
     * @param reportFrame New value of property reportFrame.
     *
     */
    public void setReportFrame(it.businesslogic.ireport.gui.JReportFrame reportFrame) {
        this.reportFrame = reportFrame;
    }
    
    /** Getter for property reportFormat.
     * @return Value of property reportFormat.
     *
     */
    public java.lang.String getReportFormat() {
        return reportFormat;
    }
    
    /** Setter for property reportFormat.
     * @param reportFormat New value of property reportFormat.
     *
     */
    public void setReportFormat(java.lang.String reportFormat) {
        this.reportFormat = reportFormat;
    }
    
    /**
     *  This method return the height needed by a graphics to
     *  draw all the document.
     */
    public int getDesignHeight() {
        int y = topMargin + bottomMargin;
        
        for (Iterator i = this.bands.iterator(); i.hasNext(); ) {
            y += ((Band) i.next()).getHeight();
        }
        
        return y;
    }
    
    public int getDesignHeightNoBG() {
        int y=0;
        y  += topMargin;
        y  += bottomMargin;
        
        for (Iterator i = this.bands.iterator(); i.hasNext(); ) {
            Band b = (Band) i.next();
            if (!b.getName().equals("background"))
                y += b.getHeight();
        }
        
        return y;
    }
    
    /** Add a group to the reprot and perform an adjust on jReportFrame
     * @param group New group to be inserted.
     *
     */
    public void addGroup(Group grp) {
        addGroup(grp,true);
    }
    
    /** Add a group to the reprot and perform an adjust on jReportFrame if
     *  specified
     * @param group New group to be inserted.
     * @param adjust If true, perform an adjust on jReportFrame
     */
    public void addGroup(Group grp, boolean adjust) {
        incrementReportChanges();
        if (!getGroups().contains(grp)) {
            getGroups().addElement(grp);
        }
        String bandsstr = "";
        
        /*
         * start looking for the detail band.
         * and place header and footer of new group around it if (Adjust)
         */
        for (int i = 0; i < bands.size(); i++) {
            Band b = (Band)bands.elementAt(i);
            
            if (b.getName().equals("detail")) {
                
                if (adjust) {
                    
                    int bandYLocation = getBandYLocation(b);
                    
                    for (Iterator i2 = elements.iterator(); i2.hasNext(); ) {
                        ReportElement elem = (ReportElement) i2.next();
                        int delta_y = grp.getGroupHeader().getHeight();
                        
                        if (elem.band == grp.getGroupHeader() || elem.band == grp.getGroupFooter()) {
                            // Do nothing
                        }
                        else if (elem.position.y >= bandYLocation + 10 + b.getHeight()) {
                            delta_y += grp.getGroupFooter().getHeight();
                            elem.trasform(new java.awt.Point(0, delta_y), TransformationType.TRANSFORMATION_MOVE);
                        }
                        else if (elem.position.y >= bandYLocation  + 10) {
                            elem.trasform(new java.awt.Point(0, delta_y), TransformationType.TRANSFORMATION_MOVE);
                        }
                    }
                }
                
                // All elements with top >  detail.top must be shifted of groupHeader height
                bands.insertElementAt(grp.getGroupHeader(),i);
                // All elements with top > detail.top + detail.bottom must be shifted of groupFooter height
                bands.insertElementAt(grp.getGroupFooter(),i+2);
                
                break;
            }
        }
        addVariable(new it.businesslogic.ireport.JRVariable(grp.getName()+"_COUNT","java.lang.Integer", true));
        
    }
    
    /**
     *  grpOne will be palce within grpTwo
     *  This means the header band of grpOne will come after the header band of grpTwo
     *  And the footer band of grpOne will come before the footer band of grpTwo
     * @author: Robert Lamping
     * @param direction  1 = down, -1 -up
     * @param grp  The group that must be moved
     */
    public synchronized void moveGroup(Group grp, int direction ) {
        
        Group grpOne = null;
        Group grpTwo = null;
        
        if ( getGroups().size() <=1 ) {
            return; // nothing to do
        }
        incrementReportChanges();
        if (direction == 1) {
            // down
            // there must be at least one element below:
            if ( getGroups().lastElement() ==  grp ) {
                return ;               // nothing to do
            }
            grpOne = grp;
            grpTwo = (Group) getGroups().get( getGroups().indexOf(grp) + 1);
            
        } else {
            // up
            // there must be at least one element above
            if ( getGroups().firstElement() ==  grp ) {
                return ;               // nothing to do
            }
            grpTwo = grp;
            grpOne = (Group) getGroups().get( getGroups().indexOf(grp) - 1);
        }
        
        Band bandGrpOneHeader = getBandByName( grpOne.getGroupHeader().getName());
        Band bandGrpTwoHeader = getBandByName( grpTwo.getGroupHeader().getName());
        Band bandGrpOneFooter = getBandByName( grpOne.getGroupFooter().getName());
        Band bandGrpTwoFooter = getBandByName( grpTwo.getGroupFooter().getName());
        
        int delta1 = bandGrpOneHeader.getHeight();
        int delta2 = bandGrpTwoHeader.getHeight();
        int delta3 = bandGrpOneFooter.getHeight();
        int delta4 = bandGrpTwoFooter.getHeight();
        
        // Move the elements
        for (Iterator i = elements.iterator(); i.hasNext(); ) {
            ReportElement re = (ReportElement) i.next();
            
            if (re.band == bandGrpOneHeader ) {
                re.trasform(new java.awt.Point(0, delta2 ), TransformationType.TRANSFORMATION_MOVE);
            } else if (re.band ==  bandGrpTwoHeader ) {
                re.trasform(new java.awt.Point(0, -delta1 ), TransformationType.TRANSFORMATION_MOVE);
            } else if ( re.band == bandGrpTwoFooter ) {
                re.trasform(new java.awt.Point(0, delta3 ), TransformationType.TRANSFORMATION_MOVE);
            } else if ( re.band ==  bandGrpOneFooter ) {
                re.trasform(new java.awt.Point(0, -delta4 ), TransformationType.TRANSFORMATION_MOVE);
            }
        }
        
        // Now move the groups withing the bands array.
        // Move Band Group Headers
        int pos1 = bands.indexOf( bandGrpOneHeader);
        Band bandBuffer = (Band) bands.get(pos1);
        bands.remove(pos1);
        bands.insertElementAt(bandBuffer, pos1+1);
        
        // Move Band Group Footers
        int pos3 = bands.indexOf( bandGrpTwoFooter);
        bandBuffer = (Band) bands.get(pos3);
        bands.remove(pos3);
        bands.insertElementAt(bandBuffer, pos3+1);
        
        // Now move the groups within the group array
        int groupPos = getGroups().indexOf( grpOne );
        // groupTwo is always after grpOne
        Group groupBuffer = (Group) getGroups().get( groupPos);
        getGroups().remove(groupPos);
        getGroups().insertElementAt( groupBuffer, groupPos + 1);
        
    }
    
    public void delGroup(Group grp) {
        if (!getGroups().contains(grp)) return;
        incrementReportChanges();
        
        String bandsstr = "";
        
        for (int i=0; i<getVariables().size(); ++i)
        {
            JRVariable var = (JRVariable)getVariables().elementAt(i);
            if (var.isBuiltin() && var.getName().equalsIgnoreCase(grp.getName()+"_COUNT"))
            {
                removeVariable(var);
                break;
            }
        }
        
        for (int i=0; i<elements.size(); ++i) {
            // Remove all elements of this group...
            ReportElement elem = (ReportElement)elements.elementAt(i);
            if (elem.getBand() == grp.getGroupHeader() || elem.getBand() == grp.getGroupFooter()) {
                elements.removeElementAt(i);
                i--;
                continue;
            }
            // Adjust elements posisitions...
            // Il element
            int delta_y = grp.getGroupHeader().getHeight();
            if (elem.position.y >= getBandYLocation(grp.getGroupFooter())+10+grp.getGroupFooter().getHeight()) {
                delta_y += grp.getGroupFooter().getHeight();
                elem.trasform(new java.awt.Point(0, -delta_y), TransformationType.TRANSFORMATION_MOVE);
            }
            else if (elem.position.y >= getBandYLocation(grp.getGroupHeader())+10+grp.getGroupHeader().getHeight()) {
                elem.trasform(new java.awt.Point(0, -delta_y), TransformationType.TRANSFORMATION_MOVE);
            }
        }
        
        bands.removeElement(grp.getGroupHeader());
        bands.removeElement(grp.getGroupFooter());
        getGroups().removeElement(grp);
    }
    
    public Group getGroupByName(String name) {
        for (int i = 0; i < getGroups().size(); i++) {
            Group grp = (Group)getGroups().elementAt(i);
            if (grp.getName().equals(name)) {
                return grp;
            }
        }
        return null;
    }
    
    public Band getBandByName(String name) {
        for (int i=0; i< bands.size(); i++) {
            Band band = (Band)bands.elementAt(i);
            if (band.getName().equals(name)) {
                return band;
            }
        }
        return null;
    }
    
    
    
    public void saveXMLFile() {
        saveXMLFile( this.getFilename());
        
    }
    
    public void saveXMLFile( String aFilename ) {
        if(isReadOnly()){
            javax.swing.JOptionPane.showMessageDialog(getReportFrame().getMainFrame(),
            it.businesslogic.ireport.util.I18n.getString("fileReadOnly", "File is read only and cannot be saved."),
            it.businesslogic.ireport.util.I18n.getString("save","Save"),javax.swing.JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        
        String scriptletFileName = getScriptletFileName(aFilename);
        
        String className = "";
        java.io.File classFile = new  java.io.File(scriptletFileName);
        
        className = classFile.getName().substring(0, classFile.getName().length()-5);
        
        if (getScriptletHandling() == SCRIPTLET_IREPORT_INTERNAL_HANDLING) {
            this.setScriptletClass( className );
        }
        
        for (int pk= 0; pk < this.getJRproperties().size(); ++pk) {
            JRProperty prop = (JRProperty)getJRproperties().elementAt( pk );
            if (prop.getName().equals("ireport.scriptlethandling") ||
                prop.getName().equals("ireport.encoding")) {
                getJRproperties().remove( prop );
                pk--;
            }
        }
        
        JRProperty prop = new JRProperty();
        prop.setName( "ireport.scriptlethandling" );
        prop.setValue( ""+ this.getScriptletHandling() );
        this.getJRproperties().add( prop );
        
        prop = new JRProperty();
        prop.setName( "ireport.encoding" );
        prop.setValue( ""+ this.getEncoding() );
        this.getJRproperties().add( prop );
        
        try {
            
            // Default file encoding
            String fileencoding = "UTF-8";
            if (encoding != null && !encoding.trim().equals("")) {
                fileencoding = encoding;
                if (fileencoding.equalsIgnoreCase("UTF-8")){
                    fileencoding = "UTF8"; // Hack for J++
                }
            } else{
                encoding = "UTF-8"; // Default XML encoding
            }
            
            //this.setCursor(Cursor.WAIT );
            //java.io.PrintWriter pw = new java.io.PrintWriter( new java.io.FileOutputStream( filename ));
            PrintWriter pw = new PrintWriter( new java.io.OutputStreamWriter( new java.io.FileOutputStream( aFilename ), fileencoding )); //UTF8
            
            pw.print("<?xml version=\"1.0\"");
            if (encoding != null && encoding.length()>0) {
                pw.print(" encoding=\""+ encoding +"\" ");
            }
            pw.println(" ?>");
            pw.println("<!-- Created with iReport - A designer for JasperReports -->");
            pw.println("<!DOCTYPE jasperReport PUBLIC \"//JasperReports//DTD Report Design//EN\" \"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd\">");
            //pw.println("-->");
            // Jasper report element...
            pw.println("<jasperReport");
            pw.println("\t\t name=\""+ this.getName()  +"\"");
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR066 && this.getLanguage() != null &&
               !this.getLanguage().trim().equals("") && !this.getLanguage().equals("java") )
            {
                pw.print("\n\t\t language=\"" + this.getLanguage().trim() + "\"");
            }

            pw.println("\t\t columnCount=\""+ columnCount  +"\"");
            pw.println("\t\t printOrder=\""+ printOrder +"\"");
            pw.println("\t\t orientation=\""+ this.getOrientation() +"\"");
            pw.println("\t\t pageWidth=\""+ this.getWidth() +"\"");
            pw.println("\t\t pageHeight=\""+ this.getHeight() +"\"");
            pw.println("\t\t columnWidth=\""+  columnWidth +"\"");
            pw.println("\t\t columnSpacing=\""+ columnSpacing  +"\"");
            pw.println("\t\t leftMargin=\""+ leftMargin +"\"");
            pw.println("\t\t rightMargin=\""+ rightMargin +"\"");
            pw.println("\t\t topMargin=\""+ topMargin +"\"");
            pw.println("\t\t bottomMargin=\""+ bottomMargin +"\"");
            pw.println("\t\t whenNoDataType=\""+ whenNoDataType +"\"");
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR063 && isFloatColumnFooter() )
            {
                    pw.println("\t\t isFloatColumnFooter=\"true\"");
            }
            
            if (getScriptletClass() != null && getScriptletClass().length()>0){
                pw.println("\t\t scriptletClass=\""+ getScriptletClass() +"\"");
            }
            
            pw.println("\t\t isTitleNewPage=\""+ this.isTitleNewPage  +"\"");
            pw.print("\t\t isSummaryNewPage=\""+ this.isSummaryNewPage +"\"");
             if ( CompatibilitySupport.version >= CompatibilitySupport.JR062 && this.getResourceBundleBaseName()!=null 
             	  && !this.getResourceBundleBaseName().trim().equals(""))
            {
                pw.print("\n\t\t resourceBundle=\"" + this.getResourceBundleBaseName().trim() + "\"");
            }
            
             if ( CompatibilitySupport.version >= CompatibilitySupport.JR100 && this.getWhenResourceMissingType()!=null 
             	  && !this.getWhenResourceMissingType().trim().equals("Null"))
            {
                pw.print("\n\t\t whenResourceMissingType=\"" + this.getWhenResourceMissingType().trim() + "\"");
            }     
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR111 && isIgnorePagination() )
            {
                    pw.print("\n\t\t isIgnorePagination=\"true\"");
            }
            
            pw.println(">");
            
            // Properties...
            Enumeration e = null;
            
            e = getJRproperties().elements();
            while (e.hasMoreElements()) {
                JRProperty property = (JRProperty)e.nextElement();
                if (!property.getName().startsWith("chart."))
                {
                    pw.print("\t<property name=\""+ Misc.xmlEscape(property.getName()) + "\" ");
                    pw.println("value=\""+ Misc.xmlEscape(property.getValue()) + "\" />");
                }

            }
            // For any chart element...
            Enumeration enum_chartElements = this.getElements().elements();
            while (enum_chartElements.hasMoreElements())
            {
                    ReportElement re = (ReportElement)enum_chartElements.nextElement();
                    if (re instanceof ChartReportElement)
                    {
                        Properties props = ((ChartReportElement)re).getProps();
                        String name = re.getName();
                        
                        Iterator keys = props.keySet().iterator();
                        int i=0;
                        while (keys.hasNext())
                        {
                            String key = ""+keys.next();
                            String val = props.getProperty(key);
                            pw.print("\t<property name=\""+ "chart." + name + "."+key + "\" ");
                            pw.println("value=\""+ Misc.xmlEscape( val) + "\" />");
                        }
                    }
            }
            
            // For IMPORTS..
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR062 )
            {
                e = imports.elements();
                while (e.hasMoreElements()) {
                    String _import = (String)e.nextElement();
                    pw.print("\t<import ");
                    pw.println("value=\""+ _import + "\" />");
                }
            }
            
            e = fonts.elements();
            
            while (e.hasMoreElements()) {
                IReportFont font = (IReportFont)e.nextElement();
                pw.print("\t<reportFont name=\""+ font.getReportFont() + "\" ");
                pw.print("isDefault=\""+ font.isDefaultFont() + "\" ");
                pw.print("fontName=\""+ font.getFontName() + "\" ");
                pw.print("size=\""+ font.getFontSize() + "\" ");
                pw.print("isBold=\""+ font.isBold() + "\" ");
                pw.print("isItalic=\""+ font.isItalic() + "\" ");
                pw.print("isUnderline=\""+ font.isUnderline() + "\" ");
                pw.print("isStrikeThrough=\""+ font.isStrikeTrought() + "\" ");
                if (Misc.nvl(font.getPDFFontName(), "").indexOf("TTF") > 0)
                    //TODO: this line cause write "" to xml when pdfFontName terminate with "TTF".
                    //this error was solved in IReportFont.setPDFFontName() take a look.
                    pw.print("pdfFontName=\""+ font.getTTFFont() + "\" ");
                else
                    pw.print("pdfFontName=\""+ font.getPDFFontName() + "\" ");
                pw.print("pdfEncoding=\""+ font.getPdfEncoding() + "\" ");
                pw.println("isPdfEmbedded=\""+ font.isPdfEmbedded() + "\"/>");
            }
            
            // Styles
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR111 )
            {
                writeXMLStyles(getStyles(), pw, "\t");
            }
            
            // SubDataset...
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR110)
            {
                writeXMLSubDatasets(getSubDatasets(), pw, "\t");
            }
            
            // Parameters
            writeXMLParameters(getParameters(), pw, "\t");
            
            // QueryString
            if (getQuery() != null && getQuery().trim().length() >0 ) {
                
                pw.print("\t<queryString");
                
                if ( CompatibilitySupport.version >= CompatibilitySupport.JR120 &&
                     !this.getQueryLanguage().equals("sql"))
                {
                    pw.print(" language=\"" + this.getQueryLanguage() + "\"");
                }
                pw.println(">"+ getCDATAString(getQuery(),1) + "</queryString>");
            }
            
            // fileds...
            writeXMLFields(getFields(), pw, "\t");
            
            
            // variables...
            writeXMLVariables(getVariables(), pw, "\t");
            
            
            // groups...
            writeXMLGroups(getGroups(), pw,true,2);
            
            // if ( CompatibilitySupport.saveBackground)
            {
                writeXMLSection("background", pw);
            }
            
            writeXMLSection("title", pw);
            writeXMLSection("pageHeader", pw);
            writeXMLSection("columnHeader", pw);
            writeXMLSection("detail", pw);
            writeXMLSection("columnFooter", pw);
            writeXMLSection("pageFooter", pw);
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR061 )
            {
                writeXMLSection("lastPageFooter", pw);
            }
            writeXMLSection("summary", pw);
            
            pw.println("</jasperReport>");
            pw.close();
            
            if (aFilename != null) {	/*
                                com.ms.wfc.io.File f = new com.ms.wfc.io.File(filename, com.ms.wfc.io.FileMode.OPEN);
                                this.loadTime = f.getLastWriteTime().toLong();
                                f.close();
             */
            }
        } catch (Exception ex) {
            //this.setCursor(Cursor.DEFAULT);
            //MessageBox.show(ex.getMessage());
            
            java.io.StringWriter s = new java.io.StringWriter();
            ex.printStackTrace(new java.io.PrintWriter(s));
            javax.swing.JOptionPane.showMessageDialog(getReportFrame().getMainFrame(),ex.getMessage()+" "+s,"Exception",javax.swing.JOptionPane.ERROR_MESSAGE);
        }
        //this.setCursor(Cursor.DEFAULT);
        this.setLoadTime( Misc.getLastWriteTime( this.getFilename() ));
        
        // saving the scriptlet...
        if (getScriptletHandling() == SCRIPTLET_IREPORT_INTERNAL_HANDLING) {
            try {
                
                String allcode = new String(scripletCode.getAll() +"");
                
                allcode = Misc.string_replace(className,"<ScriptletClassName>", allcode);
                java.io.FileOutputStream fos = new java.io.FileOutputStream(scriptletFileName);
                fos.write( allcode.getBytes() );
                fos.close();
                
            } catch (Exception ex) {
                java.io.StringWriter s = new java.io.StringWriter();
                ex.printStackTrace(new java.io.PrintWriter(s));
                javax.swing.JOptionPane.showMessageDialog(getReportFrame().getMainFrame(),ex.getMessage()+" "+s,"Exception",javax.swing.JOptionPane.ERROR_MESSAGE);
            }
        }
        
        this.setReportChanges(0);
    }
    
    void writeXMLSection(String section, PrintWriter pw) {
        // Find band...
        Band band = null;

        for (Iterator i = this.bands.iterator(); i.hasNext(); ) {
            band = (Band) i.next();
            if (band.getName().equalsIgnoreCase(section)) {
                break;
            }
        }
        if (band == null) {
            return;
        }
        
        if (section.equals("lastPageFooter") 
            && band.getHeight() == 0) return;
        
        pw.println("\t\t<"+ section +">");
        writeXMLBand(band, pw);
        pw.println("\t\t</"+ section +">");
    }
    
    void writeXMLSubDatasets(Vector subDatasets, PrintWriter pw, String tabs) {
            Enumeration e = subDatasets.elements();
            
            while (e.hasMoreElements()) {
                
                    pw.println("");
                
                    it.businesslogic.ireport.SubDataset subDataset = (it.businesslogic.ireport.SubDataset)e.nextElement();
                  
                    pw.print(tabs + "<subDataset name=\""+ subDataset.getName() +"\" ");
                    if (subDataset.getScriptletClass() != null && subDataset.getScriptletClass().length()>0){
                        pw.println( tabs + "\t scriptletClass=\""+ subDataset.getScriptletClass() +"\"");
                    }

                    if (subDataset.getResourceBundleBaseName()!=null && !subDataset.getResourceBundleBaseName().trim().equals(""))
                    {
                        pw.print("\n" + tabs +"\t resourceBundle=\"" + this.getResourceBundleBaseName().trim() + "\"");
                    }

                    if ( subDataset.getWhenResourceMissingType()!=null && !subDataset.getWhenResourceMissingType().trim().equals("Null"))
                    {
                        pw.print("\n" + tabs + "\t whenResourceMissingType=\"" + this.getWhenResourceMissingType().trim() + "\"");
                    }                    
                    pw.println(">");
                                
                    if ( CompatibilitySupport.version >= CompatibilitySupport.JR120 )
                    {
                        // properties...
                        Enumeration eProperties = subDataset.getJRproperties().elements();
                        while (eProperties.hasMoreElements()) {
                            JRProperty property = (JRProperty)eProperties.nextElement();
                            pw.print(tabs + "\t<property name=\""+ Misc.xmlEscape(property.getName()) + "\" ");
                            pw.println("value=\""+ Misc.xmlEscape(property.getValue()) + "\" />");
                        }
                    }
                    
                    // Parameters
                    writeXMLParameters(subDataset.getParameters(), pw, "\t\t");

                    // QueryString
                    if (subDataset.getQuery() != null && subDataset.getQuery().trim().length() >0 ) {
                        pw.print(tabs+ "\t<queryString");
                
                        if ( CompatibilitySupport.version >= CompatibilitySupport.JR120 &&
                             !subDataset.getQueryLanguage().equals("sql"))
                        {
                            pw.print(" language=\"" + subDataset.getQueryLanguage() + "\"");
                        }
                        pw.println(">"+  getCDATAString(subDataset.getQuery(),1) + "</queryString>");
                    }

                    // fileds...
                    writeXMLFields(subDataset.getFields(), pw, "\t\t");


                    // variables...
                    writeXMLVariables(subDataset.getVariables(), pw, "\t\t");


                    // groups...
                    writeXMLGroups(subDataset.getGroups(), pw,false,2);
                    pw.println(tabs + "</subDataset>");
            }
    }
    
    void writeXMLParameters(Vector parameters, PrintWriter pw, String tabs) {
            Enumeration e = parameters.elements();
            if (parameters.size() > 0) pw.println("");
            while (e.hasMoreElements()) {
                it.businesslogic.ireport.JRParameter p = (it.businesslogic.ireport.JRParameter)e.nextElement();
                if (p.isBuiltin()) continue;
                
                pw.print(tabs + "<parameter name=\""+ p.getName() +"\" ");
                if (p.getClassType() == null ) p.setClassType("java.lang.String");
                pw.print("isForPrompting=\""+ p.isIsForPrompting() +"\" ");
                pw.print("class=\""+ p.getClassType() +"\"");
                
                if (p.getDefaultValueExpression().trim().length()> 0 ||
                p.getDescription().trim().length()>0) {
                    pw.println(">");
                    if (p.getDescription().trim().length()> 0)
                        pw.println(tabs + "\t<parameterDescription>"+ getCDATAString(p.getDescription(),2) +"</parameterDescription>");
                    if (p.getDefaultValueExpression().trim().length()> 0) {
                        pw.print(tabs + "\t<defaultValueExpression ");
                                                /*
                                                if( this.isUsingMultiLineExpressions() ) {
                                                        pw.print(" isCode=\"true\" ");
                                                }
                                                 */
                        pw.println(">" + getCDATAString(p.getDefaultValueExpression(),2 ) +"</defaultValueExpression>");
                    }
                    pw.println(tabs + "</parameter>");
                }
                else
                    pw.println("/>");
                
            }
            
            // reset dirty operations...
            
    }
    
    void writeXMLFields(Vector fields, PrintWriter pw, String tabs)
    {
            Enumeration e = fields.elements();
            if (fields.size() > 0) pw.println("");
            while (e.hasMoreElements()) {
                it.businesslogic.ireport.JRField f = (it.businesslogic.ireport.JRField)e.nextElement();
                pw.print(tabs + "<field name=\""+ f.getName() +"\" ");
                if (f.getClassType() == null ) f.setClassType("java.lang.String");
                pw.print("class=\""+ f.getClassType() +"\"");
                
                if (f.getDescription().trim().length()>0) {
                    pw.println(">");
                    if (f.getDescription().trim().length()> 0)
                        pw.println(tabs + "\t<fieldDescription>"+ getCDATAString(f.getDescription(),2) +"</fieldDescription>");
                    pw.println(tabs + "</field>");
                }
                else
                    pw.println("/>");
            }
    }
    
    void writeXMLVariables(Vector variables, PrintWriter pw, String tabs)
    {
            Enumeration e = variables.elements();
            if (variables.size() > 0) pw.println("");
            while (e.hasMoreElements()) {
                it.businesslogic.ireport.JRVariable f = (it.businesslogic.ireport.JRVariable)e.nextElement();
                if (f.isBuiltin()) continue;
                pw.print(tabs + "<variable name=\""+ f.getName() +"\" ");
                if (f.getClassType() == null ) f.setClassType("java.lang.String");
                pw.print("class=\""+ f.getClassType() +"\" ");
                pw.print("resetType=\""+ f.getResetType() +"\" ");
                
                // From JasperReport 0.5.3
                if (f.getIncrementerFactoryClass() != null &&
                f.getIncrementerFactoryClass().trim().length() > 0) {
                    pw.print("incrementerFactoryClass=\""+ f.getIncrementerFactoryClass() +"\" ");
                }
                
                if ( CompatibilitySupport.version >= CompatibilitySupport.JR066 && f.getIncrementType() !=null 
             	  && !f.getIncrementType().trim().equals("None"))
                {
                    pw.print("incrementType=\"" + f.getIncrementType().trim() + "\" ");
                    if (f.getIncrementType().equals("Group"))
                    {
                        pw.print("incrementGroup=\"" + f.getIncrementGroup().trim() + "\" ");
                    }
                }
                
                if (f.getResetGroup().length() >0 ) pw.print("resetGroup=\""+ f.getResetGroup() +"\" ");
                pw.println("calculation=\""+ f.getCalculation()  +"\">");
                if (f.getExpression().length()>0) {
                    pw.print(tabs + "\t<variableExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+ getCDATAString(f.getExpression(),2) + "</variableExpression>");
                }
                if (f.getInitialValueExpression().length()>0) {
                    pw.print(tabs + "\t<initialValueExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(f.getInitialValueExpression(),2) +"</initialValueExpression>");
                }
                pw.println(tabs + "</variable>");
            }
    }
    
    void writeXMLMeasures(Vector measures, PrintWriter pw, String tabs)
    {
            Enumeration e = measures.elements();
            if (measures.size() > 0) pw.println("");
            while (e.hasMoreElements()) {
                it.businesslogic.ireport.crosstab.Measure f = (it.businesslogic.ireport.crosstab.Measure)e.nextElement();
                
                pw.print(tabs + "<measure name=\""+ f.getName() +"\"");
                if (f.getClassType() == null ) f.setClassType("java.lang.String");
                pw.print(" class=\""+ f.getClassType() +"\"");
                if (!f.getCalculation().equals("Nothing"))  pw.print(" calculation=\""+ f.getCalculation() +"\"");
                if (f.getIncrementerFactoryClass().trim().length() > 0)  pw.print(" incrementerFactoryClass=\""+ f.getIncrementerFactoryClass() +"\"");
                if (!f.getPercentageOf().equals("None"))  pw.print(" percentageOf=\""+ f.getPercentageOf() +"\"");
                if (f.getPercentageCalculatorClass().trim().length() > 0)  pw.print(" percentageCalculatorClass=\""+ f.getPercentageCalculatorClass() +"\"");
                pw.println(">");
                
                if (f.getExpression().length()>0) {
                    pw.print(tabs + "\t<measureExpression>");
                    pw.println(getCDATAString(f.getExpression(),2) + "</measureExpression>");
                }
                
                pw.println(tabs + "</measure>");
            }
    }
    
    void writeXMLCrosstabParameters(Vector parameters, PrintWriter pw, String tabs)
    {
            Enumeration e = parameters.elements();
            if (parameters.size() > 0) pw.println("");
            while (e.hasMoreElements()) {
                it.businesslogic.ireport.crosstab.CrosstabParameter f = (it.businesslogic.ireport.crosstab.CrosstabParameter)e.nextElement();

                pw.print(tabs + "<crosstabParameter name=\""+ f.getName() +"\" ");
                if (f.getClassType() == null ) f.setClassType("java.lang.String");
                pw.print("class=\""+ f.getClassType() +"\" ");
                pw.print(">");
                
                if (f.getParameterValueExpression().length()>0) {
                    pw.print(tabs + "\t<parameterValueExpression>");
                    pw.println(""+ getCDATAString(f.getParameterValueExpression(), tabs.length()+1 ) + "</parameterValueExpression>");
                }
                
                pw.println(tabs + "</crosstabParameter>");
            }
    }
    
    
    void writeXMLGroups(Vector groups, java.io.PrintWriter pw, boolean writeAll, int tabCount) {
        // Find band...
        if (groups.size() > 0) pw.println("");
        for (int i=0; i< groups.size(); i++) {
            Group grp = (Group)groups.elementAt(i);
            for (int t=0; t<tabCount; ++t) pw.print("\t");
            pw.print("<group ");
            pw.print(" name=\""+grp.getName()  +"\"");
            if (grp.isIsStartNewColumn()) pw.print(" isStartNewColumn=\""+grp.isIsStartNewColumn() +"\"");
            if (grp.isIsStartNewPage()) pw.print(" isStartNewPage=\""+grp.isIsStartNewPage() +"\"");
            if (grp.isIsResetPageNumber()) pw.print(" isResetPageNumber=\""+grp.isIsResetPageNumber() +"\"");
            if (grp.isIsReprintHeaderOnEachPage()) pw.print(" isReprintHeaderOnEachPage=\""+grp.isIsReprintHeaderOnEachPage() +"\"");
            if (grp.getMinHeightToStartNewPage() != 0) pw.print(" minHeightToStartNewPage=\""+grp.getMinHeightToStartNewPage() +"\"");
            pw.println(" >");
            pw.print("\t\t\t<groupExpression");
                        /*
                        if(this.isUsingMultiLineExpressions()) {
                                pw.print(" isCode=\"true\" ");
                        }
                         */
            pw.println(">" + getCDATAString(grp.getGroupExpression() ,tabCount + 1) +"</groupExpression>");
            if (writeAll)
            {
                pw.println("\t\t\t<groupHeader>");
                writeXMLBand(grp.getGroupHeader(), pw);
                pw.println("\t\t\t</groupHeader>");
                pw.println("\t\t\t<groupFooter>");
                writeXMLBand(grp.getGroupFooter(), pw);
                pw.println("\t\t\t</groupFooter>");
            }
            for (int t=0; t<tabCount; ++t) pw.print("\t");
            pw.println("</group>");
        }
    }
    
    void writeXMLStyles(Vector styles, java.io.PrintWriter pw, String tabs)
    {

            Enumeration e = styles.elements();
            if (styles.size() > 0) pw.println("");
            while (e.hasMoreElements()) {
                it.businesslogic.ireport.Style style = (it.businesslogic.ireport.Style)e.nextElement();
                
                String tabs2 = tabs;
                if ( CompatibilitySupport.version >= CompatibilitySupport.JR120 )
                {
                    if (style instanceof ConditionedStyle)
                    {
                        pw.println(tabs2 + "<conditionalStyle>");
                        tabs += "\t";
                        pw.print(tabs + "<conditionExpression");
                        pw.println(">" + getCDATAString(((ConditionedStyle)style).getCondition() ,tabs2.length()+1) +"</conditionExpression>");
                    }
                    
                }
                
                pw.println(tabs + "<style ");
                for (int i=0; i<Style.JRXMLStyleAttributes.length; ++i)
                {
                    if ( style.getAttributes().containsKey(Style.JRXMLStyleAttributes[i]) &&
                         style.getAttributes().get( Style.JRXMLStyleAttributes[i] ) != null) {
                         Object obj = style.getAttributes().get(Style.JRXMLStyleAttributes[i]);
                         String value = ""+obj;
                         if (obj instanceof java.awt.Color)
                         {
                             value = writeEncodedColor( (java.awt.Color)obj);
                         }
                         if (Style.JRXMLStyleAttributes[i].toLowerCase().endsWith("color") && value.startsWith("["))
                         {
                             // The color is in the form [r,g,b]...
                             try {
                               value =   writeEncodedColor(it.businesslogic.ireport.gui.sheet.ColorSelectorPanel.parseColorString(value));
                             } catch (Exception ex)
                             {
                                 value="black";
                             }
                         }
                         if (Style.JRXMLStyleAttributes[i].equals("style"))
                         {
                             if (value == null || value.trim().length() == 0) continue;
                         }
                         pw.println(tabs + "\t" + Style.JRXMLStyleAttributes[i] + "=\"" + value +"\"");
                    }
                }
                
                if (CompatibilitySupport.version < CompatibilitySupport.JR120 || style.getConditionedStyles().size() == 0)
                {
                    pw.println(tabs + "/>");
                }
                else
                {
                    pw.println(tabs + ">");
                    writeXMLStyles(style.getConditionedStyles(), pw, tabs+"\t");
                    pw.println(tabs + "</style>");
                }
                if ( CompatibilitySupport.version >= CompatibilitySupport.JR120 )
                {
                    if (style instanceof ConditionedStyle)
                    {
                        pw.println(tabs2 + "</conditionalStyle>");
                    }
                }
            }
    }
    
    void writeXMLBand(Band band, PrintWriter pw) {
        pw.print("\t\t\t<band height=\""+ band.getHeight() + "\" ");
        
        //if () //JasperReports 0.5.0 is supported...
        {
            pw.print(" isSplitAllowed=\"" + band.isSplitAllowed() + "\" ");
        }
        pw.println(">");
        
        if (band.getPrintWhenExpression().trim().length() > 0) {
            pw.print("\t\t\t\t<printWhenExpression");
                        /*
                        if(this.isUsingMultiLineExpressions()) {
                                pw.print(" isCode=\"true\" ");
                        }
                         */
            pw.println(">" + getCDATAString(band.getPrintWhenExpression(),4) + "</printWhenExpression>");
        }
        
        writeBandElements(pw, band, null);
        pw.println("\t\t\t</band>");
    }
    
    
    public void writeBandElements(PrintWriter pw, Band band, ReportElement parent)
    {
        String actualElementGroup = "";
        for (Iterator i = this.elements.iterator(); i.hasNext(); ) {
            ReportElement re = (ReportElement) i.next();
            if (re.band == band && re.getParentElement() == parent) {
                    actualElementGroup = writeOpenCloseGroup(pw,re.getElementGroup(), actualElementGroup);
                    writeXMLReportElement(re,pw);
            }
        }
        writeOpenCloseGroup(pw, "", actualElementGroup);
    }
    
    public String writeOpenCloseGroup(PrintWriter pw, String newGroup, String oldGroup)
    {
        if (oldGroup.equals(newGroup)) return newGroup;
        while (!newGroup.startsWith( oldGroup) && oldGroup.length() > 0)
        {
                pw.println("\t\t\t\t</elementGroup><!-- End " + oldGroup + " !-->");
                if (oldGroup.lastIndexOf(".") >= 0)
                {
                    oldGroup = oldGroup.substring(0, oldGroup.lastIndexOf("."));
                }
                else
                {
                    oldGroup="";
                }
        }

        String remainNewGroup = newGroup;
        if (oldGroup.length() > 0 && newGroup.startsWith(oldGroup))
        {
            remainNewGroup = newGroup.substring(oldGroup.length()+1);
        }
        
        String groupName = remainNewGroup;
        while (remainNewGroup.length() > 0)
        {
            pw.print("\t\t\t\t<elementGroup>");

            if (remainNewGroup.indexOf(".") >= 0)
            {
                groupName = ((oldGroup.length() > 0)  ? oldGroup + "." : "") + remainNewGroup.substring(0,remainNewGroup.indexOf("."));
                oldGroup = remainNewGroup.substring(0,remainNewGroup.indexOf("."));
                remainNewGroup = remainNewGroup.substring(remainNewGroup.indexOf(".")+1);
            }
            else
            {
                groupName = ((oldGroup.length() > 0)  ? oldGroup + "." : "") + remainNewGroup;
                remainNewGroup="";
            }
            pw.println("<!--  Start: " + groupName + " !-->");
        }
        
        return newGroup;
    }
    
    void writeXMLReportElement(ReportElement re, PrintWriter pw) {
        if (re instanceof StaticTextReportElement) {
            pw.println("\t\t\t\t<staticText>");
            
            writeXMLReportElementElement(re, pw);
            writeXMLBox( ((TextReportElement)re).getBox(), pw );
            writeXMLTextElementElement((TextReportElement)re, pw);
            pw.println("\t\t\t\t<text>"+getCDATAString(((StaticTextReportElement)re).getText(), 4)+"</text>");
            pw.println("\t\t\t\t</staticText>");
            
        }
        else if (re instanceof FrameReportElement)
        {
            FrameReportElement fre = (FrameReportElement)re;
            pw.print("\t\t\t\t<frame>");
            writeXMLReportElementElement(fre, pw);
            writeXMLBox( ((BoxElement)fre).getBox(), pw );
            if (re instanceof FrameReportElement)
            {
                   writeBandElements(pw, re.getBand(), re);
            }
            pw.print("\t\t\t\t</frame>");
        }
        else if (re instanceof TextFieldReportElement) {
            TextFieldReportElement tfre = (TextFieldReportElement)re;
            pw.print("\t\t\t\t<textField");
            pw.print(" isStretchWithOverflow=\""+ tfre.isStretchWithOverflow() +"\"");
            
            if (tfre.getPropertyValue(tfre.PATTERN) != null)
            {
                pw.print(" pattern=\"" + tfre.getPattern() + "\"");
            }
            
            pw.print(" isBlankWhenNull=\"" + tfre.isBlankWhenNull() +"\"");
            pw.print(" evaluationTime=\""+ tfre.getEvaluationTime() +"\"");
            if (tfre.getEvaluationTime().equals("Group")) {
                pw.print(" evaluationGroup=\"" + tfre.getGroup() +"\" ");
            }
            pw.print(" hyperlinkType=\"" + tfre.getHyperlinkType() +"\" ");
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR062 )
            {
                pw.print(" hyperlinkTarget=\"" + tfre.getHyperlinkTarget() +"\" ");
            }
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR100 )
            {
                if (tfre.getBookmarkLevel() != 0 ) pw.print(" bookmarkLevel=\"" + tfre.getBookmarkLevel() +"\" ");
            }
            
            pw.println(">");
           
            writeXMLReportElementElement(tfre, pw);
            writeXMLBox(((TextReportElement)re).getBox(), pw);
            writeXMLTextElementElement(tfre, pw);
            pw.print("\t\t\t\t<textFieldExpression ");
            if (tfre.getClassExpression().length() > 0) {
                pw.print("  class=\""+ tfre.getClassExpression()+"\"");
            }
                        /*
                        if(this.isUsingMultiLineExpressions()) {
                                pw.print(" isCode=\"true\" ");
                        }
                         */
            pw.println(">"+getCDATAString(((TextFieldReportElement)re).getText(),4)+"</textFieldExpression>");
            
            if (tfre.getAnchorNameExpression() != null && tfre.getAnchorNameExpression().length() > 0) {
                pw.print("\t\t\t\t\t<anchorNameExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(tfre.getAnchorNameExpression(),5)+"</anchorNameExpression>");
            }
            if (tfre.getHyperlinkType() != null && tfre.getHyperlinkType().length() > 0) {
                if ( tfre.getHyperlinkType().equals("Reference") ||
                tfre.getHyperlinkType().equals("RemoteAnchor") ||
                tfre.getHyperlinkType().equals("RemotePage")) {
                    pw.print("\t\t\t\t\t<hyperlinkReferenceExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(tfre.getHyperlinkReferenceExpression(),5)+"</hyperlinkReferenceExpression>");
                }
                if ( tfre.getHyperlinkType().equals("LocalAnchor") ||
                tfre.getHyperlinkType().equals("RemoteAnchor")) {
                    pw.print("\t\t\t\t\t<hyperlinkAnchorExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(tfre.getHyperlinkAnchorExpression(),5)+"</hyperlinkAnchorExpression>");
                }
                
                if ( tfre.getHyperlinkType().equals("LocalPage") ||
                tfre.getHyperlinkType().equals("RemotePage")) {
                    pw.print("\t\t\t\t\t<hyperlinkPageExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(tfre.getHyperlinkPageExpression(),5)+"</hyperlinkPageExpression>");
                }
            }
            
            pw.println("\t\t\t\t</textField>");
        }
        else if (re instanceof ImageReportElement) {
            ImageReportElement ire = (ImageReportElement)re;
            pw.print("\t\t\t\t<image ");
            
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(ire.getScaleImage()+"",Style.ATTRIBUTE_scaleImage,re.getStyle(), getDefaultStyle()))
            if (ire.getPropertyValue( ire.SCALE) != null)
            {
                pw.print(" scaleImage=\""+ ire.getScaleImage()  +"\"");
            }
            
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(ire.getVerticalAlignment()+"",Style.ATTRIBUTE_vAlign,re.getStyle(), getDefaultStyle()))
            if (ire.getPropertyValue( ire.VERTICAL_ALIGN) != null)
            {
                pw.print(" vAlign=\""+ ire.getVerticalAlignment()  +"\"");
            }
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(ire.getHorizontalAlignment()+"",Style.ATTRIBUTE_hAlign,re.getStyle(), getDefaultStyle()))
            if (ire.getPropertyValue( ire.HORIZONTAL_ALIGN) != null)
            {
                pw.print(" hAlign=\""+ ire.getHorizontalAlignment()  +"\"");
            }
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR065 && ire.isIsLazy() == true)
            {
                pw.print(" isLazy=\""+ ire.isIsLazy() +"\"");
            }
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR103 && !ire.getOnErrorType().equals("Error"))
            {
                pw.print(" onErrorType=\""+ ire.getOnErrorType() +"\"");
            }
            
            if (ire.getPropertyValue( ire.USING_CACHE) != null)
            {
                pw.print(" isUsingCache=\""+ ire.isIsUsingCache() +"\"");
            }
            
            pw.print(" evaluationTime=\""+ ire.getEvaluationTime() + "\"");
            
            if (((ImageReportElement)re).getEvaluationTime().equals("Group")) {
                pw.print(" evaluationGroup=\"" + ire.getEvaluationGroup() +"\" ");
            }
            
            pw.print(" hyperlinkType=\"" + ire.getHyperlinkType()+"\" ");
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR062 )
            {
                pw.print(" hyperlinkTarget=\"" + ire.getHyperlinkTarget() +"\" ");
            }
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR100 )
            {
                if (ire.getBookmarkLevel() != 0 ) pw.print(" bookmarkLevel=\"" + ire.getBookmarkLevel() +"\" ");
            }
            
            pw.println(">");
            
            
            writeXMLReportElementElement(re, pw);
            writeXMLBox( ((ImageReportElement)re).getBox(),  pw);
            writeXMLGraphicElement(ire,pw);
            
            if (re instanceof ChartReportElement) {
                pw.print("\t\t\t\t\t<imageExpression class=\"java.awt.Image\"");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.print(">"
                // + getCDATAString( getExpressionString( ire.getImageClass(), ire.getImageExpression() ), 5) +
                + getCDATAString(
                writeChartExpression( (ChartReportElement)re)
                , 5) + "</imageExpression>\n" );
            }
            else {
                pw.print("\t\t\t\t\t<imageExpression class=\""+ ire.getImageClass() + "\"");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"
                // + getCDATAString( getExpressionString( ire.getImageClass(), ire.getImageExpression() ), 5) +
                + getCDATAString(  ire.getImageExpression(), 5) + "</imageExpression>" );
            }
            
            
            
            if (ire.getAnchorNameExpression() != null && ire.getAnchorNameExpression().length() > 0) {
                pw.print("\t\t\t\t\t<anchorNameExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(ire.getAnchorNameExpression(),5)+"</anchorNameExpression>");
            }
            if (ire.getHyperlinkType() != null && ire.getHyperlinkType().length() > 0) {
                if ( ire.getHyperlinkType().equals("Reference") ||
                ire.getHyperlinkType().equals("RemoteAnchor") ||
                ire.getHyperlinkType().equals("RemotePage")) {
                    pw.print("\t\t\t\t\t<hyperlinkReferenceExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(ire.getHyperlinkReferenceExpression(),5) +"</hyperlinkReferenceExpression>");
                }
                
                if ( ire.getHyperlinkType().equals("LocalAnchor") ||
                ire.getHyperlinkType().equals("RemoteAnchor")) {
                    pw.print("\t\t\t\t\t<hyperlinkAnchorExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(ire.getHyperlinkAnchorExpression(),5)+"</hyperlinkAnchorExpression>");
                }
                
                if ( ire.getHyperlinkType().equals("LocalPage") ||
                ire.getHyperlinkType().equals("RemotePage")) {
                    pw.print("\t\t\t\t\t<hyperlinkPageExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(ire.getHyperlinkPageExpression(),5) +"</hyperlinkPageExpression>");
                }
            }
            pw.println("\t\t\t\t</image>");
            
        } else if (re instanceof LineReportElement) {
            LineReportElement lre = (LineReportElement)re;
            pw.println("\t\t\t\t<line direction=\""+ lre.getDirection() +"\">");
            writeXMLReportElementElement(re, pw);
            writeXMLGraphicElement(lre,pw);
            pw.println("\t\t\t\t</line>");
            
        } else if (re instanceof RectangleReportElement) {
            RectangleReportElement rre = (RectangleReportElement)re;
            pw.print("\t\t\t\t<rectangle");
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(rre.getRadius()+"",Style.ATTRIBUTE_radius,re.getStyle(), getDefaultStyle()))
            if (rre.getPropertyValue( rre.RADIUS) != null)
            {
                pw.print(" radius=\""+ rre.getRadius() + "\" ");
            }
            pw.println(">");
            writeXMLReportElementElement(re, pw);
            writeXMLGraphicElement(rre,pw);
            pw.println("\t\t\t\t</rectangle>");
            
        } else if (re instanceof EllipseReportElement ) {
            //if ( CompatibilitySupport.saveEllipse )
            {
                EllipseReportElement ere = (EllipseReportElement)re;
                pw.println("\t\t\t\t<ellipse>");
                writeXMLReportElementElement(ere, pw);
                writeXMLGraphicElement(ere,pw);
                pw.println("\t\t\t\t</ellipse>");
            }
        }
        else if (re instanceof SubReportElement) {
            SubReportElement sre = (SubReportElement)re;
            pw.println("\t\t\t\t<subreport  isUsingCache=\""+ sre.isIsUsingCache()  +"\">");
            writeXMLReportElementElement(re, pw);
            if (sre.getParametersMapExpression() != null &&
            sre.getParametersMapExpression().trim().length() > 0) {
                pw.print("\t\t\t\t\t<parametersMapExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(sre.getParametersMapExpression(),5)+"</parametersMapExpression>");
            }
            
            Enumeration e = sre.getSubreportParameters().elements();
            while (e.hasMoreElements()) {
                JRSubreportParameter je = (JRSubreportParameter)e.nextElement();
                pw.println("\t\t\t\t\t<subreportParameter  name=\""+ je.getName() +"\">");
                pw.print("\t\t\t\t\t\t<subreportParameterExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(je.getExpression(),6)+"</subreportParameterExpression>");
                pw.println("\t\t\t\t\t</subreportParameter>");
            }
            if (sre.isUseConnection() && sre.getConnectionExpression().trim().length() > 0 ) {
                pw.print("\t\t\t\t\t<connectionExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(sre.getConnectionExpression(),5 )+ "</connectionExpression>");
            }
            else if (!sre.isUseConnection()  && sre.getDataSourceExpression().length() > 0) {
                pw.print("\t\t\t\t\t<dataSourceExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(sre.getDataSourceExpression(),5 )+"</dataSourceExpression>");
            }
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR100)
            {
                Enumeration e_sr = sre.getReturnValues().elements();
                while (e_sr.hasMoreElements()) {
                    it.businesslogic.ireport.JRSubreportReturnValue jerv = (it.businesslogic.ireport.JRSubreportReturnValue)e_sr.nextElement();
                    pw.print("\t\t\t\t\t<returnValue");
                    if (jerv.getSubreportVariable()!= null && jerv.getSubreportVariable().length()>0) pw.print(" subreportVariable=\""+ jerv.getSubreportVariable() +"\"");
                    if (jerv.getToVariable()!= null && jerv.getToVariable().length()>0) pw.print(" toVariable=\""+ jerv.getToVariable() +"\"");
                    if (jerv.getCalculation() != null && !jerv.getCalculation().equals("Nothing")) pw.print(" calculation=\""+ jerv.getCalculation() +"\"");
                    if (jerv.getIncrementFactoryClass()!= null && jerv.getIncrementFactoryClass().length()>0) pw.print(" incrementerFactoryClass=\""+ jerv.getIncrementFactoryClass() +"\"");
                    pw.println("/>");
                }
            }
            
            if (sre.getSubreportExpression()  != null &&
            sre.getSubreportExpression().trim().length() > 0) {
                pw.print("\t\t\t\t\t<subreportExpression  class=\""+ sre.getSubreportExpressionClass()  +"\"");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">" +
                getCDATAString(sre.getSubreportExpression(),5) + "</subreportExpression>");
            }
            
            pw.println("\t\t\t\t</subreport>");
        } else if (re instanceof ChartReportElement2 ) {
            writeChartElement((ChartReportElement2)re, pw);
        } else if (re instanceof CrosstabReportElement) {
            CrosstabReportElement cre = (CrosstabReportElement)re;
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR111 )
            {
                pw.print("\t\t\t\t<crosstab ");
                    if (!cre.isRepeatColumnHeaders()) pw.print("isRepeatColumnHeaders=\""+ cre.isRepeatColumnHeaders() +"\" ");
                    if (!cre.isRepeatRowHeaders()) pw.print("isRepeatRowHeaders=\""+ cre.isRepeatRowHeaders() +"\" ");
                    if (cre.getColumnBreakOffset() != 10) pw.print("columnBreakOffset=\""+ cre.getColumnBreakOffset() +"\" ");
                pw.println(">");
                writeXMLReportElementElement(re, pw);
                writeXMLCrosstabParameters(cre.getCrosstabParameters(),pw,"\t\t\t\t\t");
                
                if (cre.getParametersMapExpression() != null && cre.getParametersMapExpression().trim().length() > 0) {
                    pw.print("\t\t\t\t\t<parametersMapExpression>");
                    pw.println(getCDATAString(cre.getParametersMapExpression(),5)+"</parametersMapExpression>");
                }
                
                if (cre.isUseDataset() ) {
                    pw.print("\t\t\t\t\t<crosstabDataset");
                        if (cre.isPreSorted()) pw.print(" isDataPreSorted=\""+ cre.isPreSorted() +"\" ");
                    pw.println(">");
                    if (cre.getDataset() != null)
                    {
                        writeDatasetDataset( cre.getDataset(), pw );
                    }
                    pw.println("\t\t\t\t\t</crosstabDataset>");
                }
                
                if ( CompatibilitySupport.version >= CompatibilitySupport.JR120 )
                {
                    for (int i=0; i<cre.getCells().size(); ++i)
                    {
                        CrosstabCell cell = (CrosstabCell)cre.getCells().elementAt(i);
                        if (cell.getType() == cell.CT_HEADER_CELL)
                        {
                            pw.print("\t\t\t\t\t<crosstabHeaderCell>");
                            writeXMLCrosstabCellcontents( cell, cre.getElements(), pw, "\t\t\t\t\t\t");
                            pw.print("\t\t\t\t\t</crosstabHeaderCell>");
                        }
                    }
                }
                
                writeXMLCrosstabRowGroups(cre.getRowGroups(), cre.getElements(), pw);
                writeXMLCrosstabColumnGroups(cre.getColumnGroups(),  cre.getElements(), pw);
                writeXMLMeasures(cre.getMeasures(), pw, "\t\t\t\t\t");
                writeXMLCrosstabCells(cre.getCells(), cre.getElements(), pw, "\t\t\t\t\t");
                
                for (int i=0; i<cre.getCells().size(); ++i)
                {
                    CrosstabCell cell = (CrosstabCell)cre.getCells().elementAt(i);
                    if (cell.getType() == cell.NODATA_CELL)
                    {
                        pw.print("\t\t\t\t\t<whenNoDataCell>");
                        writeXMLCrosstabCellcontents( cell, cre.getElements(), pw, "\t\t\t\t\t\t");
                        pw.print("\t\t\t\t\t</whenNoDataCell>");
                    }
                }
                
                
                
                pw.println("\t\t\t\t\t</crosstab>");
            }
        }
        
    }
    
    void writeXMLBox(Box box, PrintWriter pw) {
        
        if ( CompatibilitySupport.version >= CompatibilitySupport.JR063 )
        {
            if (box == null) return;
            pw.print("\t\t\t\t\t<box");
            if (box.getTopBorder() != null) pw.print(" topBorder=\"" + box.getTopBorder() + "\"");
            if (box.getTopBorderColor() != null) pw.print(" topBorderColor=\"" +  writeEncodedColor( box.getTopBorderColor() ) + "\"");
            if (box.getTopPadding() > 0) pw.print(" topPadding=\"" + box.getTopPadding() + "\"");
            
            if (box.getLeftBorder() != null) pw.print(" leftBorder=\"" + box.getLeftBorder() + "\"");
            if (box.getLeftBorderColor() != null) pw.print(" leftBorderColor=\"" +  writeEncodedColor( box.getLeftBorderColor() ) + "\"");
            if (box.getLeftPadding() > 0) pw.print(" leftPadding=\"" + box.getLeftPadding() + "\"");
            
            if (box.getRightBorder() != null) pw.print(" rightBorder=\"" + box.getRightBorder() + "\"");
            if (box.getRightBorderColor() != null) pw.print(" rightBorderColor=\"" +  writeEncodedColor( box.getRightBorderColor() ) + "\"");
            if (box.getRightPadding() > 0) pw.print(" rightPadding=\"" + box.getRightPadding() + "\"");
            
            if (box.getBottomBorder() != null) pw.print(" bottomBorder=\"" + box.getBottomBorder() + "\"");
            if (box.getBottomBorderColor() != null) pw.print(" bottomBorderColor=\"" +  writeEncodedColor( box.getBottomBorderColor() ) + "\"");
            if (box.getBottomPadding() > 0) pw.print(" bottomPadding=\"" + box.getBottomPadding() + "\"");
            pw.println("/>");
        }
    }
    
        void writeFontElement(IReportFont font, PrintWriter pw) {
        
            if (font == null) return;
            pw.print("\t\t\t\t\t<font");
            
            IReportFont base = getReportFontByName( font.getReportFont() );
            
            if (font.getReportFont() != null && font.getReportFont().length() > 0) pw.print(" reportFont=\"" +  font.getReportFont() + "\"");
            
            if (base != null && base.getFontName().equals( font.getFontName())) { /* use default value */ } 
            else if (font.getFontName() != null && font.getFontName().length() > 0) pw.print(" fontName=\"" +  font.getFontName() + "\"");
            
            if ( base != null && base.getPDFFontName().equals( font.getPDFFontName())) { /* use default value */ } 
            else if (font.getPDFFontName() != null && font.getPDFFontName().length() > 0) pw.print(" pdfFontName=\"" +  font.getPDFFontName() + "\"");
                    
            if ( base != null && base.getFontSize() == font.getFontSize() ) { /* use default value */ } 
            else pw.print(" size=\"" +  font.getFontSize() + "\"");
            
            if ( base != null && base.isBold() == font.isBold() ) { /* use default value */ } 
            else pw.print(" isBold=\"" +  ((font.isBold()) ? "true" : "false") + "\"");
            
            if ( base != null && base.isItalic() == font.isItalic() ) { /* use default value */ } 
            else pw.print(" isItalic=\"" +  ((font.isItalic()) ? "true" : "false") + "\"");
        
            if ( base != null && base.isUnderline() == font.isUnderline() ) { /* use default value */ } 
            else pw.print(" isUnderline=\"" +  ((font.isUnderline()) ? "true" : "false") + "\"");
            
            if ( base != null && base.isStrikeTrought() == font.isStrikeTrought() ) { /* use default value */ } 
            else pw.print(" isStrikeThrough=\"" +  ((font.isStrikeTrought()) ? "true" : "false") + "\"");
        
            if ( base != null && base.isPdfEmbedded() == font.isPdfEmbedded() ) { /* use default value */ } 
            else pw.print(" isPdfEmbedded=\"" +  ((font.isPdfEmbedded()) ? "true" : "false") + "\"");
            
            if ( base != null && base.getPdfEncoding().equals(font.getPdfEncoding()) ) { /* use default value */ } 
            else if (font.getPdfEncoding() != null && font.getPdfEncoding().length() > 0) pw.print(" pdfEncoding=\"" +  font.getPdfEncoding() + "\"");
            
            pw.println("/>");
    }
    
    
    void writeXMLReportElementElement(ReportElement re, PrintWriter pw) {
        pw.print("\t\t\t\t\t<reportElement");
        
        if ( CompatibilitySupport.version >= CompatibilitySupport.JR111 )
        {
            if ( re.getStyle() != null)
               pw.print("\n\t\t\t\t\t\tstyle=\""+  re.getStyle() + "\"");
        }
        
        //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getTransparent(),Style.ATTRIBUTE_mode,re.getStyle(), getDefaultStyle()))
        {
            if (re.getPropertyValue(re.MODE) != null)
            {
                pw.print("\n\t\t\t\t\t\tmode=\""+ re.getTransparent() + "\"");
            }
        }
            
        int position_x = re.getPosition().x;
        
        if (re.getParentElement() != null) position_x -= re.getParentElement().getPosition().x;
        else if (re.getCell() != null) position_x = position_x - re.getCell().getLeft()- 10;   
        else position_x = position_x - leftMargin - 10;    
        
        pw.print("\n\t\t\t\t\t\tx=\""+ position_x + "\"");
        
        int position_y = re.getPosition().y;
        if (re.getParentElement() != null) position_y -= re.getParentElement().getPosition().y;
        else if (re.getCell() != null) position_y = position_y - re.getCell().getTop()- 10;  
        else position_y = position_y - 10 - getBandYLocation(re.getBand());   
        
        pw.print("\n\t\t\t\t\t\ty=\""+ position_y +"\"");
        
        pw.print("\n\t\t\t\t\t\twidth=\""+ re.getWidth() + "\"");
        pw.print("\n\t\t\t\t\t\theight=\""+ re.getHeight() + "\"");
        

        //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getFgcolor(),Style.ATTRIBUTE_forecolor,re.getStyle(), getDefaultStyle()))
        {
            if (re.getColorValue(re.FGCOLOR, null) != null)
            {
                pw.print("\n\t\t\t\t\t\tforecolor=\""+ writeEncodedColor(re.getColorValue(re.FGCOLOR, null)) +"\"");
            }
        }
        
        //if (CompatibilitySupport.version < CompatibilitySupport.JR111 || !Style.isDefaultValue(re.getBgcolor(),Style.ATTRIBUTE_backcolor,re.getStyle(), getDefaultStyle()) )
        {
            if (re.getColorValue(re.BGCOLOR, null) != null)
            {
                pw.print("\n\t\t\t\t\t\tbackcolor=\""+ writeEncodedColor(re.getColorValue(re.BGCOLOR, null)) +"\"");
            }
        }
        
        // if =052 compatibility....
        if (!re.getKey().equals(""))
        {
            pw.print("\n\t\t\t\t\t\tkey=\""+ re.getKey() +"\"");
        }
        
        if (!re.getStretchType().equals("NoStretch"))
        {
            pw.print("\n\t\t\t\t\t\tstretchType=\""+ re.getStretchType() +"\"");
        }
        
        if (!re.getPositionType().equals("FixRelativeToTop"))
        {
            pw.print("\n\t\t\t\t\t\tpositionType=\""+ re.getPositionType() +"\"");
        }
        
        if (re.isIsPrintRepeatedValues() != true)
        {
            pw.print("\n\t\t\t\t\t\tisPrintRepeatedValues=\""+ re.isIsPrintRepeatedValues() +"\"");
        }
        if (re.isIsRemoveLineWhenBlank() != false)
        { 
            pw.print("\n\t\t\t\t\t\tisRemoveLineWhenBlank=\""+ re.isIsRemoveLineWhenBlank() +"\"");
        }
        if (re.isIsPrintInFirstWholeBand() != false)
        {
            pw.print("\n\t\t\t\t\t\tisPrintInFirstWholeBand=\""+ re.isIsPrintInFirstWholeBand() +"\"");
        }
        
        if (re.getPrintWhenGroupChanges() != null &&  re.getPrintWhenGroupChanges().trim().length()>0)
            pw.print("\n\t\t\t\t\t\tprintWhenGroupChanges=\""+ re.getPrintWhenGroupChanges() +"\"");
        
        if (re.isIsPrintWhenDetailOverflows() != false)
        {
            pw.print("\n\t\t\t\t\t\tisPrintWhenDetailOverflows=\""+ re.isIsPrintWhenDetailOverflows() +"\"");
        }
        
        if (re.getPrintWhenExpression().length()>0) {
            pw.println(">");
            pw.print("\t\t\t\t\t\t\t<printWhenExpression");
                        /*
                        if(this.isUsingMultiLineExpressions()) {
                                pw.print(" isCode=\"true\" ");
                        }
                         */
            pw.println(">"+getCDATAString(re.getPrintWhenExpression(),7) + "</printWhenExpression>");
            pw.println("\t\t\t\t\t\t</reportElement>");
        }
        else{
            pw.println("/>");
        }
        
    }
    
    public static String getCDATAString( String string, int tabCount ) {
        //if ( ! Utils.needToBeInsideCDATA( string ) )
        //	return string;
        String CRLF = System.getProperty("line.separator");
        String tab = "";
        for ( int i = 0; i < tabCount; i++ ) {
            tab += "\t";
        }
        return "<![CDATA[" + string + "]]>"; // + CRLF + tab ;
    }
    
    void writeXMLGraphicElement(GraphicReportElement re, PrintWriter pw) {
        pw.print("\t\t\t\t\t<graphicElement");
        
        pw.print(" stretchType=\"" + re.getStretchType() + "\"");
        //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getGraphicElementPen(),Style.ATTRIBUTE_pen,re.getStyle(), getDefaultStyle()))
        if (re.getPropertyValue(re.PEN) != null)
        {
            pw.print(" pen=\""+ re.getGraphicElementPen() + "\"");
        }
        
        //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getFill(),Style.ATTRIBUTE_fill,re.getStyle(), getDefaultStyle()))

        if (re.getPropertyValue(GraphicReportElement.FILL) != null)
        {
            pw.print(" fill=\"" + re.getFill() + "\" ");
        }
        
        pw.println("/>");
    }
    
    void writeXMLCrosstabRowGroups(Vector crosstabRowGroups, Vector crosstabElements, PrintWriter pw) {
        
        for (int i=0; i<crosstabRowGroups.size(); ++i)
        {
           CrosstabRowGroup group = (CrosstabRowGroup)crosstabRowGroups.elementAt(i);
           
           pw.print("\t\t\t\t\t<rowGroup");
           pw.print(" name=\"" + group.getName() + "\"");
           pw.print(" width=\""+ group.getWidth() + "\"");
           if (!group.getTotalPosition().equals("None"))  pw.print(" totalPosition=\""+ group.getTotalPosition() + "\"");
           if (!group.getHeaderPosition().equals("Top"))  pw.print(" headerPosition=\""+ group.getHeaderPosition() + "\"");
           pw.println(">");
           
           // BUCKET
           writeXMLBucket(group, pw);
           
           if (group.getHeaderCell().getHeight() > 0 && group.getHeaderCell().getWidth() > 0)
           {
               pw.println("\t\t\t\t\t\t<crosstabRowHeader>");
               writeXMLCrosstabCellcontents(group.getHeaderCell(), crosstabElements, pw, "\t\t\t\t\t\t\t"); 
               pw.println("\t\t\t\t\t\t</crosstabRowHeader>");
           }
           
           if (group.getTotalCell().getHeight() > 0 && group.getTotalCell().getWidth() > 0)
           {
               pw.println("\t\t\t\t\t\t<crosstabTotalRowHeader>");
               writeXMLCrosstabCellcontents(group.getTotalCell(), crosstabElements, pw, "\t\t\t\t\t\t\t"); 
               pw.println("\t\t\t\t\t\t</crosstabTotalRowHeader>");
           }
           
           pw.println("\t\t\t\t\t</rowGroup>");
        }
        
    }
    
    void writeXMLCrosstabColumnGroups(Vector crosstabColumnGroups, Vector crosstabElements, PrintWriter pw) {
        
        for (int i=0; i<crosstabColumnGroups.size(); ++i)
        {
           CrosstabColumnGroup group = (CrosstabColumnGroup)crosstabColumnGroups.elementAt(i);
           
           pw.print("\t\t\t\t\t<columnGroup");
           pw.print(" name=\"" + group.getName() + "\"");
           pw.print(" height=\""+ group.getHeight() + "\"");
           if (!group.getTotalPosition().equals("None"))  pw.print(" totalPosition=\""+ group.getTotalPosition() + "\"");
           if (!group.getHeaderPosition().equals("Left"))  pw.print(" headerPosition=\""+ group.getHeaderPosition() + "\"");
           pw.println(">");
           
           // BUCKET
           writeXMLBucket(group, pw);
           
           if (group.getHeaderCell().getHeight() > 0 && group.getHeaderCell().getWidth() > 0)
           {
               pw.println("\t\t\t\t\t\t<crosstabColumnHeader>");
               writeXMLCrosstabCellcontents(group.getHeaderCell(), crosstabElements, pw, "\t\t\t\t\t\t\t"); 
               pw.println("\t\t\t\t\t\t</crosstabColumnHeader>");
           }
           
           if (group.getTotalCell().getHeight() > 0 && group.getTotalCell().getWidth() > 0)
           {
               pw.println("\t\t\t\t\t\t<crosstabTotalColumnHeader>");
               writeXMLCrosstabCellcontents(group.getTotalCell(), crosstabElements, pw, "\t\t\t\t\t\t\t"); 
               pw.println("\t\t\t\t\t\t</crosstabTotalColumnHeader>");
           }
           
           pw.println("\t\t\t\t\t</columnGroup>");
        }
        
    }
    
    void writeXMLCrosstabCellcontents(CrosstabCell cell, Vector elements, PrintWriter pw, String tabs) {
        
        pw.print("\t\t\t\t\t\t<cellContents");
        if (cell.getBackcolor() != null)  pw.print(" backcolor=\""+ writeEncodedColor( cell.getBackcolor() ) + "\"");
        if ( CompatibilitySupport.version >= CompatibilitySupport.JR120)
        {
            pw.print(" mode=\""+ cell.getMode() + "\"");
        }
        
        if ( CompatibilitySupport.version >= CompatibilitySupport.JR120 && cell.getStyle() != null )
        {
            pw.print(" style=\""+ cell.getStyle() + "\"");
        }
        
        pw.println(">");
        
        if (cell.getBox() != null)
        {
            writeXMLBox(cell.getBox(), pw);
        }
        
        for (int i=0; i<elements.size(); ++i)
        {
            ReportElement re = (ReportElement)elements.elementAt(i);
            if (re.getCell() == cell)
            {
                writeXMLReportElement(re, pw);
            }
        }
        pw.println("\t\t\t\t\t\t</cellContents>");
    }
    
    void writeXMLCrosstabCells(Vector cells, Vector elements, PrintWriter pw, String tabs) {
        
        for (int i=0; i<cells.size(); ++i)
        {
            CrosstabCell cell = (CrosstabCell)cells.elementAt(i);
            // Write the cell only if it is a DETAIL cell and if at least one of this expressions is true:
            // height>0 and width > 0
            // is the pure detail cell (columnTotal and RowTotal are blank)
            if (cell.getType() == cell.DETAIL_CELL)
                //&& ( (cell.getWidth() > 0 && cell.getHeight()>0) || 
                //  (cell.getColumnTotalGroup().equals("") && cell.getRowTotalGroup().equals("")))) 
            {
                pw.print(tabs + "<crosstabCell");
                pw.print(" width=\"" + cell.getWidth()+"\"");
                pw.print(" height=\"" + cell.getHeight()+"\"");
                if (cell.getRowTotalGroup().trim().length() > 0)  pw.print(" rowTotalGroup=\""+ cell.getRowTotalGroup() + "\"");
                if (cell.getColumnTotalGroup().trim().length() > 0)  pw.print(" columnTotalGroup=\""+ cell.getColumnTotalGroup() + "\"");
                pw.println(">");
                writeXMLCrosstabCellcontents(cell, elements, pw, tabs+"\t");
        
                pw.println(tabs + "</crosstabCell>");
            }
        }
    }
    
    void writeXMLBucket(CrosstabGroup group, PrintWriter pw) {
            
           pw.print("\t\t\t\t\t\t<bucket");
           if (!group.getBucketOrder().equals("Ascending"))  pw.print(" order=\""+ group.getBucketOrder() + "\"");
           pw.println(">");
           pw.print("\t\t\t\t\t\t\t<bucketExpression");
           pw.print(" class=\""+ group.getBucketExpressionClass() + "\"");
           pw.print(">");
           pw.print(getCDATAString(group.getBucketExpression(),8));
           pw.println("</bucketExpression>");
           
           if (group.getBucketComparatorExpression().trim().length() > 0)
           {
               pw.print("\t\t\t\t\t\t\t<comparatorExpression>");
               pw.print(getCDATAString(group.getBucketComparatorExpression(),8));
               pw.println("</comparatorExpression>");
           }
           pw.println("\t\t\t\t\t\t</bucket>");
    }
    
    void writeXMLTextElementElement(TextReportElement re, PrintWriter pw) {
        java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        nf.setMaximumFractionDigits(0);
        
        
        pw.print("\t\t\t\t\t<textElement");
        
        //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getAlign()+"",Style.ATTRIBUTE_hAlign,re.getStyle(), getDefaultStyle()))
        if (re.getPropertyValue( re.ALIGN) != null)
        {
            pw.print(" textAlignment=\""+ re.getAlign()  +"\"");
        }
        
        //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getVerticalAlign()+"",Style.ATTRIBUTE_vAlign,re.getStyle(), getDefaultStyle()))
        if (re.getPropertyValue( re.VERTICAL_ALIGN) != null)
        {
            pw.print(" verticalAlignment=\""+ re.getVerticalAlign()  +"\"");
        }
        
        //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getRotate()+"",Style.ATTRIBUTE_rotation,re.getStyle(), getDefaultStyle()))
        if (re.getPropertyValue( re.ROTATE) != null)
        {
            pw.print(" rotation=\""+ re.getRotate() +"\"");
        }
        
        // From JasperReport 0.5.3
        //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.isIsStyledText()+"",Style.ATTRIBUTE_isStyledText,re.getStyle(), getDefaultStyle()))
        if (re.getPropertyValue( re.IS_STYLED_TEXT) != null)
        {
            if (re.isIsStyledText()) {
                pw.print(" isStyledText=\"true\"");
            }
        }
        
        //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getLineSpacing()+"",Style.ATTRIBUTE_lineSpacing,re.getStyle(), getDefaultStyle()))
        if (re.getPropertyValue( re.LINE_SPACING) != null)
        {
            pw.print(" lineSpacing=\""+ re.getLineSpacing() +"\"");
        }
        // FONT SECTION. This code saves only difference between
        // the report font (if sepcified)...
        
        pw.println(">");
        pw.print("\t\t\t\t\t\t<font");
        
        IReportFont font = null;
        if (re.getReportFont() != null && re.getReportFont().length()>0) {
            // Search the right font structure...
            for (int fn =0; fn < this.fonts.size(); ++fn) {
                font = (IReportFont)this.fonts.elementAt(fn);
                if (font != null && font.getReportFont().equals(re.getReportFont())) {
                    break;
                }
                else{
                    font = null;
                }
            }
            pw.print(" reportFont=\""+ re.getReportFont() +"\"");
        }
        
        if (font == null || !font.getFontName().equals(re.getFontName() ))
        {
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getFontName()+"",Style.ATTRIBUTE_fontName,re.getStyle(), getDefaultStyle()))
            if (re.getIReportFont().getPropertyValue( IReportFont.FONT_NAME) != null)
            {
                pw.print(" fontName=\"" + re.getFontName() +"\"");
            }
        }
        
        
        if (font == null || !font.getPDFFontName().equalsIgnoreCase(re.getPDFFontName()))
        {
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getPDFFontName()+"",Style.ATTRIBUTE_pdfFontName,re.getStyle(), getDefaultStyle()))
            if (re.getIReportFont().getPropertyValue( IReportFont.PDF_FONT_NAME ) != null)
            {
                pw.print(" pdfFontName=\"" + re.getPDFFontName() +"\"");
            }
        }
        
        //pw.print(" pdfEncoding=\"Times-Roman\"");
        if (font == null || font.getFontSize() != re.getFontSize())
        {
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getFontSize()+"",Style.ATTRIBUTE_fontSize,re.getStyle(), getDefaultStyle()))
            if (re.getIReportFont().getPropertyValue( IReportFont.FONT_SIZE) != null)
            {
                pw.print(" size=\"" +  re.getFontSize()  +"\"");
            }
        }
        
        if (font == null || font.isBold() != re.isBold()) {
            
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.isBold()+"",Style.ATTRIBUTE_isBold,re.getStyle(), getDefaultStyle()))
            if (re.getIReportFont().getPropertyValue( IReportFont.IS_BOLD) != null)
            {
                pw.print(" isBold=\"" + ((re.isBold()) ? "true" : "false")+"\"");
            }
        }
        
        if (font == null || font.isItalic() != re.isItalic()) {
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.isItalic()+"",Style.ATTRIBUTE_isItalic,re.getStyle(), getDefaultStyle()))
            if (re.getIReportFont().getPropertyValue( IReportFont.IS_ITALIC) != null)
            {
                pw.print(" isItalic=\"" + ((re.isItalic()) ? "true" : "false")+"\"");
            }
        }
        
        if (font == null || font.isUnderline() != re.isUnderline()){
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.isUnderline()+"",Style.ATTRIBUTE_isUnderline,re.getStyle(), getDefaultStyle()))
            if (re.getIReportFont().getPropertyValue( IReportFont.IS_UNDERLINE) != null)
            {
                pw.print(" isUnderline=\"" + ((re.isUnderline() ) ? "true" : "false")+"\"");
            }
        }
        
        if (font == null || font.isPdfEmbedded() != re.isPdfEmbedded()){
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.isPdfEmbedded()+"",Style.ATTRIBUTE_isPdfEmbedded,re.getStyle(), getDefaultStyle()))
            if (re.getIReportFont().getPropertyValue( IReportFont.IS_PDF_EMBEDDED) != null)
            {
                pw.print(" isPdfEmbedded =\"" + ((re.isPdfEmbedded() ) ? "true" : "false")+"\"");
            }
        }
        
        if (font == null || font.getPdfEncoding() == null || font.getPdfEncoding().length() == 0) {
            //if (re.getPdfEncoding() != null && re.getPdfEncoding().length() > 0) {
                //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.getPdfEncoding()+"",Style.ATTRIBUTE_pdfEncoding,re.getStyle(), getDefaultStyle()))
                if (re.getIReportFont().getPropertyValue( IReportFont.PDF_ENCODING) != null &&
                    re.getPdfEncoding().length() > 0)
                {
                    pw.print(" pdfEncoding =\"" + re.getPdfEncoding() +"\"");
                }
            //}
        }
        if (font == null || font.isStrikeTrought() != re.isStrikeTrought()){
            //if (CompatibilitySupport.version < CompatibilitySupport.JR111 ||  !Style.isDefaultValue(re.isStrikeTrought()+"",Style.ATTRIBUTE_isStrikeThrough,re.getStyle(), getDefaultStyle()))
            if (re.getIReportFont().getPropertyValue( IReportFont.IS_STRIKETROUGHT) != null)
            {
                pw.print(" isStrikeThrough=\"" + ((re.isStrikeTrought() ) ? "true" : "false")+"\" ");
            }
        }
        
        pw.println("/>");
        pw.println("\t\t\t\t\t</textElement>");
    }
    
    public static String writeEncodedColor(java.awt.Color c) {
        String nums = "0123456789ABCDEF";
        String s = "#";
        s += nums.charAt( c.getRed()/16 );
        s += nums.charAt( c.getRed()%16 );
        s += nums.charAt( c.getGreen()/16 );
        s += nums.charAt( c.getGreen()%16 );
        s += nums.charAt( c.getBlue()/16 );
        s += nums.charAt( c.getBlue()%16 );
        return s;
    }
      
    private String writeChartExpression(ChartReportElement chartElement) {
        String expression = "";
        
        expression = "(java.awt.Image)it.businesslogic.ireport.chart.DefaultChartFactory.drawChart(new String[]{";
        
        Properties props = chartElement.getProps();
        Iterator keys = props.keySet().iterator();
        int i=0;
        while (keys.hasNext())
        {
            String key = ""+keys.next();
            String val = props.getProperty(key);
            if (i>0) expression +=",";
            val = Misc.string_replace("\\\"", "\"", val );
            expression += "\"" + key + "=" + val +"\"";
            i++;
        }
        expression += "}, (it.businesslogic.ireport.IReportScriptlet)$P{REPORT_SCRIPTLET})";
        
        return expression;
    }
    
    private void writeChartElement(ChartReportElement2 chartElement, PrintWriter pw) {
        
        if ( CompatibilitySupport.version >= CompatibilitySupport.JR100 )
        {
            String chartType = "";
            if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.PieChart) chartType = "pieChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.Pie3DChart) chartType = "pie3DChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.BarChart) chartType = "barChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.Bar3DChart) chartType = "bar3DChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.XYBarChart) chartType = "xyBarChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.StackedBarChart) chartType = "stackedBarChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.StackedBar3DChart) chartType = "stackedBar3DChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.LineChart) chartType = "lineChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.XYLineChart) chartType = "xyLineChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.AreaChart) chartType = "areaChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.XYAreaChart) chartType = "xyAreaChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.ScatterChart) chartType = "scatterChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.BubbleChart) chartType = "bubbleChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.TimeSeriesChart) chartType = "timeSeriesChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.HighLowChart) chartType = "highLowChart";
            else if (chartElement.getChart() instanceof it.businesslogic.ireport.chart.CandlestickChart) chartType = "candlestickChart";
   
            pw.println("\t\t\t\t<" + chartType + ">");
            writeChartNode(chartElement, pw);
            writeDataset(chartElement, pw );
            writePlot(chartElement, pw );
            pw.println("\t\t\t\t</" + chartType + ">");
        }
    }
            

    private void writeChartNode(ChartReportElement2 chartElement, PrintWriter pw)
    {
        pw.print("\t\t\t\t\t<chart ");
        if (!chartElement.getChart().isShowLegend()) pw.print("isShowLegend=\"false\" ");
        if (!chartElement.getEvaluationTime().equals("Now")) pw.print("evaluationTime=\"" + chartElement.getEvaluationTime() + "\" ");
        if (!chartElement.getEvaluationGroup().equals("")) pw.print("evaluationGroup=\"" + chartElement.getEvaluationGroup() + "\" ");
        if (!chartElement.getChart().getHyperlinkType().equals("None")) pw.print(" hyperlinkType=\"" + chartElement.getChart().getHyperlinkType() +"\" ");
        if (!chartElement.getChart().getHyperlinkTarget().equals("None")) pw.print(" hyperlinkTarget=\"" + chartElement.getChart().getHyperlinkTarget() +"\" ");
        if (chartElement.getChart().getBookmarkLevel() != 0) pw.print(" bookmarkLevel=\"" + chartElement.getChart().getBookmarkLevel() +"\" ");
        if (chartElement.getChart().getCustomizerClass().length() != 0) pw.print(" customizerClass=\"" + chartElement.getChart().getCustomizerClass()  +"\" ");
        pw.println(">");
        writeXMLReportElementElement(chartElement, pw);
        writeXMLBox(chartElement.getBox(), pw);
        writeChartTitleNode(chartElement, pw);
        writeChartSubTitleNode(chartElement, pw);
        writeHyperLinkExpressions(chartElement.getChart(), pw);
        pw.println("\t\t\t\t\t</chart>");
    }
        
    private void writeHyperLinkExpressions(HyperLinkableReportElement hlink, PrintWriter pw)
    {
        if (hlink.getAnchorNameExpression() != null && hlink.getAnchorNameExpression().length() > 0) {
                pw.println("\t\t\t\t\t\t<anchorNameExpression>"+getCDATAString(hlink.getAnchorNameExpression(),6)+"</anchorNameExpression>");
        }
        if (hlink.getHyperlinkType() != null && hlink.getHyperlinkType().length() > 0) {
            if ( hlink.getHyperlinkType().equals("Reference") ||
                hlink.getHyperlinkType().equals("RemoteAnchor") ||
                hlink.getHyperlinkType().equals("RemotePage")) {
                pw.println("\t\t\t\t\t\t<hyperlinkReferenceExpression>"+getCDATAString(hlink.getHyperlinkReferenceExpression(),6) +"</hyperlinkReferenceExpression>");
            }

            if ( hlink.getHyperlinkType().equals("LocalAnchor") ||
                hlink.getHyperlinkType().equals("RemoteAnchor")) {
                pw.println("\t\t\t\t\t\t<hyperlinkAnchorExpression>"+getCDATAString(hlink.getHyperlinkAnchorExpression(),6)+"</hyperlinkAnchorExpression>");
            }

            if ( hlink.getHyperlinkType().equals("LocalPage") ||
                hlink.getHyperlinkType().equals("RemotePage")) {
                pw.println("\t\t\t\t\t\t<hyperlinkPageExpression>"+getCDATAString(hlink.getHyperlinkPageExpression(),6) +"</hyperlinkPageExpression>");
            }
        }
    }
    
    private void writeChartTitleNode(ChartReportElement2 chartElement, PrintWriter pw)
    {
        if (chartElement.getChart().getTitle().getTitleExpression().trim().length() > 0)
        {
            pw.print("\t\t\t\t\t\t<chartTitle ");
            if (!chartElement.getChart().getTitle().getPosition().equals("Top")) pw.print("position=\"" + chartElement.getChart().getTitle().getPosition() + "\" ");
            if (chartElement.getChart().getTitle().getColor() != null) pw.print("color=\"" +  writeEncodedColor(chartElement.getChart().getTitle().getColor() ) +  "\" ");
            pw.println(">");
            writeFontElement(chartElement.getChart().getTitle().getFont(), pw );
            pw.println("\t\t\t\t\t\t\t\t<titleExpression>" + getCDATAString(chartElement.getChart().getTitle().getTitleExpression(),8 ) + "</titleExpression>");
            pw.println("\t\t\t\t\t</chartTitle>");
        }
    }
    
    private void writeChartSubTitleNode(ChartReportElement2 chartElement, PrintWriter pw)
    {
        if (chartElement.getChart().getSubTitle().getTitleExpression().trim().length() > 0)
        {
            pw.print("\t\t\t\t\t\t<chartSubtitle ");
            if (chartElement.getChart().getSubTitle().getColor() != null) pw.print("color=\"" +  writeEncodedColor(chartElement.getChart().getSubTitle().getColor() ) +  "\" ");
            pw.println(">");
            writeFontElement(chartElement.getChart().getSubTitle().getFont(), pw );
            pw.println("\t\t\t\t\t\t\t\t<subtitleExpression>" + getCDATAString(chartElement.getChart().getSubTitle().getTitleExpression(),8 ) + "</subtitleExpression>");
            pw.println("\t\t\t\t\t</chartSubtitle>");
        }
    }
    
    private void writeDataset(ChartReportElement2 chartElement, PrintWriter pw)
    {
        if (chartElement.getChart().getDataset() instanceof it.businesslogic.ireport.chart.PieDataset)
        {
            it.businesslogic.ireport.chart.PieDataset pdataset = (it.businesslogic.ireport.chart.PieDataset)chartElement.getChart().getDataset();
            pw.println("\t\t\t\t\t<pieDataset>");
            writeDatasetDataset( chartElement.getChart().getDataset(),  pw);
            pw.println("\t\t\t\t\t\t<keyExpression>" + getCDATAString(pdataset.getKeyExpression() ,6 ) + "</keyExpression>");
            pw.println("\t\t\t\t\t\t<valueExpression>" + getCDATAString(pdataset.getValueExpression() ,6 ) + "</valueExpression>");
            if (pdataset.getLabelExpression().trim().length() > 0)
            {
                pw.println("\t\t\t\t\t\t<labelExpression>" + getCDATAString(pdataset.getLabelExpression() ,6 ) + "</labelExpression>");
            }
            pw.println("\t\t\t\t\t</pieDataset>");
        }
        else if (chartElement.getChart().getDataset() instanceof it.businesslogic.ireport.chart.CategoryDataset)
        {
            it.businesslogic.ireport.chart.CategoryDataset pdataset = (it.businesslogic.ireport.chart.CategoryDataset)chartElement.getChart().getDataset();
            pw.println("\t\t\t\t\t<categoryDataset>");
            writeDatasetDataset( chartElement.getChart().getDataset(),  pw);
            for (int i=0; i<pdataset.getCategorySeries().size(); ++i)
            {
                writeCategorySeries( (CategorySeries)pdataset.getCategorySeries().elementAt(i) ,  pw);
            }
            pw.println("\t\t\t\t\t</categoryDataset>");
        }
        else if (chartElement.getChart().getDataset() instanceof it.businesslogic.ireport.chart.TimePeriodDataset)
        {
            it.businesslogic.ireport.chart.TimePeriodDataset pdataset = (it.businesslogic.ireport.chart.TimePeriodDataset)chartElement.getChart().getDataset();
            pw.println("\t\t\t\t\t<timePeriodDataset>");
            writeDatasetDataset( chartElement.getChart().getDataset(),  pw);
            for (int i=0; i<pdataset.getTimePeriodSeries().size(); ++i)
            {
                writeTimePeriodSeries( (TimePeriodSeries)pdataset.getTimePeriodSeries().elementAt(i) ,  pw);
            }
            pw.println("\t\t\t\t\t</timePeriodDataset>");
        }
        else if (chartElement.getChart().getDataset() instanceof it.businesslogic.ireport.chart.TimeSeriesDataset)
        {
            it.businesslogic.ireport.chart.TimeSeriesDataset pdataset = (it.businesslogic.ireport.chart.TimeSeriesDataset)chartElement.getChart().getDataset();
            pw.print("\t\t\t\t\t<timeSeriesDataset");
            if (!pdataset.getTimePeriod().equals("Day")) pw.println(" timePeriod=\"" + pdataset.getTimePeriod() + "\"");
            pw.println(">");
            writeDatasetDataset( chartElement.getChart().getDataset(),  pw);
            for (int i=0; i<pdataset.getTimeSeries().size(); ++i)
            {
                writeTimeSeries((TimeSeries)pdataset.getTimeSeries().elementAt(i) ,  pw);
            }
            pw.println("\t\t\t\t\t</timeSeriesDataset>");
        }
        else if (chartElement.getChart().getDataset() instanceof it.businesslogic.ireport.chart.XYDataset)
        {
            it.businesslogic.ireport.chart.XYDataset pdataset = (it.businesslogic.ireport.chart.XYDataset)chartElement.getChart().getDataset();
            pw.println("\t\t\t\t\t<xyDataset>");
            writeDatasetDataset( chartElement.getChart().getDataset(),  pw);
            for (int i=0; i<pdataset.getXYSeries().size(); ++i)
            {
                writeXYSeries((XYSeries)pdataset.getXYSeries().elementAt(i) ,  pw);
            }
            pw.println("\t\t\t\t\t</xyDataset>");
        }
        else if (chartElement.getChart().getDataset() instanceof it.businesslogic.ireport.chart.XYZDataset)
        {
            it.businesslogic.ireport.chart.XYZDataset pdataset = (it.businesslogic.ireport.chart.XYZDataset)chartElement.getChart().getDataset();
            pw.println("\t\t\t\t\t<xyzDataset>");
            writeDatasetDataset( chartElement.getChart().getDataset(),  pw);
            for (int i=0; i<pdataset.getXYZSeries().size(); ++i)
            {
                writeXYZSeries((XYZSeries)pdataset.getXYZSeries().elementAt(i) ,  pw);
            }
            pw.println("\t\t\t\t\t</xyzDataset>");
        }
        else if (chartElement.getChart().getDataset() instanceof it.businesslogic.ireport.chart.HighLowDataset)
        {
            it.businesslogic.ireport.chart.HighLowDataset pdataset = (it.businesslogic.ireport.chart.HighLowDataset)chartElement.getChart().getDataset();
            pw.println("\t\t\t\t\t<highLowDataset>");
            writeDatasetDataset( chartElement.getChart().getDataset(),  pw);
            pw.println("\t\t\t\t\t\t<seriesExpression>" + getCDATAString(pdataset.getSeriesExpression() ,6 ) + "</seriesExpression>");
            pw.println("\t\t\t\t\t\t<dateExpression>" + getCDATAString(pdataset.getDateExpression() ,6 ) + "</dateExpression>");
            pw.println("\t\t\t\t\t\t<highExpression>" + getCDATAString(pdataset.getHighExpression() ,6 ) + "</highExpression>");
            pw.println("\t\t\t\t\t\t<lowExpression>" + getCDATAString(pdataset.getLowExpression() ,6 ) + "</lowExpression>");
            pw.println("\t\t\t\t\t\t<openExpression>" + getCDATAString(pdataset.getOpenExpression() ,6 ) + "</openExpression>");
            pw.println("\t\t\t\t\t\t<closeExpression>" + getCDATAString(pdataset.getCloseExpression() ,6 ) + "</closeExpression>");
            pw.println("\t\t\t\t\t\t<volumeExpression>" + getCDATAString(pdataset.getVolumeExpression() ,6 ) + "</volumeExpression>");
            pw.println("\t\t\t\t\t</highLowDataset>");
        }
    }
    
    private void writeCategorySeries(CategorySeries cs, PrintWriter pw)
    {
        pw.println("\t\t\t\t\t\t<categorySeries>");
        pw.println("\t\t\t\t\t\t\t<seriesExpression>" + getCDATAString( cs.getSeriesExpression() ,7 ) + "</seriesExpression>");
        pw.println("\t\t\t\t\t\t\t<categoryExpression>" + getCDATAString( cs.getCategoryExpression() ,7 ) + "</categoryExpression>");
        pw.println("\t\t\t\t\t\t\t<valueExpression>" + getCDATAString( cs.getValueExpression() ,7 ) + "</valueExpression>");
        if (cs.getLabelExpression().trim().length() != 0)
            pw.println("\t\t\t\t\t\t\t<labelExpression>" + getCDATAString( cs.getLabelExpression() ,7 ) + "</labelExpression>");
        pw.println("\t\t\t\t\t\t</categorySeries>");
    }
    
    private void writeXYSeries(XYSeries cs, PrintWriter pw)
    {
        pw.println("\t\t\t\t\t\t<xySeries>");
        pw.println("\t\t\t\t\t\t\t<seriesExpression>" + getCDATAString( cs.getSeriesExpression() ,7 ) + "</seriesExpression>");
        pw.println("\t\t\t\t\t\t\t<xValueExpression>" + getCDATAString( cs.getXValueExpression() ,7 ) + "</xValueExpression>");
        pw.println("\t\t\t\t\t\t\t<yValueExpression>" + getCDATAString( cs.getYValueExpression() ,7 ) + "</yValueExpression>");
        if (cs.getLabelExpression().trim().length() != 0)
            pw.println("\t\t\t\t\t\t\t<labelExpression>" + getCDATAString( cs.getLabelExpression() ,7 ) + "</labelExpression>");
        pw.println("\t\t\t\t\t\t</xySeries>");
    }
    
    private void writeXYZSeries(XYZSeries cs, PrintWriter pw)
    {
        pw.println("\t\t\t\t\t\t<xyzSeries>");
        pw.println("\t\t\t\t\t\t\t<seriesExpression>" + getCDATAString( cs.getSeriesExpression() ,7 ) + "</seriesExpression>");
        pw.println("\t\t\t\t\t\t\t<xValueExpression>" + getCDATAString( cs.getXValueExpression() ,7 ) + "</xValueExpression>");
        pw.println("\t\t\t\t\t\t\t<yValueExpression>" + getCDATAString( cs.getYValueExpression() ,7 ) + "</yValueExpression>");
        if (cs.getZValueExpression().trim().length() != 0)
            pw.println("\t\t\t\t\t\t\t<zValueExpression>" + getCDATAString( cs.getZValueExpression() ,7 ) + "</zValueExpression>");
        pw.println("\t\t\t\t\t\t</xyzSeries>");
    }
    
    private void writeTimePeriodSeries(TimePeriodSeries cs, PrintWriter pw)
    {
        pw.println("\t\t\t\t\t\t<timePeriodSeries>");
        pw.println("\t\t\t\t\t\t\t<seriesExpression>" + getCDATAString( cs.getSeriesExpression() ,7 ) + "</seriesExpression>");
        pw.println("\t\t\t\t\t\t\t<startDateExpression>" + getCDATAString( cs.getStartDateExpression() ,7 ) + "</startDateExpression>");
        pw.println("\t\t\t\t\t\t\t<endDateExpression>" + getCDATAString( cs.getStartDateExpression() ,7 ) + "</endDateExpression>");
        pw.println("\t\t\t\t\t\t\t<valueExpression>" + getCDATAString( cs.getValueExpression() ,7 ) + "</valueExpression>");
        if (cs.getLabelExpression().trim().length() != 0)
            pw.println("\t\t\t\t\t\t\t<labelExpression>" + getCDATAString( cs.getLabelExpression() ,7 ) + "</labelExpression>");
        pw.println("\t\t\t\t\t\t</timePeriodSeries>");
    }
    
    private void writeTimeSeries(TimeSeries cs, PrintWriter pw)
    {
        pw.println("\t\t\t\t\t\t<timeSeries>");
        pw.println("\t\t\t\t\t\t\t<seriesExpression>" + getCDATAString( cs.getSeriesExpression() ,7 ) + "</seriesExpression>");
        pw.println("\t\t\t\t\t\t\t<timePeriodExpression>" + getCDATAString( cs.getTimePeriodExpression() ,7 ) + "</timePeriodExpression>");
        pw.println("\t\t\t\t\t\t\t<valueExpression>" + getCDATAString( cs.getValueExpression() ,7 ) + "</valueExpression>");
        if (cs.getLabelExpression().trim().length() != 0)
            pw.println("\t\t\t\t\t\t\t<labelExpression>" + getCDATAString( cs.getLabelExpression() ,7 ) + "</labelExpression>");
        pw.println("\t\t\t\t\t\t</timeSeries>");
    }
    
    
    
    private void writeDatasetDataset(Dataset dataset, PrintWriter pw)
    {
        pw.print("\t\t\t\t\t\t<dataset ");
        if (!dataset.getResetType().equals("Report")) pw.print("resetType=\"" + dataset.getResetType() +  "\" ");
        if (!dataset.getResetGroup().equals("")) pw.print("resetGroup=\"" + dataset.getResetGroup() + "\" ");
        if (!dataset.getIncrementType().equals("None")) pw.print("incrementType=\"" + dataset.getIncrementType() +  "\" ");
        if (!dataset.getIncrementGroup().equals("")) pw.print("incrementGroup=\"" + dataset.getIncrementGroup() + "\" ");
        pw.println(">");
        if ( CompatibilitySupport.version >= CompatibilitySupport.JR110 )
        {
            if (dataset.getSubDataset() != null)
            {
                pw.println("\t\t\t\t\t\t\t<datasetRun subDataset=\"" + dataset.getSubDataset().getName()  +"\">");
                if (dataset.getParametersMapExpression() != null &&
                    dataset.getParametersMapExpression().trim().length() > 0)
                {
                    pw.println("\t\t\t\t\t\t\t\t<parametersMapExpression>" + getCDATAString(dataset.getParametersMapExpression().trim(), 9 ) + "</parametersMapExpression>");
                }
                
                
                 Enumeration e = dataset.getSubreportParameters().elements();
                while (e.hasMoreElements()) {
                    JRSubreportParameter je = (JRSubreportParameter)e.nextElement();
                    pw.println("\t\t\t\t\t\t\t\t<datasetParameter  name=\""+ je.getName() +"\">");
                    pw.print("\t\t\t\t\t\t\t\t\t<datasetParameterExpression");
                     pw.println(">"+getCDATAString(je.getExpression(),9)+"</datasetParameterExpression>");
                    pw.println("\t\t\t\t\t\t\t\t</datasetParameter>");
                }
                 
                if (dataset.isUseConnection() && dataset.getConnectionExpression().trim().length() > 0 ) {
                    pw.print("\t\t\t\t\t\t\t\t<connectionExpression");
                    pw.println(">"+getCDATAString(dataset.getConnectionExpression(),8 )+ "</connectionExpression>");
                }
                else if (!dataset.isUseConnection()  && dataset.getDataSourceExpression().length() > 0) {
                    pw.print("\t\t\t\t\t<dataSourceExpression");
                    pw.println(">"+getCDATAString(dataset.getDataSourceExpression(),8 )+"</dataSourceExpression>");
                }
                
                pw.println("\t\t\t\t\t\t\t</datasetRun>");
            }
        }
        
        pw.println("\t\t\t\t\t\t</dataset>");
    }
    
    private void writePlot(ChartReportElement2 chartElement, PrintWriter pw)
    {
        if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.PiePlot)
        {
            it.businesslogic.ireport.chart.PiePlot plot = (it.businesslogic.ireport.chart.PiePlot)chartElement.getChart().getPlot();
            pw.println("\t\t\t\t\t<piePlot>");
            writePlotPlot( chartElement,  pw);
            pw.println("\t\t\t\t\t</piePlot>");
        }
        else if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.Pie3DPlot)
        {
            it.businesslogic.ireport.chart.Pie3DPlot plot = (it.businesslogic.ireport.chart.Pie3DPlot)chartElement.getChart().getPlot();
            pw.print("\t\t\t\t\t<pie3DPlot ");
            if (plot.getDepthFactor() != 0.2) pw.print("depthFactor=\"" + plot.getDepthFactor() +  "\" ");
            pw.println(">");
            writePlotPlot( chartElement,  pw);
            pw.println("\t\t\t\t\t</pie3DPlot>");
        }
        else if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.BarPlot)
        {
            it.businesslogic.ireport.chart.BarPlot plot = (it.businesslogic.ireport.chart.BarPlot)chartElement.getChart().getPlot();
            pw.print("\t\t\t\t\t<barPlot ");
            if (plot.isShowLabels()) pw.print("isShowLabels=\"" + plot.isShowLabels() +  "\" ");
            if (!plot.isShowTickMarks()) pw.print("isShowTickMarks=\"" + plot.isShowTickMarks() +  "\" ");
            if (!plot.isShowTickLabels()) pw.print("isShowTickLabels=\"" + plot.isShowTickLabels() +  "\" ");
            pw.println(">");
            
            writePlotPlot( chartElement,  pw);
            
            if (plot.getCategoryAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<categoryAxisLabelExpression>" + getCDATAString(plot.getCategoryAxisLabelExpression() ,6 ) + "</categoryAxisLabelExpression>");
            if (plot.getValueAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<valueAxisLabelExpression>" + getCDATAString(plot.getValueAxisLabelExpression() ,6 ) + "</valueAxisLabelExpression>");
            pw.println("\t\t\t\t\t</barPlot>");
        }
        else if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.Bar3DPlot)
        {
            it.businesslogic.ireport.chart.Bar3DPlot plot = (it.businesslogic.ireport.chart.Bar3DPlot)chartElement.getChart().getPlot();
            pw.print("\t\t\t\t\t<bar3DPlot ");
            if (plot.isShowLabels()) pw.print("isShowLabels=\"" + plot.isShowLabels() +  "\" ");
            if (plot.getXOffset() != org.jfree.chart.renderer.category.BarRenderer3D.DEFAULT_X_OFFSET) pw.print("xOffset=\"" + plot.getXOffset() +  "\" ");
            if (plot.getYOffset() != org.jfree.chart.renderer.category.BarRenderer3D.DEFAULT_Y_OFFSET) pw.print("yOffset=\"" + plot.getYOffset() +  "\" ");
            pw.println(">");
            
            writePlotPlot( chartElement,  pw);
            
            if (plot.getCategoryAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<categoryAxisLabelExpression>" + getCDATAString(plot.getCategoryAxisLabelExpression() ,6 ) + "</categoryAxisLabelExpression>");
            if (plot.getValueAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<valueAxisLabelExpression>" + getCDATAString(plot.getValueAxisLabelExpression() ,6 ) + "</valueAxisLabelExpression>");
            pw.println("\t\t\t\t\t</bar3DPlot>");
        }
        else if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.LinePlot)
        {
            it.businesslogic.ireport.chart.LinePlot plot = (it.businesslogic.ireport.chart.LinePlot)chartElement.getChart().getPlot();
            pw.print("\t\t\t\t\t<linePlot ");
            if (!plot.isShowLines()) pw.print("isShowLines=\"" + plot.isShowLines() +  "\" ");
            if (!plot.isShowShapes()) pw.print("isShowShapes=\"" + plot.isShowShapes() +  "\" ");
            pw.println(">");
            
            writePlotPlot( chartElement,  pw);
            
            if (plot.getCategoryAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<categoryAxisLabelExpression>" + getCDATAString(plot.getCategoryAxisLabelExpression() ,6 ) + "</categoryAxisLabelExpression>");
            if (plot.getValueAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<valueAxisLabelExpression>" + getCDATAString(plot.getValueAxisLabelExpression() ,6 ) + "</valueAxisLabelExpression>");
            pw.println("\t\t\t\t\t</linePlot>");
        }
        else if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.AreaPlot)
        {
            it.businesslogic.ireport.chart.AreaPlot plot = (it.businesslogic.ireport.chart.AreaPlot)chartElement.getChart().getPlot();
            pw.print("\t\t\t\t\t<areaPlot>");
            
            writePlotPlot( chartElement,  pw);
            
            if (plot.getCategoryAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<categoryAxisLabelExpression>" + getCDATAString(plot.getCategoryAxisLabelExpression() ,6 ) + "</categoryAxisLabelExpression>");
            if (plot.getValueAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<valueAxisLabelExpression>" + getCDATAString(plot.getValueAxisLabelExpression() ,6 ) + "</valueAxisLabelExpression>");
            pw.println("\t\t\t\t\t</areaPlot>");
        }
        else if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.ScatterPlot)
        {
            it.businesslogic.ireport.chart.ScatterPlot plot = (it.businesslogic.ireport.chart.ScatterPlot)chartElement.getChart().getPlot();
            pw.print("\t\t\t\t\t<scatterPlot ");
            if (!plot.isShowLines()) pw.print("isShowLines=\"" + plot.isShowLines() +  "\" ");
            if (!plot.isShowShapes()) pw.print("isShowShapes=\"" + plot.isShowShapes() +  "\" ");
            pw.println(">");
            
            writePlotPlot( chartElement,  pw);
            
            if (plot.getXAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<xAxisLabelExpression>" + getCDATAString(plot.getXAxisLabelExpression() ,6 ) + "</xAxisLabelExpression>");
            if (plot.getYAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<yAxisLabelExpression>" + getCDATAString(plot.getYAxisLabelExpression() ,6 ) + "</yAxisLabelExpression>");
            pw.println("\t\t\t\t\t</scatterPlot>");
        }
        else if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.BubblePlot)
        {
            it.businesslogic.ireport.chart.BubblePlot plot = (it.businesslogic.ireport.chart.BubblePlot)chartElement.getChart().getPlot();
            pw.print("\t\t\t\t\t<bubblePlot ");
            if (!plot.getScaleType().equals("RangeAxis") ) pw.print("scaleType=\"" + plot.getScaleType() +  "\" ");
            pw.println(">");
            
            writePlotPlot( chartElement,  pw);
            
            if (plot.getXAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<xAxisLabelExpression>" + getCDATAString(plot.getXAxisLabelExpression() ,6 ) + "</xAxisLabelExpression>");
            if (plot.getYAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<yAxisLabelExpression>" + getCDATAString(plot.getYAxisLabelExpression() ,6 ) + "</yAxisLabelExpression>");
            pw.println("\t\t\t\t\t</bubblePlot>");
        }
        else if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.TimeSeriesPlot)
        {
            it.businesslogic.ireport.chart.TimeSeriesPlot plot = (it.businesslogic.ireport.chart.TimeSeriesPlot)chartElement.getChart().getPlot();
            pw.print("\t\t\t\t\t<timeSeriesPlot ");
            if (!plot.isShowLines()) pw.print("isShowLines=\"" + plot.isShowLines() +  "\" ");
            if (!plot.isShowShapes()) pw.print("isShowShapes=\"" + plot.isShowShapes() +  "\" ");
            pw.println(">");
            
            writePlotPlot( chartElement,  pw);
            
            if (plot.getTimeAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<timeAxisLabelExpression>" + getCDATAString(plot.getTimeAxisLabelExpression() ,6 ) + "</timeAxisLabelExpression>");
            if (plot.getValueAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<valueAxisLabelExpression>" + getCDATAString(plot.getValueAxisLabelExpression() ,6 ) + "</valueAxisLabelExpression>");
            pw.println("\t\t\t\t\t</timeSeriesPlot>");
        }
        else if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.HighLowPlot)
        {
            it.businesslogic.ireport.chart.HighLowPlot plot = (it.businesslogic.ireport.chart.HighLowPlot)chartElement.getChart().getPlot();
            pw.print("\t\t\t\t\t<highLowPlot ");
            if (!plot.isShowCloseTicks()) pw.print("isShowCloseTicks=\"" + plot.isShowCloseTicks() +  "\" ");
            if (!plot.isShowOpenTicks()) pw.print("isShowOpenTicks=\"" + plot.isShowOpenTicks() +  "\" ");
            pw.println(">");
            
            writePlotPlot( chartElement,  pw);
            
            if (plot.getTimeAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<timeAxisLabelExpression>" + getCDATAString(plot.getTimeAxisLabelExpression() ,6 ) + "</timeAxisLabelExpression>");
            if (plot.getValueAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<valueAxisLabelExpression>" + getCDATAString(plot.getValueAxisLabelExpression() ,6 ) + "</valueAxisLabelExpression>");
            pw.println("\t\t\t\t\t</highLowPlot>");
        }
        else if (chartElement.getChart().getPlot() instanceof it.businesslogic.ireport.chart.CandlestickPlot)
        {
            it.businesslogic.ireport.chart.CandlestickPlot plot = (it.businesslogic.ireport.chart.CandlestickPlot)chartElement.getChart().getPlot();
            pw.print("\t\t\t\t\t<candlestickPlot ");
            if (!plot.isShowVolume()) pw.print("isShowVolume=\"" + plot.isShowVolume() +  "\" ");
            pw.println(">");
            
            writePlotPlot( chartElement,  pw);
            
            if (plot.getTimeAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<timeAxisLabelExpression>" + getCDATAString(plot.getTimeAxisLabelExpression() ,6 ) + "</timeAxisLabelExpression>");
            if (plot.getValueAxisLabelExpression().trim().length() != 0)
                pw.println("\t\t\t\t\t<valueAxisLabelExpression>" + getCDATAString(plot.getValueAxisLabelExpression() ,6 ) + "</valueAxisLabelExpression>");
            pw.println("\t\t\t\t\t</candlestickPlot>");
        }
    }
    
    private void writePlotPlot(ChartReportElement2 chartElement, PrintWriter pw)
    {
        pw.print("\t\t\t\t\t\t<plot ");
        if (chartElement.getChart().getPlot().getBackcolor() != null) pw.print("backcolor=\"" +  writeEncodedColor(chartElement.getChart().getPlot().getBackcolor() ) +  "\" ");
        if (!chartElement.getChart().getPlot().getOrientation().equals("Vertical")) pw.print("orientation=\"" + chartElement.getChart().getPlot().getOrientation() + "\" ");
        if (chartElement.getChart().getPlot().getBackgroundAlpha() != 1.0) pw.print("backgroundAlpha=\"" + chartElement.getChart().getPlot().getBackgroundAlpha() + "\" ");
        if (chartElement.getChart().getPlot().getBackgroundAlpha() != 1.0) pw.print("foregroundAlpha=\"" + chartElement.getChart().getPlot().getForegroundAlpha() + "\" ");
        pw.println("/>");
    }
    
    /**
     * Getter for property usingMultiLineExpressions.
     * @return Value of property usingMultiLineExpressions.
     */
    public boolean isUsingMultiLineExpressions() {
        return false; //usingMultiLineExpressions;
    }
    
    /**
     * Setter for property usingMultiLineExpressions.
     * @param usingMultiLineExpressions New value of property usingMultiLineExpressions.
     */
    public void setUsingMultiLineExpressions(boolean usingMultiLineExpressions) {
        this.usingMultiLineExpressions = false; //usingMultiLineExpressions;
    }
    
    
    
    /** Getter for property scripletCode.
     * @return Value of property scripletCode.
     *
     */
    public it.businesslogic.ireport.ScriptletCode getScripletCode() {
        return scripletCode;
    }
    
    /** Setter for property scripletCode.
     * @param scripletCode New value of property scripletCode.
     *
     */
    public void setScripletCode(it.businesslogic.ireport.ScriptletCode scripletCode) {
        this.scripletCode = scripletCode;
    }
    
    /** Getter for property scriptletHandling.
     * @return Value of property scriptletHandling.
     *
     */
    public int getScriptletHandling() {
        return scriptletHandling;
    }
    
    /** Setter for property scriptletHandling.
     * @param scriptletHandling New value of property scriptletHandling.
     *
     */
    public void setScriptletHandling(int scriptletHandling) {
        if (this.scriptletHandling == scriptletHandling) return;
        this.scriptletHandling = scriptletHandling;
        incrementReportChanges();
        
    }
    
    
    public String getScriptletFileName() {
        return this.getScriptletFileName( this.getFilename() );
    }
    
    public String getScriptletFileName(String file) {
        if (file == null) return "Scriptlet.java";
        
        // we assume /xxx/yyY/qqq/myreport.xml as input file name
        if (file.length() > 3) {
            file = Misc.changeFileExtension(file,  "");
            file = file.substring(0, file.length() -1 );
            File f = new File( file );
            String className = f.getName() + "Scriptlet";
            
            className = Misc.string_replace("_",".", className);
            className = Misc.string_replace("_"," ",className);
            if ( Character.isDigit(className.charAt( 0 )  )) {
                className = "_"+ className;
            }
            className += ".java";
            return  f.getPath().substring(0, f.getPath().length() - f.getName().length()) + className;
        }
        
        return "Scriptlet.java";
    }
    
    
    /**
     * Default font specified in xml file.
     * @return
     */
    public IReportFont getDefaultFont() {
        return defaultFont;
    }
    
    public boolean isReadOnly(){
        return readOnly;
    }
    public void checkReadOnlyFlag(){
        checkReadOnlyFlag(getFilename());
    }
    public void checkReadOnlyFlag(String oF){
        if (oF == null) return;
        File f = new File(oF);
        try {
        if (!f.exists()) {
            readOnly = false;
        } else {
            readOnly = !f.canWrite();
        }
        } catch (Exception ex) { }
        readOnly = false;
    }
    
    /**
     * return the band that encloses the parameter originY
     * @param originY
     * @return
     *
     * an originY < 0 will return nothing
     * an originY > designheight will return the Summary band
     */
    public Band getBandByPosition( int originY ){
        Band bname = null;
        for (Iterator i = this.getBands().iterator(); i.hasNext(); ) {
            Band b = (Band) i.next();
            if ( this.getBandYLocation(b) + 10 <= originY) {
                bname = b;
            }
        }
        if (bname != null && (this.getBandYLocation(bname) + 10 + bname.getHeight() < originY)) return null;
        return bname;
    }

    public Vector getImports() {
        return imports;
    }

    public void setImports(Vector imports) {
        this.imports = imports;
        incrementReportChanges();
    }

    public boolean isFloatColumnFooter() {
        return floatColumnFooter;
    }

    public void setFloatColumnFooter(boolean floatColumnFooter) {
        if (this.floatColumnFooter == floatColumnFooter) return;
        this.encoding = encoding;
        incrementReportChanges();
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        if ((this.language == null) ? language == null : this.language.equals(language)) return;
        this.language = language;
        incrementReportChanges();
    }

    public java.util.HashMap getProposedValues() {
        return proposedValues;
    }

    public void setProposedValues(java.util.HashMap proposedValues) {
        this.proposedValues = proposedValues;
    }
    
    /**
     * Recalculate the Columnwidth bases on the available space.
     * Introduces at June, 6 to allow PageTransformation.java to calculate the column width again.
     *
    */
    public void recalcColumnWidth() {

        //this.columns = (int)jNumberFieldColumns.getValue();
        // calculate space...
        //        this.setColumnCount( report.getColumnCount() );
        //        this.setColumnSpacing( report.getColumnSpacing());
        
        int avail = getWidth() - getLeftMargin() - getRightMargin() - (getColumnCount()-1) * getColumnSpacing();
        int dim = avail;
        dim = (int)( (double)dim / (double)this.getColumnCount());
        
        while ( (dim*this.getColumnCount()) > avail) {
            dim--;
        }
        this.setColumnWidth(dim);
    }
    
    public IReportFont getReportFontByName(String name)
    {
        if (name == null || name.length() == 0) return null;
        for (int i=0; i<getFonts().size(); ++i)
        {
                IReportFont font = (IReportFont)getFonts().elementAt(i);
                if (font.getReportFont().equals(name))
                {
                    return font;
                }
        }
        return null;
    }

    public Vector getStyles() {
        return styles;
    }

    public void setStyles(Vector styles) {
        this.styles = styles;
        incrementReportChanges();
    }
    
    public void elementGroupResort(Band band)
    {
        
        it.businesslogic.ireport.util.TreeNode root = extractBandElementsTree(band, true);
        addElementsTree( root );
        incrementReportChanges();        
    }
    
    public it.businesslogic.ireport.util.TreeNode extractBandElementsTree(Band band, boolean remove)
    {
        java.util.List tmpElements = new java.util.ArrayList();
        it.businesslogic.ireport.util.TreeNode root = new it.businesslogic.ireport.util.TreeNode("");
        for (int i=0; i< getElements().size(); ++i)
        {
            ReportElement element = (ReportElement)getElements().elementAt(i);
            if (element.getBand() == band)
            {
                tmpElements.add(element);
                if (remove)
                {
                    getElements().removeElementAt(i);
                    i--;
                }
            }
        }
        
        if (tmpElements.size() > 0)
        {
            // we have to reorder all....
            for (int i=0; i< tmpElements.size(); ++i)
            {
                ReportElement element = (ReportElement)tmpElements.get(i);
                String elementGroup = element.getElementGroup();
                try {
                        if (element.getParentElement() != null)
                        {
                            it.businesslogic.ireport.util.TreeNode tmpRoot = findElementInTreeNode(root,element.getParentElement());
                            if (tmpRoot != null) addElementToGroup(tmpRoot, elementGroup, element );
                        }
                        else
                        {
                            addElementToGroup(root, elementGroup, element );
                        }
                } catch (Exception ex)
                {
                      ex.printStackTrace();
                }
            }
        }
        
        return root;
    }
    
    
    public void moveElementDown(ReportElement element)
    {
        incrementReportChanges();
        it.businesslogic.ireport.util.TreeNode root = extractBandElementsTree(element.getBand(), true);
        root.moveDown( element );
        addElementsTree( root );
    }
    
    public void moveElementUp(ReportElement element)
    {
        incrementReportChanges();
        
         it.businesslogic.ireport.util.TreeNode root = extractBandElementsTree(element.getBand(), true);
        root.moveUp( element );
        addElementsTree( root );
        
    }
    
    private  void addElementsTree(it.businesslogic.ireport.util.TreeNode root)
    {
        for (int i=0; i< root.getChilds().size(); ++i)
        {
            it.businesslogic.ireport.util.TreeNode node =(it.businesslogic.ireport.util.TreeNode)(root.getChilds().get(i));
            Object obj = node.getUserObject();
            if (obj instanceof ReportElement)
            {
                getElements().add( obj );
                if (obj instanceof FrameReportElement)
                {
                    addElementsTree( node );
                }
            }
            else
            {
                addElementsTree( node );
            }            
        }
    }
    /*
    public void addElementToGroup(NamedList parentNode, String subGroup, ReportElement element)
    {
        // 1. We have to find the group node...
        if (subGroup.equals(""))
        {
            parentNode.add( element);
            return;
        }
        
        String levelGroupName = "";
        if (subGroup.indexOf(".")>=0)
        {
            levelGroupName = subGroup.substring(0, subGroup.indexOf("."));
            subGroup = subGroup.substring(subGroup.indexOf(".")+1);
        }
        else
        {
            levelGroupName = subGroup;
            subGroup = "";
        }
        
        // 2. Look for the node named levelGroupName
        for (int i =0; i<parentNode.size(); ++i)
        {
            Object node = parentNode.get(i);
            if (node instanceof NamedList)
            {
                NamedList nl = (NamedList)node;
                if (nl.getName().equals( levelGroupName ))
                {
                    addElementToGroup(nl, subGroup, element);
                    return;
                }
            }
        }
        
        // Node doesn't exists....
        NamedList nl = new NamedList(levelGroupName);
        addElementToGroup(nl, subGroup, element);
        parentNode.add( nl );        
    }
    */
    
    public void addElementToGroup(it.businesslogic.ireport.util.TreeNode parentNode, String subGroup, ReportElement element)
    {
        incrementReportChanges();
        // 1. We have to find the group node...
        if (subGroup.equals(""))
        {
            parentNode.addChild(new it.businesslogic.ireport.util.TreeNode( element ));
            return;
        }
        
        String levelGroupName = "";
        if (subGroup.indexOf(".")>=0)
        {
            levelGroupName = subGroup.substring(0, subGroup.indexOf("."));
            subGroup = subGroup.substring(subGroup.indexOf(".")+1);
        }
        else
        {
            levelGroupName = subGroup;
            subGroup = "";
        }
        
        // 2. Look for the node named levelGroupName
        for (int i =0; i<parentNode.getChilds().size(); ++i)
        {
            it.businesslogic.ireport.util.TreeNode node = (it.businesslogic.ireport.util.TreeNode)(parentNode.getChilds().get(i));
            if (node.getName().equals( levelGroupName ) )
            {
                 addElementToGroup(node, subGroup, element);
                 return;
            }
        }
        
        // Node doesn't exists....
        it.businesslogic.ireport.util.TreeNode nl = new it.businesslogic.ireport.util.TreeNode(levelGroupName);
        addElementToGroup(nl, subGroup, element);
        parentNode.addChild( nl );        
    }
    
     public it.businesslogic.ireport.util.TreeNode findElementInTreeNode(it.businesslogic.ireport.util.TreeNode parentNode, ReportElement re)
    {
        for (int k=0; k<parentNode.getChilds().size(); ++k) {
            it.businesslogic.ireport.util.TreeNode child = (it.businesslogic.ireport.util.TreeNode)(parentNode.getChilds().get(k));
            if (child.getUserObject() == re) {
                return child;
            }
            if (re.getElementGroup().equals("") || re.getParentElement() != null)
            {
                if (child.getUserObject() instanceof FrameReportElement ||
                    child.getUserObject() instanceof String)
                {
                    it.businesslogic.ireport.util.TreeNode newchild = findElementInTreeNode(child,re);
                    if (newchild != null) return newchild;
                }
            }
        }
        return null;
    }

    public Vector getSubDatasets() {
        return subDatasets;
    }

    public void setSubDatasets(Vector subDatasets) {
        this.subDatasets = subDatasets;
        incrementReportChanges();
    }

    public boolean isIgnorePagination() {
        return ignorePagination;
    }

    public void setIgnorePagination(boolean ignorePagination) {
        if (this.ignorePagination == ignorePagination) return;
        this.ignorePagination = ignorePagination;
        incrementReportChanges();
    }

    /**
     * Utility field used by event firing mechanism.
     */
    private javax.swing.event.EventListenerList listenerList =  null;

   
    public void addSubDataset(SubDataset subDataset) {
        this.getSubDatasets().add( subDataset);
        incrementReportChanges();
        this.fireReportSubDatasetChangedListenerReportSubDatasetChanged( new ReportSubDatasetChangedEvent(this, subDataset, ReportSubDatasetChangedEvent.ADDED, ReportSubDatasetChangedEvent.OBJECT_SUBDATASET));
        subDataset.addSubDatasetObjectChangedListener( this );
    }

    public void removeSubDataset(SubDataset subDataset) {
        this.getSubDatasets().remove(subDataset);
        this.fireReportSubDatasetChangedListenerReportSubDatasetChanged( new ReportSubDatasetChangedEvent(this,subDataset, ReportSubDatasetChangedEvent.REMOVED, ReportSubDatasetChangedEvent.OBJECT_SUBDATASET));
        subDataset.removeSubDatasetObjectChangedListener( this );
        incrementReportChanges();
    }
    
    public void removeStyle(Style s) {
        
        this.getStyles().remove(s);
        removeStyleFromElements( s,  getElements());
        this.fireStyleChangedListenerStyleChanged( new StyleChangedEvent( this,StyleChangedEvent.DELETED , s,s));
        incrementReportChanges();
    }
    
    public void addStyle(Style s)
    {
        this.getStyles().add(s);
        incrementReportChanges();
        this.fireStyleChangedListenerStyleChanged( new StyleChangedEvent( this,StyleChangedEvent.ADDED , s,s));
    }
    
    private void removeStyleFromElements(Style s, Vector thisElements)
    {
        for (int i=0; i<thisElements.size(); ++i)
        {
            ReportElement re = (ReportElement)thisElements.elementAt(i);
        
            if (re.getStyle() == s) re.setStyle(null);
            
            if (re instanceof CrosstabReportElement)
            {
                removeStyleFromElements(s, ((CrosstabReportElement)re).getElements());
            }
        }
        incrementReportChanges();
    }

    /**
     * Registers ReportSubDatasetChangedListener to receive events.
     * @param listener The listener to register.
     */
    public synchronized void addReportSubDatasetChangedListener(it.businesslogic.ireport.gui.event.ReportSubDatasetChangedListener listener) {
        if (listenerList == null ) {
            listenerList = new javax.swing.event.EventListenerList();
        }
        listenerList.add (it.businesslogic.ireport.gui.event.ReportSubDatasetChangedListener.class, listener);
    }

    /**
     * Removes ReportSubDatasetChangedListener from the list of listeners.
     * @param listener The listener to remove.
     */
    public synchronized void removeReportSubDatasetChangedListener(it.businesslogic.ireport.gui.event.ReportSubDatasetChangedListener listener) {
        listenerList.remove (it.businesslogic.ireport.gui.event.ReportSubDatasetChangedListener.class, listener);
    }

    /**
     * Notifies all registered listeners about the event.
     * 
     * @param event The event to be fired
     */
    public void fireReportSubDatasetChangedListenerReportSubDatasetChanged(it.businesslogic.ireport.gui.event.ReportSubDatasetChangedEvent event) {
        if (listenerList == null) return;
        Object[] listeners = listenerList.getListenerList ();
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i]==it.businesslogic.ireport.gui.event.ReportSubDatasetChangedListener.class) {
                ((it.businesslogic.ireport.gui.event.ReportSubDatasetChangedListener)listeners[i+1]).reportSubDatasetChanged (event);
            }
        }
    }

    public void subDatasetObjectChanged(it.businesslogic.ireport.gui.event.SubDatasetObjectChangedEvent evt) {
        

        //System.out.println(evt.getSource() + "   " + this);
        //fireSubDatasetObjectChangedListenerSubDatasetObjectChanged( evt );
        if (getListenerList() != null && evt.getSource() != this)
        {
            Object[] listeners = getListenerList().getListenerList ();
             for (int i = listeners.length - 2; i >= 0; i -= 2) {
                if (listeners[i+1] == this) continue;
                //if (listeners[i+1] == evt.getSource()) continue;
                if (listeners[i]==it.businesslogic.ireport.gui.event.SubDatasetObjectChangedListener.class) {
                ((it.businesslogic.ireport.gui.event.SubDatasetObjectChangedListener)listeners[i+1]).subDatasetObjectChanged (evt);
                }
             }
        }

        incrementReportChanges();
    }

    /**
     * Registers StyleChangedListener to receive events.
     * @param listener The listener to register.
     */
    public synchronized void addStyleChangedListener(it.businesslogic.ireport.gui.event.StyleChangedListener listener) {
        if (listenerList == null ) {
            listenerList = new javax.swing.event.EventListenerList();
        }
        listenerList.add (it.businesslogic.ireport.gui.event.StyleChangedListener.class, listener);
    }

    /**
     * Removes StyleChangedListener from the list of listeners.
     * @param listener The listener to remove.
     */
    public synchronized void removeStyleChangedListener(it.businesslogic.ireport.gui.event.StyleChangedListener listener) {
        listenerList.remove (it.businesslogic.ireport.gui.event.StyleChangedListener.class, listener);
    }

    /**
     * Notifies all registered listeners about the event.
     * 
     * @param event The event to be fired
     */
    public void fireStyleChangedListenerStyleChanged(it.businesslogic.ireport.gui.event.StyleChangedEvent event) {
        
        // We have to apply again the style...
        Enumeration enum_elements = getElements().elements();
        while (enum_elements.hasMoreElements())
        {
            ReportElement re = (ReportElement)enum_elements.nextElement();
            if (re.getStyle() == event.getNewValue())
            {
                re.setStyle( event.getNewValue());
            }
        }
        
        if (listenerList == null) return;
        Object[] listeners = listenerList.getListenerList ();
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i]==it.businesslogic.ireport.gui.event.StyleChangedListener.class) {
                ((it.businesslogic.ireport.gui.event.StyleChangedListener)listeners[i+1]).styleChanged (event);
            }
        }
    }
    
    public Style getDefaultStyle()
    {
        for (int i=0; i<getStyles().size(); ++i)
        {
         Style s = (Style)getStyles().elementAt(i);
         if (s.getAttributeBoolean( s.ATTRIBUTE_isDefault, false ))
         {
             return s;
         }
        }
        return null;
    }
    
    
            
    public int getReportChanges() {
        return reportChanges;
    }

    /* 
     *  Keep track of report changes. A ReportDocumentStatusChanged
     *  event is thrown in the following cases:
     *  
     *   currentChanges == 0 && newChanges > 0  => ReportDocumentStatusChanged to DIRTY
     *   currentChanges > 0 && newChanges == 0  => ReportDocumentStatusChanged to NO_DIRTY
     *
     */
    public void setReportChanges(int newChanges) {
        
        boolean fireEvent = false;
        
        if (reportChanges == 0 && newChanges > 0) fireEvent = true;
        else if (reportChanges > 0 && newChanges == 0) fireEvent = true;
        
        this.reportChanges = newChanges;
        
        if (fireEvent)
        {
            fireReportDocumentStatusChangedListenerReportDocumentStatusChanged( 
                new ReportDocumentStatusChangedEvent(this));
        }
    }
    
    public void incrementReportChanges() {
        setReportChanges( getReportChanges() + 1);
    }
    
    public void decrementReportChanges() {
        if (getReportChanges() > 0)
        {
            setReportChanges( getReportChanges() - 1);
        }
    }
    
    /**
     * Alias for getReportChanges() > 0
     */
    public boolean isModified()
    {
        return getReportChanges() > 0;
    }
    
    public boolean isLoadingFile() {
        return loadingFile;
    }

    public void setLoadingFile(boolean loading) {
        this.loadingFile = loading;
    }

    /**
     * Registers ReportDocumentStatusChangedListener to receive events.
     * @param listener The listener to register.
     */
    public synchronized void addReportDocumentStatusChangedListener(it.businesslogic.ireport.gui.event.ReportDocumentStatusChangedListener listener) {

        if (listenerList == null ) {
            listenerList = new javax.swing.event.EventListenerList();
        }
        listenerList.add (it.businesslogic.ireport.gui.event.ReportDocumentStatusChangedListener.class, listener);
    }

    /**
     * Removes ReportDocumentStatusChangedListener from the list of listeners.
     * @param listener The listener to remove.
     */
    public synchronized void removeReportDocumentStatusChangedListener(it.businesslogic.ireport.gui.event.ReportDocumentStatusChangedListener listener) {

        listenerList.remove (it.businesslogic.ireport.gui.event.ReportDocumentStatusChangedListener.class, listener);
    }

    /**
     * Notifies all registered listeners about the event.
     * 
     * @param event The event to be fired
     */
    private void fireReportDocumentStatusChangedListenerReportDocumentStatusChanged(it.businesslogic.ireport.gui.event.ReportDocumentStatusChangedEvent event) {

        if (listenerList == null) return;
        Object[] listeners = listenerList.getListenerList ();
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i]==it.businesslogic.ireport.gui.event.ReportDocumentStatusChangedListener.class) {
                ((it.businesslogic.ireport.gui.event.ReportDocumentStatusChangedListener)listeners[i+1]).reportDocumentStatusChanged (event);
            }
        }
    }
    
    
}
