Index: hci/trunk/eneraptor-web-app/web-app/img/icons/arrow_leftright.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: hci/trunk/eneraptor-web-app/web-app/img/icons/arrow_leftright.png
===================================================================
--- hci/trunk/eneraptor-web-app/web-app/img/icons/arrow_leftright.png	(revision 0)
+++ hci/trunk/eneraptor-web-app/web-app/img/icons/arrow_leftright.png	(revision 6)

Property changes on: hci/trunk/eneraptor-web-app/web-app/img/icons/arrow_leftright.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: hci/trunk/eneraptor-web-app/web-app/css/style.css
===================================================================
--- hci/trunk/eneraptor-web-app/web-app/css/style.css	(revision 5)
+++ hci/trunk/eneraptor-web-app/web-app/css/style.css	(revision 6)
@@ -9,6 +9,7 @@
 body{
 	font-size: 12px;
 	font-family: Arial, Tahoma, Verdana;
+	min-height: 700px;
 }
 a, a:visited{
 	text-decoration:none;
@@ -345,6 +346,20 @@
 	background:#E4F0C9;
 	padding: 8px;
 }
+
+.warningBoxContent {
+	border:1px solid #FCFFAB;
+	background:#FDFFCC;
+	padding: 8px;
+}
+
+.rawInfoBox {
+	padding:10px;
+	border:1px solid #FCFFAB;
+	background:#FDFFCC;
+	margin:5px;
+	font-family:monospace;	
+}
 /*********************
 	Icons
 *********************/
@@ -387,12 +402,13 @@
 *********************/
 
 .sysState-main{background:transparent url(../img/icons/eye.png) no-repeat left;}
-.sysState-measure{background:transparent url(../img/icons/chart_bar.png) no-repeat left;}
+.sysState-measure{background:transparent url(../img/icons/monitor.png) no-repeat left;}
+.sysState-actions{background:transparent url(../img/icons/lightning.png) no-repeat left;}
 
 .sysLog-main{background:transparent url(../img/icons/eye.png) no-repeat left;}
 .sysLog-browse{background:transparent url(../img/icons/magnifier.png) no-repeat left;}
 
 .config-main{background:transparent url(../img/icons/eye.png) no-repeat left;}
-.config-hci{background:transparent url(../img/icons/cog.png) no-repeat left;}
+.config-hci{background:transparent url(../img/icons/application.png) no-repeat left;}
 .config-logic{background:transparent url(../img/icons/cog.png) no-repeat left;}
-.config-connection{background:transparent url(../img/icons/cog.png) no-repeat left;}
\ No newline at end of file
+.config-connection{background:transparent url(../img/icons/connect.png) no-repeat left;}
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/taglib/com/eneraptor/hci/ErptrJSTagLib.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/taglib/com/eneraptor/hci/ErptrJSTagLib.groovy	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/taglib/com/eneraptor/hci/ErptrJSTagLib.groovy	(revision 6)
@@ -0,0 +1,22 @@
+package com.eneraptor.hci
+
+class ErptrJSTagLib {
+
+	static namespace = 'js'
+	
+	def checkBoxToggle = {
+		
+		out << "<script type='text/javascript'>"
+		out << "var toggleCheck = false;"
+		out << "function checkToggle(formId) {"
+		out << "  if (toggleCheck == false) toggleCheck = true; else toggleCheck = false;"
+		out << "  for (var i = 0; i < document.getElementById(formId).elements.length; i++) {"
+		out << "    if(document.getElementById(formId).elements[i].type == 'checkbox')"
+		out << "      document.getElementById(formId).elements[i].checked = toggleCheck;"
+		out << "  }"
+		out << "}"
+		out << "</script>"
+		
+	}
+	
+}
Index: hci/trunk/eneraptor-web-app/grails-app/taglib/com/eneraptor/hci/ErptrTagLib.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/taglib/com/eneraptor/hci/ErptrTagLib.groovy	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/taglib/com/eneraptor/hci/ErptrTagLib.groovy	(revision 6)
@@ -32,7 +32,11 @@
 				out << g.createLink(controller: "${it.name}", action: "${it.url}")
 				out << "' class='"
 				out << "${it.name}-${it.url}"
-				out << "'>${it.label}</a></li>"
+				out << "'>"
+				if(attrs.chosen == it.url) out << "<u>"
+				out << it.label
+				if(attrs.chosen == it.url) out << "</u>"
+				out << "</a></li>"
 			}
 		}
 		
@@ -62,7 +66,7 @@
 	def confirmBox = { attrs, body ->
 		out << "<div id='confirmBox'>"
 		out << "<div class='confirmBoxContent'>"
-		out << "<img style='float: left;margin:5px;' src='" + g.resource(dir: 'img/icons/', file:'tick.png') + "' />"
+		out << "<img style='float: left;margin:5px;position:relative;top:-2px;' src='" + g.resource(dir: 'img/icons/', file:'tick.png') + "' />"
 		out << body()
 		out << "</div>"
 		out << "</div><br />"
@@ -71,12 +75,21 @@
 	def errorBox = { attrs, body ->
 		out << "<div id='errorBox'>"
 		out << "<div class='errorBoxContent'>"
-		out << "<img style='float: left;margin:5px;' src='" + g.resource(dir: 'img/icons/', file:'cross.png') + "' />"
+		out << "<img style='float: left;margin:5px;position:relative;top:-2px;' src='" + g.resource(dir: 'img/icons/', file:'cross.png') + "' />"
 		out << body()
 		out << "</div>"
 		out << "</div><br />"
 	}
 	
+	def warningBox = { attrs, body ->
+		out << "<div id='warningBox'>"
+		out << "<div class='warningBoxContent'>"
+		out << "<img style='float: left;margin:5px;position:relative;top:-2px;' src='" + g.resource(dir: 'img/icons/', file:'error.png') + "' />"
+		out << body()
+		out << "</div>"
+		out << "</div><br />"
+	}
+	
 	def logEntryOptions = { attrs ->
 		out << "<a href='"
 		out << g.createLink(action: 'detail', id: attrs.for)
@@ -94,6 +107,23 @@
 		out << "</a>"
 	}
 	
+	def changeDeleteOptions = { attrs ->
+		out << "<a href='"
+		out << g.createLink(action: 'change' + attrs.table + 'Entry', id: attrs.for)
+		out << "'>"
+		out << "<img src='"
+		out << g.resource(dir: 'img/icons/', file: 'wrench_orange.png')
+		out << "' />"
+		out << "</a>"
+		out << "<a href='"
+		out << g.createLink(action: 'delete' + attrs.table + 'Entry', id: attrs.for)
+		out << "'>"
+		out << "<img src='"
+		out << g.resource(dir: 'img/icons/', file: 'delete.png')
+		out << "' />"
+		out << "</a>"
+	}
+	
 	def icon = { attrs ->
 		out << "<img style='float:left;position:relative;bottom:2px;' src='"
 		out << g.resource(dir: "img/icons/", file: attrs.w + ".png")
@@ -106,4 +136,10 @@
 		
 	}
 	
+	def rawInfoBox = { attrs, body ->
+		out << "<div class='rawInfoBox'>"
+		out << body()
+		out << "</div>"
+	}
+	
 }
Index: hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/MainMenuService.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/MainMenuService.groovy	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/MainMenuService.groovy	(revision 6)
@@ -31,7 +31,8 @@
 		
 		sysStateSubMenu = new ArrayList()
 		sysStateSubMenu.add(new MenuItem("Overview","sysState","main"))
-		sysStateSubMenu.add(new MenuItem("Measurements","sysState","measure"))
+		sysStateSubMenu.add(new MenuItem("Last measurements","sysState","measure"))
+		sysStateSubMenu.add(new MenuItem("Last actions taken","sysState","actions"))
 		
 		sysLogSubMenu = new ArrayList()
 		sysLogSubMenu.add(new MenuItem("Overview","sysLog","main"))
Index: hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/HciLogicCommService.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/HciLogicCommService.groovy	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/HciLogicCommService.groovy	(revision 6)
@@ -0,0 +1,47 @@
+package com.eneraptor.hci
+
+class HciLogicCommService {
+
+    static transactional = true
+
+    Map getReplyToRequest(String requestContent) {
+		
+		Map reply = new HashMap()
+		
+		Socket logicSocket = null;
+		PrintWriter toLogic = null;
+		BufferedReader fromLogic = null;
+		
+		def ipAddress = InternalConfig.findByConfigId("logic-ip")['configVal']
+		def portNum = InternalConfig.findByConfigId("logic-port")['configVal']
+
+		try {
+			logicSocket = new Socket(ipAddress, portNum as int);
+			toLogic = new PrintWriter(logicSocket.getOutputStream(), true);
+			fromLogic = new BufferedReader(new InputStreamReader(
+										logicSocket.getInputStream()));
+		} catch (UnknownHostException e) {
+			reply['status'] = "error"
+			reply['content'] = "Unknown host: "
+			reply['content'] += e.getMessage()
+			return reply
+		} catch (IOException e) {
+			reply['status'] = "error"
+			reply['content'] += e.getMessage()
+			return reply
+		}
+		
+		reply['status'] = "ok"
+		reply['content'] = ""
+		toLogic.println(requestContent)
+		List allLines = new ArrayList()
+		allLines = fromLogic.readLines()
+		allLines.each {
+			reply['content'] += it.toString() + "\n"
+		}
+		
+		return reply
+
+    }
+	
+}
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysStateController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysStateController.groovy	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysStateController.groovy	(revision 6)
@@ -1,7 +1,110 @@
 package com.eneraptor.hci
 
 class SysStateController {
-
-    def main = { }
+
+	def reportService
+	def hciLogicCommService
 	
+    def main = {
+		
+		List inDevices = DeviceInfo.findAllByInputDevice(true, [sort:'friendlyName', order:'asc'])
+		List inDevicesData = new ArrayList()
+		inDevices.each {
+			Map inDeviceDataEntry = new HashMap()
+			inDeviceDataEntry['friendlyName'] = it.friendlyName
+			inDeviceDataEntry['icon'] = it.iconPath
+			inDeviceDataEntry['loggedData'] = LoggedData.findByDeviceId(it.deviceId, [sort:'dateRecieved', order:'desc'])	
+			inDevicesData << inDeviceDataEntry
+		}
+		
+		List outDevices = DeviceInfo.findAllByOutputDevice(true, [sort:'friendlyName', order:'asc'])
+		List outDevicesData = new ArrayList()
+		outDevices.each {
+			Map outDeviceDataEntry = new HashMap()
+			outDeviceDataEntry['friendlyName'] = it.friendlyName
+			outDeviceDataEntry['icon'] = it.iconPath
+			outDeviceDataEntry['loggedData'] = LoggedData.findByDeviceId(it.deviceId, [sort:'dateRecieved', order:'desc'])
+			outDevicesData << outDeviceDataEntry
+		}
+		
+		[inDevicesData: inDevicesData, outDevicesData: outDevicesData]
+		
+	}
+	
+	def measure = {
+		
+		List inDevices = DeviceInfo.findAllByInputDevice(true, [sort:'friendlyName', order:'asc'])
+		List inDevicesData = new ArrayList()
+		inDevices.each {
+			Map inDeviceDataEntry = new HashMap()
+			inDeviceDataEntry['deviceId'] = it.deviceId
+			inDeviceDataEntry['friendlyName'] = it.friendlyName
+			inDeviceDataEntry['icon'] = it.iconPath
+			inDeviceDataEntry['loggedData'] = LoggedData.findByDeviceId(it.deviceId, [sort:'dateRecieved', order:'desc'])
+			inDevicesData << inDeviceDataEntry
+		}
+		
+		[inDevicesData: inDevicesData]
+		
+    }
+	
+	def measureUpdate = {
+		
+		List devices = new ArrayList()
+		
+		DeviceInfo.findAllByInputDevice(true).each {
+			if(params[it.deviceId] == "on")
+				devices << it.deviceId
+		}
+		
+		def output = "";
+		
+		if(devices.size == 0) {
+			flash['errors'] = "<p>No device was selected. At least one device must be selected.</p>"
+			redirect(action: 'measure')
+			return false
+		}
+		
+		output += reportService.println("Trying to update measurements manually for devices")
+		devices.each {
+			output += reportService.println(" - " + it)
+		}
+		output += reportService.println("Generating request xml")
+		
+		// generate request xml
+		def reqXML = "<todo />"
+		
+		output += reportService.println("Request xml generated")
+		output += reportService.println("Sending request")
+		
+		// send request
+		Map rspXML = hciLogicCommService.getReplyToRequest(reqXML)
+		
+		if(rspXML['status'] == "error") {
+			output += reportService.println("<span style='color:red;'>Error: " + rspXML['content'] + "</span>")
+		} else {
+			output += reportService.println("<span style='color:red;'>Error: implementation missing - TODO.</span>")
+		}
+		
+		[errorExplanation: output]
+		
+	}
+	
+	def actions = {
+		
+		List outDevices = DeviceInfo.findAllByOutputDevice(true, [sort:'friendlyName', order:'asc'])
+		List outDevicesData = new ArrayList()
+		outDevices.each {
+			Map outDeviceDataEntry = new HashMap()
+			outDeviceDataEntry['deviceId'] = it.deviceId
+			outDeviceDataEntry['friendlyName'] = it.friendlyName
+			outDeviceDataEntry['icon'] = it.iconPath
+			outDeviceDataEntry['loggedData'] = LoggedData.findByDeviceId(it.deviceId, [sort:'dateRecieved', order:'desc'])
+			outDevicesData << outDeviceDataEntry
+		}
+		
+		[outDevicesData: outDevicesData]
+		
+    }
+	
 }
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysLogController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysLogController.groovy	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysLogController.groovy	(revision 6)
@@ -10,14 +10,43 @@
 	
 	def browse = {
 		
+		flash['warnings'] = null
+		
 		def entries = LoggedData.list()
+		Map devices = new HashMap()
+		Map icons   = new HashMap()
+		List unknownDevices = new ArrayList()
+		DeviceInfo.list().each {
+			devices[it.deviceId] = it.friendlyName
+			if(it.iconPath) {
+				icons[it.deviceId] = it.iconPath
+			}
+		}
+		entries.each {
+			if(!devices[it.deviceId]) {
+				if(!unknownDevices.contains(it.deviceId)) {
+					unknownDevices << it.deviceId
+				}
+			}
+		}
+		unknownDevices.each {
+			if(!flash['warnings']) flash['warnings'] = ""
+			flash['warnings'] += "<p>There was found at least one log entry for a device with id <b>${it}</b>, which is <b>unknown</b> to HCI. You should <b>add this device</b> by <b>" + g.link(controller: 'config', action: 'addDevice', params: ['deviceId' : it], "clicking here") + "</b>.</p>"
+		}
 		
-		[data: entries]
+		[data: entries, devices: devices, icons: icons]
 		
 	}
 	
 	def detail = {
 		
+		def detailsOf = LoggedData.findById(params.id)
+		if(!detailsOf) {
+			flash['errors'] = "<p>There is no logged data with id ${params.id}</p>"
+			redirect(action: 'browse')
+			return false
+		}
+		return detailsOf.getProperties()
 	}
 	
 	def deleteEntry = {
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ConfigController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ConfigController.groovy	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ConfigController.groovy	(revision 6)
@@ -1,13 +1,31 @@
 package com.eneraptor.hci
 
-class ConfigController {
+import groovy.sql.*
+import java.sql.*
+
+class ConfigController {
+	
+	def dataSource
 
     def main = { }
 	
 	def hci = {
-	
+		
+		def db_sql = new Sql(dataSource)
+		
+		def single = db_sql.firstRow("show data_directory")
+		def loca = single.data_directory
+		def partition = new File(loca)
+		def totalSpace = partition.getTotalSpace()
+		def freeSpace  = partition.getFreeSpace()
+		
+		totalSpace = (int)((totalSpace/1024)/1024)
+		freeSpace = (int)((freeSpace/1024)/1024)
+		
+		def percent = 100 - ((int) ((freeSpace/totalSpace)*100))
+		
 		def allDevices = DeviceInfo.list()
-		[conf: InternalConfig, devices: allDevices]		
+		[conf: InternalConfig, devices: allDevices, totalSpace: totalSpace, freeSpace: freeSpace, percent: percent]		
 	}
 	
 	def addDevice = {
@@ -15,16 +33,69 @@
 	
 	def addDeviceSave = {
 		def newDevice = new DeviceInfo(params)
-		if(newDevice.validate()) {
+		if(newDevice.validate() && (params.inputDevice || params.outputDevice)) {
 			newDevice.save()
 			flash['confirms'] = "<p>New device added successfully.</p>"
 			redirect(action:'hci')
 		} else {
 			flash['errors'] = "<p>New device was not saved. Check input data.</p>"
+			if(!params.inputDevice && !params.outputDevice)
+				flash['errors'] += "<p>Device must be capable of making masurements, actions or both. You have selected none.</p>"
 			redirect(action:'addDevice', params: params)
 		}
 	}
 	
+	def deleteHciEntry = {
+		
+		def deviceToBeDeleted = DeviceInfo.findById(params.id)
+		
+		if(deviceToBeDeleted) {
+			deviceToBeDeleted.delete()
+			flash['confirms'] = "<p>Device deleted succesfully.</p>"
+		} else {
+			flash['errors'] = "<p>There was no device deleted.</p><p>There was no device with id ${params.id}.</p>"
+		}
+		redirect(action: 'hci')
+		
+	}
+	
+	def changeHciEntry = {
+		
+		def deviceToBeChanged = DeviceInfo.findById(params.id)
+		if(!deviceToBeChanged) {
+			flash['errors'] = "<p>There is no device with id ${params.id}.</p>"
+			redirect(action: 'hci')
+			return false
+		}
+		deviceToBeChanged.getProperties()
+    }
+	
+	def changeHciEntrySave = {
+		
+		def deviceToBeUpdated = DeviceInfo.findById(params.id)
+		deviceToBeUpdated.properties = params
+		if(deviceToBeUpdated.save()) {
+			flash['confirms'] = "<p>Device updated succesfully.</p>"
+			redirect(action: 'hci')
+		} else {
+			flash['errors'] = "<p>Device was not changed.</p>"
+			redirect(action:'changeHciEntry', params: params)
+		}
+		
+	}
+	
+	def dbInfo = {
+		
+		List databaseInfo = new ArrayList()
+		def db_sql = new Sql(dataSource)
+		db_sql.eachRow "SHOW ALL", {
+			databaseInfo << it.toRowResult()
+		}
+		
+		[databaseInfo: databaseInfo]
+		
+	}
+	
 	def logic = {
 		
 		[conf: InternalConfig]
@@ -53,6 +124,41 @@
 		
 	}
 	
+	def dbExec = {
+		
+		if(params['sqlQuery']) {
+			
+			flash['confirms'] = null
+			flash['errors'] = null
+			
+			def db_sql = new Sql(dataSource)
+			List rows
+			List keys = new ArrayList()
+			boolean wasError = false
+			try {
+				rows = db_sql.rows(params['sqlQuery'])
+				rows[0].each {
+					keys << it.key
+				}
+				flash['confirms'] = "<p>SQL query executed succesfully. Chrck returned rows below.</p>"
+			} catch (SQLException e) {
+				rows = new ArrayList()
+				if(e.getSQLState().equals("02000")) {
+					keys << 'SQL query result'
+					rows << ['SQL query result' : 'No rows were returned.']
+					flash['confirms'] = "<p>SQL query executed succesfully.</p>"
+				} else {
+					rows << e
+					rows << e.getSQLState()
+					wasError = true
+					flash['errors'] = "<p>There was an error while executing the SQL query. Check the report below.</p><p>The query was not executed</p>"
+				}
+			}
+			return [sqlResult: rows, keys: keys, wasError: wasError]
+		}
+		
+	}
+	
 	def getHelp = {
 		[what : params.what]
 	}
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/LogicRequestController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/LogicRequestController.groovy	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/LogicRequestController.groovy	(revision 6)
@@ -3,6 +3,7 @@
 class LogicRequestController {
 
 	def reportService
+	def hciLogicCommService
 	
     def testConnection = {
 		
@@ -12,7 +13,22 @@
 		output += reportService.println("Logic port number: " + InternalConfig.findByConfigId('logic-port').configVal)
 		
 		output += reportService.println("Test started")
-		output += reportService.println("<span style='color:red;'>Error: " + "Connection implementation missing.</span>")
+		
+		String reqStr = "<hci-request type='checkConnection'><data>012345</data></hci-request>"
+		Map testReply = hciLogicCommService.getReplyToRequest(reqStr)
+		
+		if(testReply['status'] == "error") {
+			output += reportService.println("<span style='color:red;'>Error: " + testReply['content'] + "</span>")
+		} else {
+			output += reportService.println("Connection established succesfully")
+			if(testReply['content'] == "012345") {
+				output += "<span style='color:green;'>Logic unit replied! The eneraptor system is set up properly.</span>"
+			} else {
+				output += reportService.println("<span style='color:red;'>The connection was established, but there was no reply from the logic unit.</span>")
+				output += reportService.println("<span style='color:red;'>You should check the logic's port number and IP address.</span>");
+			}
+		}
+		
 		output += reportService.println("Test ended")
 		
 		[output:output]
Index: hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/DeviceInfo.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/DeviceInfo.groovy	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/DeviceInfo.groovy	(revision 6)
@@ -6,11 +6,17 @@
 	String friendlyName
 	String description
 	String iconPath
+	boolean inputDevice
+	boolean outputDevice
+	
+	 
 	
     static constraints = {
 		deviceId(blank: false, unique: true)
 		friendlyName(blank: false, maxSize: 64)
 		description(nullable: true, maxSize: 128)
-		iconPath(nullable: true)
+		iconPath(nullable: true)
+		inputDevice(blank: false)
+		outputDevice(blank: false)
     }
 }
Index: hci/trunk/eneraptor-web-app/grails-app/views/config/dbExec.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/config/dbExec.gsp	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/views/config/dbExec.gsp	(revision 6)
@@ -0,0 +1,71 @@
+<html>
+
+<head>
+	<title>Configuration &raquo; Manual SQL querying</title>
+	<meta name="layout" content="main" />
+</head>
+
+<body>
+
+	<g:if test="${sqlResult}">
+		<erptr:box title="SQL query result">
+			<p>The SQL query has been executed. Result:</p>
+			<div>
+				
+				<g:if test="${wasError}">
+					<g:each in="${sqlResult}" var="row">
+						<p>${row.toString()}</p>
+					</g:each>
+				</g:if>
+				<g:else>
+				
+					<table width="100%">
+						<thead>
+							<tr>
+								<g:each in="${keys}" var="key">
+									<th>${key}</th>
+								</g:each>
+							</tr>
+						</thead>
+						<tbody>
+							<g:each in="${sqlResult}" var="row">
+								<tr>
+								<g:each in="${keys}" var="key">
+									<td>${row[key.toString()]}</td>
+								</g:each>
+								</tr>
+							</g:each>
+						</tbody>
+					</table>
+					
+				</g:else>
+				
+			</div>
+		</erptr:box>
+	</g:if>
+	
+	<erptr:box title="Manual SQL querying">
+	
+		<p style="color:red;"><erptr:icon w="error" /><i>Caution: Changing database contents and configuration may cause system errors and as a result the HCI may stop working. Use only if you are completely sure of what you are doing.</i></p>
+		
+		<g:form name="sqlQueryForm" action="dbExec">
+		
+			<p>SQL query:</p>
+		
+			<g:textArea name="sqlQuery" style="width:100%;height:150px;"></g:textArea>
+			
+			<br /><br />
+			
+			<g:submitButton name="sqlQueryFormSubmit" value="Execute" />
+			
+			<div style="float:right;">
+			<g:link target="_blank" url="http://www.postgresql.org/docs/9.0/static/sql.html"><erptr:icon w="help" />SQL language documentation</g:link>
+			</div>
+		
+		</g:form>
+	
+	</erptr:box>
+	
+</body>
+
+</html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/config/changeHciEntry.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/config/changeHciEntry.gsp	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/views/config/changeHciEntry.gsp	(revision 6)
@@ -0,0 +1,61 @@
+<html>
+
+<head>
+	<title>Configuration &raquo; HCI</title>
+	<meta name="layout" content="main" />
+</head>
+
+<body>
+	
+	<erptr:box title="Change device properties">
+	
+		<g:form name="change-device-form" action="changeHciEntrySave">
+		
+			<label for="deviceId">Device ID *</label>
+			<g:textField name="deviceId" value="${deviceId}" />
+			<erptr:helpLink for="deviceId"/>
+			
+			<br />
+			
+			<label for="friendlyName">Friendly name *</label>
+			<g:textField name="friendlyName" value="${friendlyName}" />
+			<erptr:helpLink for="friendlyName"/>
+					
+			<br />
+			
+			<label for="inputDevice">Can measure data</label>
+			<g:checkBox name ="inputDevice" value="${inputDevice}" />
+			<erptr:helpLink for="inputDevice"/>
+			
+			<br />
+			
+			<label for="outputDevice">Can run actions</label>
+			<g:checkBox name ="outputDevice" value="${outputDevice}" />
+			<erptr:helpLink for="outputDevice"/>
+			
+			<br />
+			
+			<label for="description">Short description</label>
+			<g:textArea name="description">${description}</g:textArea>
+					
+			<br />
+			
+			<label for="iconPath">Icon</label>
+			<g:textField name="iconPath" value="${iconPath}" />
+					
+			<br />
+			
+			<erptr:helpBox />
+			
+			<g:hiddenField name="id" value="${id}" />
+			
+			<g:actionSubmit action="hci" value="Cancel" />
+			<g:submitButton name="save" value="Save changes" />
+			
+		</g:form>
+	
+	</erptr:box>
+	
+</body>
+
+</html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/config/connection.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/config/connection.gsp	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/views/config/connection.gsp	(revision 6)
@@ -42,7 +42,7 @@
 		<p>You can test connectivity by pressing the 'Test connection' link below. This will show a simple report under it.</p>
 		<p>Note that any configuration changes (Logic's IP, port, etc.) should be saved first.</p>
 		<br />
-		<g:remoteLink controller="logicRequest" action="testConnection" update="testResponse" before="\$('testResponse').update('Testing... (Please wait)')" after="\$('testResponse').pulsate({pulses: 2, duration: 0.5})">Test connection</g:remoteLink>
+		<g:remoteLink controller="logicRequest" action="testConnection" update="testResponse" before="\$('testResponse').update('Testing... (Please wait)')" after="\$('testResponse').pulsate({pulses: 2, duration: 0.5})"><erptr:icon w="connect"></erptr:icon>Test connection</g:remoteLink>
 		<br /><br />
 		<div id="testResponse"></div>
 		
Index: hci/trunk/eneraptor-web-app/grails-app/views/config/dbInfo.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/config/dbInfo.gsp	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/views/config/dbInfo.gsp	(revision 6)
@@ -0,0 +1,19 @@
+<p>Database configuration:</p>
+<table width="100%">
+	<thead>
+		<tr>
+			<th>Name</th>
+			<th>Value</th>
+			<th>Description</th>
+		</tr>
+	</thead>
+	<tbody>
+		<g:each in="${databaseInfo}" var="row">
+			<tr>
+				<td>${row.name}</td>
+				<td>${row.setting}</td>
+				<td>${row.description}</td>
+			</tr>
+		</g:each>
+	</tbody>
+</table>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/config/hci.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/config/hci.gsp	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/views/config/hci.gsp	(revision 6)
@@ -7,13 +7,23 @@
 
 <body>
 	
-	<erptr:box title="HCI configuration">
-		<g:form name="hci-config-form" action="saveHci">
+	<erptr:box title="Information">
 		
-			<label for="hci-version">HCI Version</label>
-			<g:textField name="hci-version" value="${conf.findByConfigId('hci-version').configVal}" disabled="true" />
+		<p>HCI Version: &nbsp;&nbsp;&nbsp;<span style="font-family:monospace;">${conf.findByConfigId('hci-version').configVal}</span></p>
 			
-		</g:form>
+		<p style="float: left;">Disk usage: &nbsp;&nbsp;&nbsp;</p>
+		<div style="float:left;">
+			<div style="width: 100px;border:1px solid grey;">
+				<div style="width:${percent}px;background:grey;">
+					&nbsp;
+				</div>
+			</div>
+		</div>
+		<span> &nbsp;&nbsp;&nbsp; ${percent}% (free space ${(int)freeSpace} MB) </span>
+		<g:if test="${percent >= 95}">
+				<i style="color:red;">&nbsp;&nbsp;&nbsp;Warning: disk is almost full. You should erase some old log entries.</i>
+		</g:if>
+		
 	</erptr:box>
 	
 	<erptr:box title="Known devices">
@@ -21,9 +31,9 @@
 		<table width="100%">
 			<thead>
 				<tr>
-					<th width="28px">&nbsp;</th>
 					<th width="200px">Device ID</th>
 					<th width="200px">Friendly name</th>
+					<th width="100px">Capable of making</th>
 					<th>Description</th>
 					<th width="60px">Options</th>
 	            </tr>
@@ -31,15 +41,25 @@
 			<tbody>
 				<g:each in="${devices}" var="device">
 					<tr>
-						<td>
+						<td><p>
 							<g:if test="${device.iconPath}">
-							 <erptr:icon w="${device.iconPath}" />
+								<erptr:icon w="${device.iconPath}" /> &nbsp;
 							</g:if>
-						</td>
-						<td>${device.deviceId}</td>
-						<td>${device.friendlyName}</td>
-						<td>${device.description}</td>
-						<td>todo</td>
+						${device.deviceId}</p></td>
+						<td><p>${device.friendlyName}</p></td>
+						<td><p>
+							<g:if test="${device.inputDevice && device.outputDevice}">
+								measurements, actions
+							</g:if>
+							<g:if test="${device.inputDevice && !device.outputDevice}">
+								measurements
+							</g:if>
+							<g:if test="${!device.inputDevice && device.outputDevice}">
+								actions
+							</g:if>
+						</p></td>
+						<td><p>${device.description}</p></td>
+						<td><center><erptr:changeDeleteOptions table="Hci" for="${device.id}" /></center></td>
 					</tr>
 				</g:each>
 			</tbody>
@@ -57,6 +77,22 @@
 	
 	</erptr:box>
 	
+	<erptr:box title="Database information">
+	
+		<p>Eneraptor system uses PostgreSQL database management system to store log data and HCI configuration.</p>
+		
+		<br />
+		
+		<div id="dbConfigHolder">
+			<g:remoteLink action="dbInfo" update="dbConfigHolder"><erptr:icon w="eye" />View database configuration</g:remoteLink>
+		</div>
+		
+		<br />
+		
+		<g:link action="dbExec"><erptr:icon w="database_edit" />Execute SQL queries manually</g:link>
+		
+	</erptr:box>
+	
 </body>
 
 </html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/config/addDevice.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/config/addDevice.gsp	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/views/config/addDevice.gsp	(revision 6)
@@ -23,6 +23,18 @@
 					
 			<br />
 			
+			<label for="inputDevice">Can measure data</label>
+			<g:checkBox name ="inputDevice" value="${params['inputDevice']}" />
+			<erptr:helpLink for="inputDevice"/>
+			
+			<br />
+			
+			<label for="outputDevice">Can run actions</label>
+			<g:checkBox name ="outputDevice" value="${params['outputDevice']}" />
+			<erptr:helpLink for="outputDevice"/>
+			
+			<br />
+			
 			<label for="description">Short decription</label>
 			<g:textArea name="description">${params['description']}</g:textArea>
 					
Index: hci/trunk/eneraptor-web-app/grails-app/views/logicRequest/updateMeasurements.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/logicRequest/updateMeasurements.gsp	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/views/logicRequest/updateMeasurements.gsp	(revision 6)
@@ -0,0 +1 @@
+${output}
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/sysState/measure.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/sysState/measure.gsp	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/views/sysState/measure.gsp	(revision 6)
@@ -0,0 +1,55 @@
+<html>
+
+<head>
+	<title>System State &raquo; Last measurements</title>
+	<meta name="layout" content="main" />
+</head>
+
+<body>
+
+	<erptr:box title="Last measurements">
+		<form id="measureForm" action="measureUpdate">
+			<table>
+				<thead>
+					<tr>
+						<th style="width:20px;">&nbsp;</th>
+						<th style="width:200px;">Device</th>
+						<th>Value</th>
+						<th style="width:200px;">Time measured</th>
+					</tr>
+				</thead>
+				<tbody>
+					<g:each in="${inDevicesData}" var="inDevice">
+						<tr>
+							<td>
+								&nbsp;<g:checkBox name="${inDevice.deviceId}" />
+							</td>
+							<td><p>
+							<g:if test="${inDevice.icon}">
+								<erptr:icon w="${inDevice.icon}" />&nbsp;
+							</g:if>
+							${inDevice.friendlyName}</p></td>
+							<td><p>${inDevice.loggedData?.reportedData ?: '<i>this device has not returned any value yet</i>'}</p></td>
+							<td><p>${inDevice.loggedData?.dateRecieved ?: '<i>never</i>'}</p></td>
+						</tr>
+					</g:each>
+				</tbody>
+			</table>
+			
+			<p><a href="#" onclick="checkToggle('measureForm');return false;">Check / uncheck</a> all.</p>
+			
+			<table style="border:0px;">
+				<tr>
+					<td style="width:25px;border:0px;"><g:submitButton name="measureFormSubmit" type="image" src="${resource(dir:'img/icons/',file:'arrow_refresh.png')}" onclick="\$('refreshLabel').innerHTML = 'Refreshing... Please wait.';" /></td>
+					<td style="border:0px;"><p id="refreshLabel" style="position:relative;top:-2px">Refresh selected devices' values manually</p></td>
+				</tr>
+			</table>
+			
+		</form>		
+	</erptr:box>
+	
+	<js:checkBoxToggle />
+
+</body>
+
+</html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/sysState/main.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/sysState/main.gsp	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/views/sysState/main.gsp	(revision 6)
@@ -6,7 +6,69 @@
 </head>
 
 <body>
-	<p>Deluje!</p>
+	
+	<erptr:box title="Welcome">
+		<p>Welcome to Eneraptor's administration web application (HCI)!</p>
+	</erptr:box>
+
+	<erptr:box title="Last measurements overview">
+		<table>
+			<thead>
+				<tr>
+					<th style="width:200px;">Device</th>
+					<th>Value</th>
+					<th style="width:200px;">Time measured</th>
+				</tr>
+			</thead>
+			<tbody>
+				<g:each in="${inDevicesData}" var="inDevice">
+					<tr>
+						<td><p>
+						<g:if test="${inDevice.icon}">
+							<erptr:icon w="${inDevice.icon}" />&nbsp;
+						</g:if>
+						${inDevice.friendlyName}</p></td>
+						<td><p>${inDevice.loggedData?.reportedData ?: '<i>this device has not returned any value yet</i>'}</p></td>
+						<td><p>${inDevice.loggedData?.dateRecieved ?: '<i>never</i>'}</p></td>
+					</tr>
+				</g:each>
+			</tbody>
+		</table>
+		<br />
+		
+		<g:link action="measure"><erptr:icon w="monitor" />&nbsp;View details and options</g:link>
+
+	</erptr:box>
+
+	<erptr:box title="Last actions taken overview">
+		<table>
+			<thead>
+				<tr>
+					<th style="width:200px;">Device</th>
+					<th>Action taken</th>
+					<th style="width:200px;">Time executed</th>
+				</tr>
+			</thead>
+			<tbody>
+				<g:each in="${outDevicesData}" var="outDevice">
+					<tr>
+						<td><p>
+						<g:if test="${outDevice.icon}">
+							<erptr:icon w="${outDevice.icon}" />&nbsp;
+						</g:if>
+						${outDevice.friendlyName}</p></td>
+						<td><p>${outDevice.loggedData?.reportedData ?: '<i>no actions have been executed on this device yet</i>'}</p></td>
+						<td><p>${outDevice.loggedData?.dateRecieved ?: '<i>never</i>'}</p></td>
+					</tr>
+				</g:each>
+			</tbody>
+		</table>
+		<br />
+		
+		<g:link action="actions"><erptr:icon w="lightning" />&nbsp;View details and options</g:link>
+		
+	</erptr:box>
+
 </body>
 
 </html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/sysState/measureUpdate.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/sysState/measureUpdate.gsp	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/views/sysState/measureUpdate.gsp	(revision 6)
@@ -0,0 +1,23 @@
+<!-- This page gets rendered only if there were errors  -->
+<html>
+
+<head>
+	<title>System State &raquo; Error updating measurements manually</title>
+	<meta name="layout" content="main" />
+</head>
+
+<body>
+
+	<erptr:box title="Updating measurements manually failed">
+		
+		<p>Unfortunately, there were some errors while trying to send the request to the logic unit. You can check the output below.</p>
+		<p>Please try sending the request again. If sending fails again, check <g:link controller="config" action="connection">HCI to Logic connection settings</g:link>.</p>
+		<br />
+		
+		<div>${errorExplanation}</div>
+		
+	</erptr:box>
+
+</body>
+
+</html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/sysState/actions.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/sysState/actions.gsp	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/views/sysState/actions.gsp	(revision 6)
@@ -0,0 +1,48 @@
+<html>
+
+<head>
+	<title>System State &raquo; Last actions taken</title>
+	<meta name="layout" content="main" />
+</head>
+
+<body>
+
+	<erptr:box title="Last actions taken">
+		<form id="actionsForm">
+			<table>
+				<thead>
+					<tr>
+						<th style="width:20px;">&nbsp;</th>
+						<th style="width:200px;">Device</th>
+						<th>Action taken</th>
+						<th style="width:200px;">Time executed</th>
+					</tr>
+				</thead>
+				<tbody>
+					<g:each in="${outDevicesData}" var="outDevice">
+						<tr>
+							<td>
+								&nbsp;<g:checkBox name="${outDevice.deviceId}" />
+							</td>
+							<td><p>
+							<g:if test="${outDevice.icon}">
+								<erptr:icon w="${outDevice.icon}" />&nbsp;
+							</g:if>
+							${outDevice.friendlyName}</p></td>
+							<td><p>${outDevice.loggedData?.reportedData ?: '<i>no actions have been executed on this device yet</i>'}</p></td>
+							<td><p>${outDevice.loggedData?.dateRecieved ?: '<i>never</i>'}</p></td>
+						</tr>
+					</g:each>
+				</tbody>
+			</table>
+
+			<p><a href="#" onclick="checkToggle('actionsForm');return false;">Check / uncheck</a> all.</p>
+
+		</form>
+	</erptr:box>
+	
+	<js:checkBoxToggle />
+
+</body>
+
+</html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/layouts/main.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/layouts/main.gsp	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/views/layouts/main.gsp	(revision 6)
@@ -25,7 +25,7 @@
    			<div id="top-panel">
        			<div id="panel">
            			<ul>
-              			<erptr:subMenu menu="${controllerName}" />
+              			<erptr:subMenu menu="${controllerName}" chosen="${actionName}" />
            			</ul>
        			</div><!-- /panel -->
  			</div><!-- /top-pannel -->
@@ -43,6 +43,11 @@
 						${flash.confirms}
 					</erptr:confirmBox>
 				</g:if>
+				<g:if test="${flash.warnings}">
+					<erptr:warningBox>
+						${flash.warnings}
+					</erptr:warningBox>
+				</g:if>
        			<g:layoutBody />
        		</div><!-- /content -->
  		</div><!-- /wrapper -->
@@ -65,6 +70,9 @@
 		<g:if test="${flash.errors}">
 			new Effect.Shake('errorBox', {duration: 0.2, distance: 5})	
 		</g:if>
+		<g:if test="${flash.warnings}">
+			new Effect.Pulsate('warningBox',{pulses:2, duration: 0.2, from: 0.5})
+		</g:if>
 	}
 	</g:javascript>
 	
Index: hci/trunk/eneraptor-web-app/grails-app/views/sysLog/browse.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/sysLog/browse.gsp	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/views/sysLog/browse.gsp	(revision 6)
@@ -24,7 +24,17 @@
 					<tr>
 						<td class="a-center">${entry.id}</td>
 						<td><a href="#">${entry.dateRecieved}</a></td>
-						<td><a href="#">${entry.deviceId}</a></td>
+						<td><a href="#">
+							<g:if test="${icons[entry.deviceId]}">
+								<erptr:icon w="${icons[entry.deviceId]}" />
+							</g:if>
+							<g:if test="${devices[entry.deviceId]}">
+								${devices[entry.deviceId]}
+							</g:if>
+							<g:else>
+								${entry.deviceId}
+							</g:else>
+						</a></td>
 						<td>${entry.reportedData}</td>
 						<td><erptr:logEntryOptions for="${entry.id}" /></td>
 					</tr>
Index: hci/trunk/eneraptor-web-app/grails-app/views/sysLog/detail.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/sysLog/detail.gsp	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/views/sysLog/detail.gsp	(revision 6)
@@ -0,0 +1,32 @@
+<html>
+
+<head>
+	<title>Log &raquo; Log entry details</title>
+	<meta name="layout" content="main" />
+</head>
+
+<body>
+	
+	<erptr:box title="Details for log entry ${params.id}">
+	
+		<div>Id:</div>
+		<erptr:rawInfoBox>${params.id}</erptr:rawInfoBox>
+		<br />
+		
+		<div>Entered on:</div>
+		<erptr:rawInfoBox>${dateRecieved}</erptr:rawInfoBox>
+		<br />
+		
+		<div>Device id:</div>
+		<erptr:rawInfoBox>${deviceId}</erptr:rawInfoBox>
+		<br />
+		
+		<div>Data:</div>
+		<erptr:rawInfoBox><pre>${reportedData}</pre></erptr:rawInfoBox>
+		<br />
+		
+	</erptr:box>
+	
+</body>
+
+</html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/sysLog/main.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/sysLog/main.gsp	(revision 5)
+++ hci/trunk/eneraptor-web-app/grails-app/views/sysLog/main.gsp	(revision 6)
@@ -6,7 +6,15 @@
 </head>
 
 <body>
-	<p>Deluje!</p>
+	
+	<erptr:box title="Log">
+		<p>TODO: Some information about log.</p>
+	</erptr:box>
+	
+	<erptr:box title="Disk usage">
+		<p>TODO: Some information about log.</p>
+	</erptr:box>
+
 </body>
 
 </html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/ErptrJSTagLibTests.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/ErptrJSTagLibTests.groovy	(revision 0)
+++ hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/ErptrJSTagLibTests.groovy	(revision 6)
@@ -0,0 +1,17 @@
+package com.eneraptor.hci
+
+import grails.test.*
+
+class ErptrJSTagLibTests extends TagLibUnitTestCase {
+    protected void setUp() {
+        super.setUp()
+    }
+
+    protected void tearDown() {
+        super.tearDown()
+    }
+
+    void testSomething() {
+
+    }
+}
Index: hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/HciLogicCommServiceTests.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/HciLogicCommServiceTests.groovy	(revision 0)
+++ hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/HciLogicCommServiceTests.groovy	(revision 6)
@@ -0,0 +1,17 @@
+package com.eneraptor.hci
+
+import grails.test.*
+
+class HciLogicCommServiceTests extends GrailsUnitTestCase {
+    protected void setUp() {
+        super.setUp()
+    }
+
+    protected void tearDown() {
+        super.tearDown()
+    }
+
+    void testSomething() {
+
+    }
+}
