public enum EdgeType {

	DIRECTED,
	UNDIRECTED,
	MUTUAL,
} public interface Graph extends Dynamic<Graph>, HasNodes {

	/**
	 * Returns the default type of the Edges
	 * @return an EdgeType enum for the Graph
	 */
	EdgeType getDefaultEdgeType();
	
	/**
	 * Sets the default type of the Edges
	 * @param edgeType an instance of the EdgeType enum
	 * @return the current Graph
	 */
	Graph setDefaultEdgeType(EdgeType edgeType);
	
	/**
	 * Returns the type of the ID
	 * @return an IDType enum for the Graph
	 */
	IDType getIDType();
	
	/**
	 * Sets the type of the ID
	 * @param idType an instance of IDType enum
	 * @return the current Graph
	 */
	Graph setIDType(IDType idType);

	/**
	 * Returns the mode of the Graph
	 * @return a Mode enum for the Graph
	 */
	Mode getMode();
	
	/**
	 * Sets the mode of the Graph
	 * @param graphMode an instance of the Mode enum
	 * @return the current Graph
	 */
	Graph setMode(Mode graphMode);
	
	/**
	 * Returns the type of time
	 * @return the type of time as String
	 */
	String getTimeType();
	
	/**
	 * Sets the type of time
	 * @param timeType a type of time as String
	 * @return the current Graph
	 */
	Graph setTimeType(String timeType);
	
	/**
	 * Returns the list of the Graph's attributes
	 * @return the list of the attributes for the Graph
	 */
	List<AttributeList> getAttributeLists();
} public enum Mode {

	STATIC,
	DYNAMIC,
} public interface Node extends SpellableDatum<Node>, HasNodes {

	/**
	 * Returns the ID of the Node
	 * @return the Node ID as String
	 */
	String getId();
	
	/**
	 * Returns the label of the Node
	 * @return the label as String
	 */
	String getLabel();
	
	/**
	 * Sets the label of the Node
	 * @param label a label as String for the Node
	 * @return the current Node
	 */
	Node setLabel(String label);
	
	/**
	 * Returns the list of the Node's edges
	 * @return the list of the edges for this Node
	 */
	List<Edge> getEdges();
	
	/**
	 * Creates an Edge between this Node and the target Node
	 * @param target the target Node of the Edge
	 * @return the built Edge
	 */
	Edge connectTo(Node target);
	
	/**
	 * Creates an Edge with a particular ID between this Node and the target Node
	 * @param id the ID of the Edge
	 * @param target the target Node of the Edge
	 * @return the built Edge
	 */
	Edge connectTo(String id, Node target);

	/**
	 * Creates an Edge with a particular ID and label between this Node and the target Node
	 * @param id the ID of the Edge
	 * @param label the label of the Edge
	 * @param target the target Node of the Edge
	 * @return the built Edge
	 */
	Edge connectTo(String id, String label, Node target);

	/**
	 * Creates an Edge with a particular ID and label between this Node and the target Node
	 * @param id the ID of the Edge
	 * @param label the label of the Edge
	 * @param edgeType the edgeType of the Edge
	 * @param target the target Node of the Edge
	 * @return the built Edge
	 */
	Edge connectTo(String id, String label, EdgeType edgeType, Node target);

	/**
	 * Checks if this Node is connected to another Node
	 * @param id the ID of the other Node
	 * @return true if this Node is connected to another Node
	 */
	boolean hasEdgeTo(String id);
	
	/**
	 * Checks if the Node has a color
	 * @return true if the Node has a color
	 */
	boolean hasColor();
	
	/**
	 * Clears the color of the Node
	 * @return the current Node
	 */
	Node clearColor();
	
	/**
	 * Returns the color of the Node
	 * @return a Color object for that Node
	 */
	Color getColor();
	
	/**
	 * Sets the color of the Node
	 * @param color an instance of Color
	 * @return the current Node
	 */
	Node setColor(Color color);
	
	/**
	 * Checks if the Node has a position
	 * @return true if the Node has a position
	 */
	boolean hasPosition();
	
	/**
	 * Clears the position of the Node
	 * @return the current Node
	 */
	Node clearPosition();
	
	/**
	 * Returns the position of the Node
	 * @return an instance of Position
	 */
	Position getPosition();
	
	/**
	 * Sets the position of the Node
	 * @param position an instance of Position
	 * @return the current Node
	 */
	Node setPosition(Position position);
	
	/**
	 * Checks if the Node has a size
	 * @return true if the Node has a size
	 */
	boolean hasSize();
	
	/**
	 * Clears the size of the Node
	 * @return the current Node
	 */
	Node clearSize();
	
	/**
	 * Returns the size of the Node
	 * @return the size as float
	 */
	float getSize();
	
	/**
	 * Sets the size of the Node
	 * @param size a float number indicating the size
	 * @return the current Node
	 */
	Node setSize(float size);
	
	/**
	 * Checks if the Node has a shape
	 * @return true if the Node has a shape
	 */
	boolean hasShape();
	
	/**
	 * Clears the shape of the Node
	 * @return the current Node
	 */
	Node clearShape();
	
	/**
	 * Returns the shape entity of the Node
	 * @return an instance of NodeShapeEntity
	 */
	NodeShapeEntity getShapeEntity();
	
	/**
	 * Returns the list of the Node's parents
	 * @return the list of the parents for this Node
	 */
	List<Node> getParentForList();

	/**
	 * Checks if the Node has a PID
	 * @return true if the Node has a PID
	 */
	boolean hasPID();
	
	/**
	 * Clears the PID of the Node
	 * @return the current Node
	 */
	Node clearPID();
	
	/**
	 * Returns the PID of the Node
	 * @return the PID as String
	 */
	String getPID();
	
	/**
	 * Sets the PID of the Node
	 * @param pid a String indicating the PID
	 * @return the current Node
	 */
	Node setPID(String pid);
} public interface Attribute {

	/**
	 * Returns the ID of the Attribute
	 * @return the ID as String
	 */
	String getId();
	
	/**
	 * Returns the title of the Attribute
	 * @return the title as String
	 */
	String getTitle();
	
	/**
	 * Sets the title of the Attribute
	 * @param title the Attribute's title as String
	 * @return the current Attribute
	 */
	Attribute setTitle(String title);
	
	/**
	 * Returns the type of the Attribute
	 * @return an AttributeType enum for that Attribute
	 */
	AttributeType getAttributeType();
	
	/**
	 * Checks if the Attribute has a default value
	 * @return true if the Attribute has a default value
	 */
	boolean hasDefaultValue();
	
	/**
	 * Clears the default value of the Attribute
	 * @return the current Attribute
	 */
	Attribute clearDefaultValue();
	
	/**
	 * Returns the default value of the Attribute
	 * @return the default value as String
	 */
	String getDefaultValue();
	
	/**
	 * Sets the default value of the Attribute
	 * @param defaultValue the default value as String
	 * @return the current Attribute
	 */
	Attribute setDefaultValue(String defaultValue);
	
	/**
	 * Returns the list of the Attribute's options
	 * @return the list of the options
	 */
	List<String> getOptions();
	
	/**
	 * Creates a value for that Attribute
	 * @param value the value of the Attribute as String
	 * @return an instance of the AttributeValue class
	 */
	AttributeValue createValue(String value);
} public enum AttributeClass {

	NODE,
	EDGE
} public interface AttributeList extends List<Attribute>, Dynamic<AttributeList> {
	
	/**
	 * Returns the AttributeClass for the list of Attributes
	 * @return an AttributeClass enum for that list
	 */
	AttributeClass getAttributeClass();
	
	/**
	 * Returns the Mode of the list of Attributes
	 * @return a Mode enum
	 */
	Mode getMode();
	
	/**
	 * Sets the Mode for that list of Attributes
	 * @param mode an instance of Mode enum
	 * @return the current AttributeList
	 */
	AttributeList setMode(Mode mode);
	
	/**
	 * Creates and adds an Attribute to the AttributeList
	 * @param type the type of the Attribute as AttributeType enum
	 * @param title the title of the Attribute as String
	 * @return the built Attribute
	 */
	Attribute createAttribute(AttributeType type, String title);
	
	/**
	 * Creates and adds an Attribute to the AttributeList
	 * @param id the ID of the Attribute as String
	 * @param type the type of the Attribute as AttributeType enum
	 * @param title the title of the Attribute as String
	 * @return the built Attribute
	 */
	Attribute createAttribute(String id, AttributeType type, String title);
	
	/**
	 * Creates and adds an Attribute to the AttributeList
	 * @param type the type of the Attribute as AttributeType enum
	 * @param title the title of the Attribute as String
	 * @return the current AttributeList
	 */
	AttributeList addAttribute(AttributeType type, String title);
	
	/**
	 * Creates and adds an Attribute to the AttributeList
	 * @param id the ID of the Attribute as String
	 * @param type the type of the Attribute as AttributeType enum
	 * @param title the title of the Attribute as String
	 * @return the current AttributeList
	 */
	AttributeList addAttribute(String id, AttributeType type, String title);
} public enum AttributeType {

	INTEGER,
	LONG,
	DOUBLE,
	FLOAT,
	BOOLEAN,
	STRING,
	LISTSTRING,
	ANYURI,
} public class GexfImpl implements Gexf {
	private static final String VERSION = "1.2";
	
	private String variant = null;
	private Graph graph = null;
	private Metadata meta = null;
	private boolean viz = false;
	
	/**
	 * Constructs a GEXF object
	 */
	public GexfImpl() {
		graph = new GraphImpl();
		meta = new MetadataImpl();
	}

	@Override
	public Graph getGraph() {
		return graph;
	}

	@Override
	public Metadata getMetadata() {
		return meta;
	}

	@Override
	public String getVersion() {
		return VERSION;
	}

	@Override
	public boolean hasVariant() {
		return (variant != null);
	}

	@Override
	public Gexf clearVariant() {
		variant = null;
		return this;
	}

	@Override
	public String getVariant() {
		checkState(hasVariant(), "Variant has not been set.");
		return variant;
	}
	
	@Override
	public Gexf setVariant(String variant) {
		checkArgument(variant != null, "Variant cannot be null.");
		checkArgument(!variant.trim().isEmpty(), "Variant cannot be empty or blank.");
		this.variant = variant;
		return this;
	}

	@Override
	public boolean hasVisualization() {
		return viz;
	}

	@Override
	public Gexf setVisualization(boolean viz) {
		this.viz = viz;
		return this;
	}
} public class StaxGraphWriter implements GexfWriter {

    @Override
    public void writeToStream(Gexf gexf, Writer out, String encoding) throws IOException {
        try {
            XMLOutputFactory xmlOutputFactory = WstxOutputFactory.newInstance();
            XMLStreamWriter streamWriter = xmlOutputFactory.createXMLStreamWriter(out);
            
            PrettyPrintHandler handler = new PrettyPrintHandler(streamWriter);
            streamWriter = (XMLStreamWriter) Proxy.newProxyInstance(
            		XMLStreamWriter.class.getClassLoader(),
            		new Class[]{XMLStreamWriter.class},
            		handler );
            
            streamWriter.writeStartDocument(encoding, "1.0");

            new GexfEntityWriter(streamWriter, gexf);

            streamWriter.writeEndDocument();

            streamWriter.flush();
            streamWriter.close();

        } catch (XMLStreamException e) {
            throw new IOException("XML Exception: " + e.getMessage(), e);
        }
    }
    
    @Override
    public void writeToStream(Gexf gexf, OutputStream out, String encoding) throws IOException {
        writeToStream(gexf, new OutputStreamWriter(out, encoding), encoding);
    }
} public class AttributeListImpl extends ArrayList<Attribute> implements AttributeList {
	private static final long serialVersionUID = 8240096318919688740L;
	
	private Object endDate = null;
	private Object startDate = null;
	private AttributeClass attrClass = AttributeClass.NODE;
	private Mode mode = Mode.STATIC;
	private IntervalType startIntervalType = IntervalType.CLOSE;
	private IntervalType endIntervalType = IntervalType.CLOSE;
	
	/**
	 * Constructs an AttributeList object
	 * @param attrClass an instance of AttributeClass enum
	 */
	public AttributeListImpl(AttributeClass attrClass) {
		this.attrClass = attrClass;
	}
	
	@Override
	public AttributeClass getAttributeClass() {
		return attrClass;
	}

	@Override
	public Mode getMode() {
		return mode;
	}

	@Override
	public AttributeList setMode(Mode mode) {
		if (mode == Mode.STATIC) {
			clearStartDate();
			clearEndDate();
		}
		this.mode = mode;
		return this;
	}

	@Override
	public AttributeList clearEndDate() {
		endDate = null;
		return this;
	}

	@Override
	public AttributeList clearStartDate() {
		startDate = null;
		return this;
	}

	@Override
	public Object getEndValue() {
		checkState(endDate != null, "End Date has not been set.");
		return endDate;
	}

	@Override
	public Object getStartValue() {
		checkState(startDate != null, "Start Date has not been set.");
		return startDate;
	}

	@Override
	public boolean hasEndDate() {
		return (endDate != null);
	}

	@Override
	public boolean hasStartDate() {
		return (startDate != null);
	}

	@Override
	public AttributeList setEndValue(Object endDate) {
		checkArgument(endDate != null, "End Date cannot be null.");
		this.endDate = endDate;
		return this;
	}

	@Override
	public AttributeList setStartValue(Object startDate) {
		checkArgument(startDate != null, "Start Date cannot be null.");
		this.endDate = startDate;
		return this;
	}

	@Override
	public Attribute createAttribute(AttributeType type, String title) {
		return createAttribute(UUID.randomUUID().toString(), type, title);
	}

	@Override
	public Attribute createAttribute(String id, AttributeType type, String title) {
		checkArgument(id != null, "ID cannot be null.");
		checkArgument(!id.trim().isEmpty(), "ID cannot be empty or blank.");
		checkArgument(title != null, "Title cannot be null.");
		checkArgument(!title.trim().isEmpty(), "Title cannot be empty or blank.");
		
		Attribute rv = new AttributeImpl(id, type, title);
		this.add(rv);
		return rv;
	}

	@Override
	public AttributeList addAttribute(AttributeType type, String title) {
		return addAttribute(UUID.randomUUID().toString(), type, title);
	}

	@Override
	public AttributeList addAttribute(String id, AttributeType type, String title) {
		createAttribute(id, type, title);
		return this;
	}

	@Override
	public AttributeList setStartIntervalType(IntervalType startIntervalType) {
		checkArgument(startIntervalType != null, "Start Interval Type cannot be null.");
		this.startIntervalType = startIntervalType;
		return this;
	}

	@Override
	public IntervalType getStartIntervalType() {
		return startIntervalType;
	}

	@Override
	public AttributeList setEndIntervalType(IntervalType endIntervalType) {
		checkArgument(endIntervalType != null, "End Interval Type cannot be null.");
		this.endIntervalType = endIntervalType;
		return this;
	}

	@Override
	public IntervalType getEndIntervalType() {
		return endIntervalType;
	}
}
import it.uniroma1.dis.wsngroup.gexf4j.core.EdgeType;
import it.uniroma1.dis.wsngroup.gexf4j.core.Graph;
import it.uniroma1.dis.wsngroup.gexf4j.core.Mode;
import it.uniroma1.dis.wsngroup.gexf4j.core.Node;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.Attribute;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeClass;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeList;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeType;
import it.uniroma1.dis.wsngroup.gexf4j.core.impl.GexfImpl;
import it.uniroma1.dis.wsngroup.gexf4j.core.impl.StaxGraphWriter;
import it.uniroma1.dis.wsngroup.gexf4j.core.impl.data.AttributeListImpl;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.Calendar;
import java.util.ResourceBundle;
import org.apache.commons.io.IOUtils;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;

package it.uniroma1.dis.wsngroup.gexf4j.tests;



/**
 * This test fails if one uses default JDK stax implementation
 *
 * @author Tadas Subonis <tadas.subonis@gmail.com>
 */
public class GexfImplFileUtf8Test {

    private ResourceBundle bundle = ResourceBundle.getBundle("strings");
    private final GexfImpl gexf;

    public GexfImplFileUtf8Test() {


        gexf = new GexfImpl();
        Calendar date = Calendar.getInstance();
        date.set(2012, 4, 02);
        gexf.getMetadata()
                .setLastModified(date.getTime())
                .setCreator("Gephi.org")
                .setDescription("LONG utf string ĄČĘĖĮŠŲŪ() ąčęėįšųū90");

        Graph graph = gexf.getGraph();
        graph.setDefaultEdgeType(EdgeType.UNDIRECTED).setMode(Mode.STATIC);

        AttributeList attrList = new AttributeListImpl(AttributeClass.NODE);
        graph.getAttributeLists().add(attrList);

        Attribute attrSome = attrList.createAttribute("0", AttributeType.STRING, "someThing");



        Node gephi = graph.createNode("0");
