commit af223c76a16cf01541b12817163b1305f7498614
Author: Tomáš Šimandl <tomas.simandl@gmail.com>
Date:   Tue Feb 5 10:40:52 2019 +0100

    Added template for creating of plugins

diff --git a/plugins/_template/pom.xml b/plugins/_template/pom.xml
new file mode 100644
index 0000000..a5694a5
--- /dev/null
+++ b/plugins/_template/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.example.plugin</groupId>
+    <artifactId>imiger-plugin-template</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+                    </archive>
+                    <descriptorRefs>
+                        <descriptorRef>jar-with-dependencies</descriptorRef>
+                    </descriptorRefs>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id> <!-- this is used for inheritance merges -->
+                        <phase>package</phase> <!-- bind to the packaging phase -->
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <!-- Lib for JSON handling -->
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.5</version>
+        </dependency>
+
+        <!-- Lib for loading file -->
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.6</version>
+        </dependency>
+
+        <!-- Libs for Logging -->
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+            <version>2.11.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <version>2.11.1</version>
+        </dependency>
+
+        <!-- Libs for Unit testing -->
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>5.3.2</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+
+</project>
\ No newline at end of file
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/Converter.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/Converter.java
new file mode 100644
index 0000000..8f828bb
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/Converter.java
@@ -0,0 +1,16 @@
+package cz.zcu.kiv.imiger.plugin.spade;
+
+import com.google.gson.Gson;
+import cz.zcu.kiv.imiger.plugin.spade.api.Graph;
+
+public class Converter {
+
+    /**
+     * Convert input file to RAW JSON and return it.
+     */
+    public String getRawJson(String inputFile) {
+
+        Graph graph = new Graph();
+        return new Gson().toJson(graph);
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/AttributeDataType.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/AttributeDataType.java
new file mode 100644
index 0000000..7686787
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/AttributeDataType.java
@@ -0,0 +1,37 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+public enum AttributeDataType {
+    NUMBER {
+        @Override
+        public String toString() {
+            return "number";
+        }
+    },
+    DATE {
+        @Override
+        public String toString() {
+            return "date";
+        }
+    },
+    ENUM {
+        @Override
+        public String toString() {
+            return "enum";
+        }
+    },
+    STRING {
+        @Override
+        public String toString() {
+            return "string";
+        }
+    };
+
+    public static AttributeDataType getEnum(String value){
+        switch (value) {
+            case "number": return AttributeDataType.NUMBER;
+            case "date": return AttributeDataType.DATE;
+            case "enum": return AttributeDataType.ENUM;
+            default: return AttributeDataType.STRING;
+        }
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/AttributeType.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/AttributeType.java
new file mode 100644
index 0000000..9771d07
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/AttributeType.java
@@ -0,0 +1,32 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+/**
+ * Class represents one attribute type which is used in input JSON file and in output JSON file (file between frontend
+ * and backend).
+ */
+public class AttributeType {
+    /** name of attribute */
+    public String name;
+    /** data type of attribute */
+    public AttributeDataType dataType;
+    /** additional info */
+    public String text;
+
+    public AttributeType(String name, AttributeDataType dataType, String text) {
+        this.name = name;
+        this.dataType = dataType;
+        this.text = text;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public AttributeDataType getDataType() {
+        return dataType;
+    }
+
+    public String getText() {
+        return text;
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/BaseEdge.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/BaseEdge.java
new file mode 100644
index 0000000..c6b8769
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/BaseEdge.java
@@ -0,0 +1,78 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+/**
+ * Class represents edge. Class contains attributes which are common for input JSON format and for
+ * output JSON format (JSON between frontend and backend)
+ */
+public class BaseEdge {
+    /** identification number of edge */
+    private int id;
+    /** original ID of vertex from edge leads */
+    private int from;
+    /** original ID of vertex where edge leads */
+    private int to;
+    /** additional info */
+    private String text;
+
+    public BaseEdge(int id, int from, int to, String text) {
+        this.id = id;
+        this.from = from;
+        this.to = to;
+        this.text = text;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getFrom() {
+        return from;
+    }
+
+    public void setFrom(int from) {
+        this.from = from;
+    }
+
+    public int getTo() {
+        return to;
+    }
+
+    public void setTo(int to) {
+        this.to = to;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    /**
+     * Generate hash code based on attributes {@code from} and {@code to}.
+     * @return generated hash code.
+     */
+    @Override
+    public int hashCode() {
+        return from * 100000 + to;
+    }
+
+    /**
+     * Two edges are equals where their {@code from} and {@code to} are equals.
+     *
+     * @param edge which will be compared with this instance
+     * @return tru if edges are equal, false otherwise
+     */
+    @Override
+    public boolean equals(Object edge) {
+        if (!(edge instanceof BaseEdge)) return false;
+
+        BaseEdge cmpEdge = (BaseEdge) edge;
+        return from == cmpEdge.from && to == cmpEdge.to;
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/BaseVertex.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/BaseVertex.java
new file mode 100644
index 0000000..db7e3f0
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/BaseVertex.java
@@ -0,0 +1,76 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+/**
+ * Class represents vertex. Class contains attributes which are common for input JSON format and for
+ * output JSON format (JSON between frontend and backend)
+ */
+public class BaseVertex {
+
+    /** New generated identification number. */
+    private int id;
+    /** Name of vertex. */
+    private String name;
+    /** Index of vertex archetype. */
+    private int archetypeIndex;
+    /** Additional info. */
+    private String text;
+
+    public BaseVertex(int id, String name, int archetypeIndex, String text) {
+        this.id = id;
+        this.name = name;
+        this.archetypeIndex = archetypeIndex;
+        this.text = text;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getArchetype() {
+        return archetypeIndex;
+    }
+
+    public void setArchetype(int archetypeIndex) {
+        this.archetypeIndex = archetypeIndex;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    /**
+     * Generate hash code which is based on {@code originalId}.
+     * @return generated has code
+     */
+    @Override
+    public int hashCode() {
+        return id;
+    }
+
+    /**
+     * Two vertices are equals when their {@code originalId} is equals.
+     * @param vertex which will be compared with this instance
+     * @return true if vertices are equal, false otherwise
+     */
+    @Override
+    public boolean equals(Object vertex) {
+        if (!(vertex instanceof BaseVertex)) return false;
+        return id == ((BaseVertex) vertex).id;
+    }
+}
\ No newline at end of file
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Edge.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Edge.java
new file mode 100644
index 0000000..60e1872
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Edge.java
@@ -0,0 +1,36 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+import java.util.List;
+
+/**
+ * Class represents edge which is used for output JSON format (JSON between frontend and backend).
+ */
+public class Edge extends BaseEdge {
+
+    /**
+     * List of subedgeInfo.
+     * When two input edges are equals, in output their are in one record and their differences are in subedgeInfo.
+     */
+    private List<SubedgeInfo> subedgeInfo;
+
+    /**
+     * Create new edge.
+     * @param id new generated identification number
+     * @param from original ID of vertex from edge leads
+     * @param to original ID of vertex where edge leads
+     * @param text additional info
+     * @param subedgeInfo list which contains differences between equals edges
+     */
+    public Edge(int id, int from, int to, String text, List<SubedgeInfo> subedgeInfo) {
+        super(id, from, to, text);
+        this.subedgeInfo = subedgeInfo;
+    }
+
+    public List<SubedgeInfo> getSubedgeInfo(){
+        return subedgeInfo;
+    }
+
+    public void setSubedgeInfo(List<SubedgeInfo> subedgeInfo) {
+        this.subedgeInfo = subedgeInfo;
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/EdgeArchetype.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/EdgeArchetype.java
new file mode 100644
index 0000000..d836c3b
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/EdgeArchetype.java
@@ -0,0 +1,19 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+public class EdgeArchetype {
+    public String name;
+    public String text;
+
+    public EdgeArchetype(String name, String text) {
+        this.name = name;
+        this.text = text;
+    }
+
+    public String getName() {
+        return  name;
+    }
+
+    public String getText() {
+        return text;
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Graph.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Graph.java
new file mode 100644
index 0000000..bc95629
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Graph.java
@@ -0,0 +1,111 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.*;
+
+/**
+ * Class represents graph with all information about graph plus information about state in which used store graph.
+ * Class is used for creating of JSON which is send to frontend.
+ */
+public class Graph {
+
+    private Set<Vertex> vertices;
+    private List<Edge> edges;
+    private List<VertexArchetype> vertexArchetypes;
+    private List<EdgeArchetype> edgeArchetypes;
+    private List<AttributeType> attributeTypes;
+    private Map<String, List<String>> possibleEnumValues;
+
+    private List<Group> groups;
+    private List<SideBar> sideBar;
+    private String highlightedVertex; // group-ID, vertex-ID
+    private String highlightedEdge;
+
+    private static final Logger logger = LogManager.getLogger();
+
+    public Graph() {
+        vertices = new HashSet<>();
+        edges = new LinkedList<>();
+    }
+
+    public List<Edge> getEdges() {
+        logger.trace("ENTRY");
+        logger.trace("EXIT");
+        return edges;
+    }
+
+    public Set<Vertex> getVertices() {
+        logger.trace("ENTRY");
+        logger.trace("EXIT");
+        return vertices;
+    }
+
+    public List<VertexArchetype> getVertexArchetypes() {
+        return vertexArchetypes;
+    }
+
+    public List<EdgeArchetype> getEdgeArchetypes() {
+        return edgeArchetypes;
+    }
+
+    public List<AttributeType> getAttributeTypes() {
+        return attributeTypes;
+    }
+
+    public Map<String, List<String>> getPossibleEnumValues() {
+        return possibleEnumValues;
+    }
+
+    public List<Group> getGroups() {
+        return groups;
+    }
+
+    public List<SideBar> getSideBar() {
+        return sideBar;
+    }
+
+    public String getHighlightedVertex() {
+        return highlightedVertex;
+    }
+
+    public String getHighlightedEdge() {
+        return highlightedEdge;
+    }
+
+    public void setVertexArchetypes(List<VertexArchetype> vertexArchetypes) {
+        this.vertexArchetypes = vertexArchetypes;
+    }
+
+    public void setEdgeArchetypes(List<EdgeArchetype> edgeArchetypes) {
+        this.edgeArchetypes = edgeArchetypes;
+    }
+
+    public void setAttributeTypes(List<AttributeType> attributeTypes) {
+        this.attributeTypes = attributeTypes;
+    }
+
+    public void setPossibleEnumValues(Map<Integer, List<String>> possibleEnumValues) {
+        this.possibleEnumValues = new HashMap<>();
+        for (Map.Entry<Integer, List<String>> entry : possibleEnumValues.entrySet()) {
+            this.possibleEnumValues.put("" + entry.getKey(), entry.getValue());
+        }
+    }
+
+    public void setGroups(List<Group> groups) {
+        this.groups = groups;
+    }
+
+    public void setSideBar(List<SideBar> sideBar) {
+        this.sideBar = sideBar;
+    }
+
+    public void setHighlightedVertex(String highlightedVertex) {
+        this.highlightedVertex = highlightedVertex;
+    }
+
+    public void setHighlightedEdge(String highlightedEdge) {
+        this.highlightedEdge = highlightedEdge;
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Group.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Group.java
new file mode 100644
index 0000000..fd28ab0
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Group.java
@@ -0,0 +1,101 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class represents group of edges and their settings. Used in JSON between frontend and backend.
+ */
+public class Group {
+
+    /** Generated id of group. */
+    private int id;
+    /** Name of group */
+    private String name;
+    /** List of vertices id which belongs to this group */
+    private List<Integer> verticesId;
+    /** List of vertices id whose outgoing edges are visible. */
+    private List<Integer> verticesEdgeFromId;
+    /** List of vertices id whose incoming edges are visible. */
+    private List<Integer> verticesEdgeToId;
+    /** Relative position in graph */
+    private Position position;
+
+    public Group(int id, String name){
+        this.id = id;
+        this.name = name;
+        this.verticesId = new ArrayList<>();
+        this.verticesEdgeFromId = new ArrayList<>();
+        this.verticesEdgeToId = new ArrayList<>();
+        this.position = null;
+    }
+
+    public Group(int id, String name, List<Integer> verticesId, List<Integer> verticesEdgeFromId, List<Integer> verticesEdgeToId) {
+        this.id = id;
+        this.name = name;
+        this.verticesId = verticesId;
+        this.verticesEdgeFromId = verticesEdgeFromId;
+        this.verticesEdgeToId = verticesEdgeToId;
+        this.position = null;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<Integer> getVerticesId() {
+        return verticesId;
+    }
+
+    public void setVerticesId(List<Integer> verticesId) {
+        this.verticesId = verticesId;
+    }
+
+    public List<Integer> getVerticesEdgeFromId() {
+        return verticesEdgeFromId;
+    }
+
+    public void setVerticesEdgeFromId(List<Integer> verticesEdgeFromId) {
+        this.verticesEdgeFromId = verticesEdgeFromId;
+    }
+
+    public List<Integer> getVerticesEdgeToId() {
+        return verticesEdgeToId;
+    }
+
+    public void setVerticesEdgeToId(List<Integer> verticesEdgeToId) {
+        this.verticesEdgeToId = verticesEdgeToId;
+    }
+
+    public void addVertexId(int vertexId){
+        this.verticesId.add(vertexId);
+    }
+
+    public void addVetexEdgeToId(int vertexId){
+        this.verticesEdgeToId.add(vertexId);
+    }
+
+    public void addVetexEdgeFromId(int vertexId){
+        this.verticesEdgeFromId.add(vertexId);
+    }
+
+    public Position getPosition() {
+        return position;
+    }
+
+    public void setPosition(Position position) {
+        this.position = position;
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Position.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Position.java
new file mode 100644
index 0000000..8b18aae
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Position.java
@@ -0,0 +1,33 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+/**
+ * Class is used for storing information about vertex/group relative position.
+ */
+public class Position {
+
+    /** Relative X position. */
+    private float x;
+    /** Relative Y position */
+    private float y;
+
+    public Position(float x, float y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    public float getX() {
+        return x;
+    }
+
+    public void setX(float x) {
+        this.x = x;
+    }
+
+    public float getY() {
+        return y;
+    }
+
+    public void setY(float y) {
+        this.y = y;
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/SideBar.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/SideBar.java
new file mode 100644
index 0000000..634ba50
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/SideBar.java
@@ -0,0 +1,33 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+/**
+ * Class store information about item in side bar.
+ */
+public class SideBar {
+
+    /** Identification number of vertex or group which was generated in application. */
+    private int vertexId;
+    /** Indicates if related vertexes of this item have visible icon which shows relation with this item. */
+    private boolean isIconsDisplayed;
+
+    public SideBar(int vertexId, boolean isIconsDisplayed) {
+        this.vertexId = vertexId;
+        this.isIconsDisplayed = isIconsDisplayed;
+    }
+
+    public int getVertexId() {
+        return vertexId;
+    }
+
+    public void setVertexId(int vertexId) {
+        this.vertexId = vertexId;
+    }
+
+    public boolean isIconsDisplayed() {
+        return isIconsDisplayed;
+    }
+
+    public void setIconsDisplayed(boolean iconsDisplayed) {
+        this.isIconsDisplayed = iconsDisplayed;
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/SubedgeInfo.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/SubedgeInfo.java
new file mode 100644
index 0000000..7610127
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/SubedgeInfo.java
@@ -0,0 +1,37 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+import java.util.List;
+
+public class SubedgeInfo {
+
+    /** Edge archetype index. */
+    private int archetype;
+    /** Original id of edge which is taken from input JSON file. */
+    private int id;
+    /** List of all tributes. Every attribute is stored in String array in pair as {attribute name, attribute value}. */
+    private List<String[]> attributes;
+
+    /**
+     * Create new subedgeInfo
+     * @param id Original id of edge which is taken from input JSON file.
+     * @param archetype Edge archetype index.
+     * @param attributes  List of all tributes. Every attribute is stored in String array in pair as {attribute name, attribute value}.
+     */
+    public SubedgeInfo(int id, int archetype, List<String[]> attributes) {
+        this.id = id;
+        this.archetype = archetype;
+        this.attributes = attributes;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public int getArchetype() {
+        return archetype;
+    }
+
+    public List<String[]> getAttributes() {
+        return attributes;
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Vertex.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Vertex.java
new file mode 100644
index 0000000..9138751
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/Vertex.java
@@ -0,0 +1,44 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+import java.util.List;
+
+/**
+ * Class represents vertex which is used for output JSON format (JSON between frontend and backend)
+ */
+public class Vertex extends BaseVertex {
+
+    /** List of all tributes. Every attribute is stored in String array in pair as {attribute name, attribute value}. */
+    private List<String[]> attributes;
+    /** Relative position in graph */
+    private Position position;
+
+    /**
+     * Create new vertex.
+     * @param id original identification number from input file
+     * @param name of vertex
+     * @param archetypeIndex index of vertex archetype
+     * @param text additional info
+     * @param attributes List of all attributes. Every attribute is stored in String array in pair as {attribute name, attribute value}.
+     */
+    public Vertex(int id, String name, int archetypeIndex, String text, List<String[]> attributes) {
+        super(id, name, archetypeIndex, text);
+        this.attributes = attributes;
+        this.position = null;
+    }
+
+    public List<String[]> getAttributes() {
+        return attributes;
+    }
+
+    public void setAttributes(List<String[]> attributes) {
+        this.attributes = attributes;
+    }
+
+    public Position getPosition() {
+        return position;
+    }
+
+    public void setPosition(Position position) {
+        this.position = position;
+    }
+}
diff --git a/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/VertexArchetype.java b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/VertexArchetype.java
new file mode 100644
index 0000000..707a3bf
--- /dev/null
+++ b/plugins/_template/src/main/java/cz/zcu/kiv/imiger/plugin/spade/api/VertexArchetype.java
@@ -0,0 +1,29 @@
+package cz.zcu.kiv.imiger.plugin.spade.api;
+
+public class VertexArchetype {
+    public String name;
+    public String text;
+    public String icon;
+
+    public VertexArchetype(String name, String text, String icon) {
+        this.name = name;
+        this.text = text;
+        this.icon = icon;
+    }
+
+    public VertexArchetype(String name, String text) {
+        this(name, text, "");
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+}
diff --git a/plugins/_template/src/main/resources/META-INF/MANIFEST.MF b/plugins/_template/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..17111f4
--- /dev/null
+++ b/plugins/_template/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Created-By: Apache Maven ${maven.version}
+Built-By: ${user.name}
+Build-Jdk: ${java.version}
+Module-Name: My Convertor
diff --git a/plugins/_template/src/main/resources/log4j2.properties b/plugins/_template/src/main/resources/log4j2.properties
new file mode 100644
index 0000000..bf4c521
--- /dev/null
+++ b/plugins/_template/src/main/resources/log4j2.properties
@@ -0,0 +1,18 @@
+name=PropertiesConfig
+property.filename = logs
+appenders = console, file
+
+appender.console.type = Console
+appender.console.name = STDOUT
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern=%d{yy-MM-dd HH:mm:ss:SSS} %-6p [%c:%M:%L] - %m%n
+
+appender.file.type = File
+appender.file.name = LOGFILE
+appender.file.fileName=${filename}/propertieslogs.log
+appender.file.layout.type=PatternLayout
+appender.file.layout.pattern=%d{yy-MM-dd HH:mm:ss:SSS} %-6p [%c:%M:%L] - %m%n
+
+rootLogger.level = debug
+rootLogger.appenderRefs = stdout
+rootLogger.appenderRef.stdout.ref = STDOUT
\ No newline at end of file
diff --git a/plugins/_template/src/test/java/PluginTest.java b/plugins/_template/src/test/java/PluginTest.java
new file mode 100644
index 0000000..4392e70
--- /dev/null
+++ b/plugins/_template/src/test/java/PluginTest.java
@@ -0,0 +1,69 @@
+import org.junit.jupiter.api.Test;
+import org.junit.platform.commons.util.StringUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.jar.Attributes;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * This class is only for testing integrity of Jar file.
+ * Testing:
+ *      Jar file can be open
+ *      Manifest contains Module-Name and it is not blank
+ *      Manifest contains Module-Class and this class exists in Jar file
+ *      Given class contains method 'String getRawJson(String)'
+ *
+ *
+ * !!! BEFORE USAGE PLEASE CHANGE VARIABLE 'ARCHIVE_WITH_DEPENDENCIES_PATH' !!!
+ */
+class PluginTest {
+
+    private static final String ARCHIVE_WITH_DEPENDENCIES_PATH = "target\\imiger-plugin-template-1.0-SNAPSHOT-jar-with-dependencies.jar";
+
+
+    // ========================================= DO NOT CHANGE UNDER THIS LINE =========================================
+
+    private static final String MODULE_CLASS_IDENTIFIER = "Module-Class";
+    private static final String MODULE_NAME_IDENTIFIER = "Module-Name";
+    private static final String METHOD_NAME = "getRawJson";
+    private static final Class METHOD_PARAMETER_CLASS = String.class;
+
+    @Test
+    void integrityTest() {
+        try {
+            File jarFile = new File(ARCHIVE_WITH_DEPENDENCIES_PATH);
+
+            JarInputStream jis = new JarInputStream(new FileInputStream(jarFile));
+            final Manifest mf = jis.getManifest();
+            final Attributes attributes = mf.getMainAttributes();
+            final String moduleClassName = attributes.getValue(MODULE_CLASS_IDENTIFIER);
+            final String moduleVisibleName = attributes.getValue(MODULE_NAME_IDENTIFIER);
+
+            assertFalse(StringUtils.isBlank(moduleClassName), "Blank module class name given by manifest attribute 'Module-Class'");
+            assertFalse(StringUtils.isBlank(moduleVisibleName), "Blank module visible name given by manifest attribute 'Module-Name'");
+
+            final ClassLoader loader = URLClassLoader.newInstance(new URL[]{jarFile.toURI().toURL()});
+            final Class<?> clazz = Class.forName(moduleClassName, true, loader);
+            // checking if method exists, if not throw exception
+            Method method = clazz.getMethod(METHOD_NAME, METHOD_PARAMETER_CLASS);
+
+
+            assertEquals(String.class, method.getReturnType(), "Invalid method return type.");
+
+        } catch (IOException e){
+            fail("Can not open given Jar file. Given path is probably incorrect.");
+        } catch (ClassNotFoundException e) {
+            fail("Class given by attribute 'Module-Class' in MANIFEST.MF was not found in Jar file.");
+        } catch (NoSuchMethodException e) {
+            fail("Class given by attribute 'Module-Class' in MANIFEST.MF do not contains method: String getRawJson(String).");
+        }
+    }
+}
