InitLibTopoARTScripts <- function() {
	
	# Required by S4 (usually available)
	library(methods)

#--------------------------------------------------------------------------------------------------
# Neural network reading
#--------------------------------------------------------------------------------------------------

	setClass("TopoARTNode",
		representation(
			nodeID				=	"numeric",
			clusterID 			=	"numeric",
			inputLen			=	"numeric",
			representedInputs	=	"numeric",
			activation			=	"numeric",
			matchValue			=	"numeric",
			classID				=	"numeric",
			edgeNum				=	"numeric",
			edgeTargets			=	"vector",
			weights				=	"vector",
			temporalMatchValue	=	"numeric",
			combinedMatchValue	=	"numeric",
			temporalWeights		=	"vector"
		),
		prototype(
			nodeID				=	-1,
			clusterID			=	-1,
			inputLen			=	-1,
			representedInputs	=	-1,
			activation			=	-1,
			matchValue			=	-1,
			classID				=	-1,
			edgeNum				=	-1,
			edgeTargets 		=	vector(mode = "list", length = 0),
			weights				=	vector(mode = "list", length = 0),
			temporalMatchValue	=	-1,
			combinedMatchValue	=	-1,
			temporalWeights		=	vector(mode = "list", length = 0)
		)
	)

	setMethod("initialize", "TopoARTNode", function(.Object, srcFile, nodeIndex, networkType)
	{
		f <- srcFile
		readLines(f, n = 1)

		.Object@nodeID				<-	ReadNumeric(f, "node ID: %i");
		.Object@clusterID			<-	ReadNumeric(f, "cluster ID: %i");
		.Object@inputLen			<-	ReadNumeric(f, "input length: %i");
		.Object@representedInputs	<-	ReadNumeric(f, "represented inputs: %i");
		.Object@activation			<-	ReadNumeric(f, "activation: %f");
		.Object@matchValue			<-	ReadNumeric(f, "match value: %f");

		# Read class IDs (HTAC node, TAC node) 
		if(bitwAnd(networkType, 2) != 0) {
			.Object@classID	<-	ReadNumeric(f, "class ID: %i");
		}

		readLines(f, n = 1)
		.Object@edgeNum <- ReadNumeric(f, "edge number: %i");
		.Object@edgeTargets <- vector(mode = "numeric", length = .Object@edgeNum)
		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		for(i in seq_len(.Object@edgeNum))
			.Object@edgeTargets[i] <- subStrings[[1]][i + 2]

		l <- readLines(f, n = 1)

		.Object@weights <- vector(mode = "numeric", length = .Object@inputLen)
		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		for(i in seq_len(.Object@inputLen))
			.Object@weights[i] <- as.numeric(subStrings[[1]][i])

		# Read temporal information (ETA node)
		if(bitwAnd(networkType, 1) != 0) {
			readLines(f, n = 1)

			.Object@temporalMatchValue	<-	ReadNumeric(f, "temporal match value: %f");
			.Object@combinedMatchValue	<-	ReadNumeric(f, "combined match value: %f");

			readLines(f, n = 1)
			.Object@temporalWeights <- vector(mode = "numeric", length = 2)
			l <- readLines(f, n = 1)
			substrings <- strsplit(l, split = " ")
			.Object@temporalWeights[1] <- as.numeric(substrings[[1]][1])
			.Object@temporalWeights[2] <- as.numeric(substrings[[1]][2])
		} 

		.Object
	})

#--------------------------------------------------------------------------------------------------

	setClass("TopoARTModule",
		representation(
			t_F1			=	"vector",
			x_F1_len		=	"numeric",
			x_F1			=	"vector",
			rho				=	"numeric",
			nextID			=	"numeric",
			validClusterIDs	=	"logical",
			clusterNum		=	"numeric",
			learningCycles	=	"numeric",
			nodeNum			=	"numeric",
			nodes			=	"vector",
			minClassID		=	"numeric",
			maxClassID		=	"numeric"
		),
		prototype(
			t_F1			=	vector(mode = "numeric", length = 0),
			x_F1_len		=	-1,
			x_F1			=	vector(mode = "numeric", length = 0),
			rho				=	-1,
			nextID			=	-1,
			validClusterIDs	=	FALSE,
			clusterNum		=	-1,
			learningCycles	=	-1,
			nodeNum			=	-1,
			nodes			=	vector(mode = "list", length = 0),
			minClassID		=	-1,
			maxClassID		=	-1
		)
	)

	setMethod("initialize", "TopoARTModule", function(.Object, typeName, srcFile, moduleIndex, networkType = 0)
	{
		letters <- c("a", "b", "c", "d", "e")
		tmpString <- sprintf("Load %s module %s", typeName, letters[moduleIndex])
		print(tmpString)

		f <- srcFile
		readLines(f, n = 3)

		# ETA module
		if(networkType == 1) {
			.Object@t_F1 <- vector(mode = "numeric", length = 2)
			l <- readLines(f, n = 1)
			substrings <- strsplit(l, split = " ")
			num_string <- substrings[[1]][2]
			.Object@t_F1[1] <- as.numeric(num_string)
			num_string <- substrings[[1]][3]
			.Object@t_F1[2] <- as.numeric(num_string)
		}

		.Object@x_F1_len <- ReadNumeric(f, "x^F1 length: %i");

		.Object@x_F1 <- vector(mode = "numeric", length = .Object@x_F1_len)
		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		for(i in seq_len(.Object@x_F1_len))
			.Object@x_F1[i] <- subStrings[[1]][i + 1]

		.Object@rho		<-	ReadNumeric(f, "rho: %f");
		.Object@nextID	<-	ReadNumeric(f, "next ID: %i");

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		logicalString <- subStrings[[1]][4]
		.Object@validClusterIDs <- (logicalString == "true")
		if(.Object@validClusterIDs) {
			tmpString2 <- "TRUE"
		} else {
			tmpString2 <- "FALSE"
		}

		.Object@clusterNum		<-	ReadNumeric(f, "cluster number: %i");
		.Object@learningCycles	<-	ReadNumeric(f, "learning cycles: %i");
		.Object@nodeNum			<-	ReadNumeric(f, "node number: %i");	

		# Set initial min/max class IDs (HTAC node, TAC node) 
		if(bitwAnd(networkType, 2) != 0) {
			.Object@minClassID <- .Machine$integer.max
			.Object@maxClassID <- -.Machine$integer.max - 1
		}

		.Object@nodes <- vector(mode = "list", length = 0)	
		for(i in seq_len(.Object@nodeNum)) {
			.Object@nodes[[i]] <- new("TopoARTNode", f, i, networkType)

			# Compute min/max class IDs (HTAC node, TAC node) 
			if(bitwAnd(networkType, 2) != 0) {
				.Object@minClassID	<-	min(.Object@nodes[[i]]@classID, .Object@minClassID)
				.Object@maxClassID	<-	max(.Object@nodes[[i]]@classID, .Object@maxClassID)
			}
		}

		.Object
	})

#--------------------------------------------------------------------------------------------------

	setClass("TopoART", 
		representation(
			LibTopoART_version	=	"numeric",
			taFileFormatVersion	=	"numeric",
			x_F0_len			=	"numeric",
			x_F0				=	"vector",
			rho_a				=	"numeric",
			beta_sbm			=	"numeric",
			tau					=	"numeric",
			phi					=	"numeric",
			phis				=	"vector",
			learningSteps		=	"numeric",
			alpha				=	"numeric",
			moduleNum			=	"numeric",
			modules				=	"vector"
		), 
		prototype(
			LibTopoART_version	=	-1,
			taFileFormatVersion	=	-1,
			x_F0_len			=	-1,
			x_F0				=	vector(mode = "numeric", length = 0),
			rho_a				=	-1,
			beta_sbm			=	-1,
			tau					=	-1,
			phi					=	-1,
			phis				=	vector(mode = "numeric", length = 0),
			learningSteps		=	-1,
			alpha				=	-1,
			moduleNum			=	-1,
			modules				=	vector(mode = "list", length = 0)
		)
	)

	setMethod("initialize", "TopoART", function(.Object, path)
	{
		tmpString <- sprintf("Load TopoART network: %s", path)
		print(tmpString)

		f <- file(path, "r")
		readLines(f, n = 1)
		l <- readLines(f, n = 1)
		if(!(l == "*        TopoART network        *")) {
			warning("No TopoART text file")
			close(f)
			return(.Object)
		}

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = "v")
		versionString <- substr(subStrings[[1]][2], 1, 4)
		.Object@LibTopoART_version <- as.numeric(versionString)
		tmpString <- sprintf("LibTopoART v%.2f", .Object@LibTopoART_version)
		print(tmpString)
		readLines(f, n = 1)

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		versionString <- substr(subStrings[[1]][4], 1, 4)
		.Object@taFileFormatVersion <- as.numeric(versionString)
		if((.Object@taFileFormatVersion != 0.10) & (.Object@taFileFormatVersion != 0.11) & (.Object@taFileFormatVersion != 1.00)) {
			warning("File format version not supported")
			close(f)
			return(.Object)
		}

		readLines(f, n = 3)

		.Object@x_F0_len <- ReadNumeric(f, "x^F0 length: %i")

		.Object@x_F0 <- vector(mode = "numeric", length = .Object@x_F0_len)
		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		for(i in seq_len(.Object@x_F0_len))
			.Object@x_F0[i] <- subStrings[[1]][i + 1]

		.Object@rho_a			<-	ReadNumeric(f, "rho_a: %f");
		.Object@beta_sbm		<-	ReadNumeric(f, "beta_sbm: %f");
		.Object@tau				<-	ReadNumeric(f, "tau: %i");
		.Object@phi				<-	ReadNumeric(f, "phi: %i");
		.Object@learningSteps	<-	ReadNumeric(f, "learning steps: %i");
		.Object@alpha			<-	ReadNumeric(f, "alpha: %f");

		if(.Object@taFileFormatVersion >= 1.00) {
			readLines(f, n = 1)
		}

		.Object@moduleNum		<-	ReadNumeric(f, "module number: %i");

		.Object@phis <- vector(mode = "numeric", length = .Object@moduleNum)
		if(.Object@phi != -1) {
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- .Object@phi
		} else {
			l <- readLines(f, n = 1)
			subStrings <- strsplit(l, split = " ")
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- as.numeric(subStrings[[1]][i + 1])
		}

		.Object@modules <- vector(mode = "list", length = 0)	
		for(i in seq_len(.Object@moduleNum))
			.Object@modules[[i]] <- new("TopoARTModule", "TopoART", f, i)

		close(f)

		.Object
	})

	setGeneric("SaveNetworkPlot", function(this) standardGeneric("SaveNetworkPlot"))
	setMethod("SaveNetworkPlot", "TopoART", function(this)
	{
		if(this@x_F0_len != 2) {
			warning("Incompatible input length")
		} else {
			colorShift <- 4
			maxClusterNum <- max(this@modules[[this@moduleNum]]@clusterNum, 2)
			letters <- c("a", "b", "c", "d", "e")
			
			for(m in seq_len(this@moduleNum)) {
				tmpString <- sprintf("images/TA_%s.pdf", letters[m])
				pdf(file = tmpString)
				palette(rainbow(maxClusterNum))
				par(cex.axis = 1.5, cex.main = 1.6)
				plot(NULL, NULL, xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "")
				grid()

				phiSubscript <- ifelse(this@phi != -1, "", paste("_", letters[m], sep=""))

				moduleString <- sprintf("TA %s:", letters[m])
				rhoString <- sprintf("%.2f", this@modules[[m]]@rho)
				betaSbmString <- sprintf("%.2f", this@beta_sbm)
				phiSubscript <- ifelse(this@phi != -1, "", letters[m])
				titleString <- bquote(.(moduleString)~rho[.(letters[m])]~"="~.(rhoString)*","~beta[sbm]~"="~.(betaSbmString)*","~phi[.(phiSubscript)]~"="~.(this@phis[m])*","~tau~"="~.(this@tau))
				title(main = titleString, font.main = 2)

				for(n in seq_len(this@modules[[m]]@nodeNum)) {
					if(this@modules[[m]]@nodes[[n]]@clusterID > 0) {
						PlotTAWeights(this@modules[[m]]@nodes[[n]]@weights, (this@modules[[m]]@nodes[[n]]@clusterID - 1 + colorShift) %% maxClusterNum + 1)
					}
				}

				dev.off()
			}
		}
	})	

#--------------------------------------------------------------------------------------------------

	setClass("EpisodicTopoART", 
		representation(
			fileFormatVersion	=	"numeric",
			t_F0				=	"numeric",
			t_max				=	"numeric"
		), 
		prototype(
			fileFormatVersion	=	-1,
			t_F0				=	-1,
			t_max				=	-1
		),
		contains = "TopoART"
	)

	setMethod("initialize", "EpisodicTopoART", function(.Object, path)
	{
		tmpString <- sprintf("Load Episodic TopoaART network: %s", path)
		print(tmpString)
		
		f <- file(path, "r")
		readLines(f, n = 1)
		l <- readLines(f, n = 1)
		if(!(l == "*   Episodic TopoART network    *")) {
			warning("No Episodic TopoART text file")
			close(f)
			return(.Object)
		}

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = "v")
		versionString <- substr(subStrings[[1]][2], 1, 4)
		.Object@LibTopoART_version <- as.numeric(versionString)
		tmpString <- sprintf("LibTopoART v%.2f", .Object@LibTopoART_version)
		print(tmpString)
		l <- readLines(f, n = 1)

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		versionString <- substr(subStrings[[1]][4], 1, 4)
		.Object@fileFormatVersion <- as.numeric(versionString)
		versionString <- substr(subStrings[[1]][5], 1, 4)
		.Object@taFileFormatVersion <- as.numeric(versionString)
		if(((.Object@fileFormatVersion != 0.02) & (.Object@fileFormatVersion != 1.00)) | ((.Object@taFileFormatVersion != 0.10) & (.Object@taFileFormatVersion != 0.11) & (.Object@taFileFormatVersion != 1.00))) {
			warning("File format version not supported")
			close(f)
			return(.Object)
		}

		readLines(f, n = 3)

		.Object@t_F0	<-	ReadNumeric(f, "t^F0: %i");	
		.Object@t_max	<-	ReadNumeric(f, "t^max: %i");	

		readLines(f, n = 1)

		.Object@x_F0_len <- ReadNumeric(f, "x^F0 length: %i")

		.Object@x_F0 <- vector(mode = "numeric", length = .Object@x_F0_len)
		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		for(i in seq_len(.Object@x_F0_len))
			.Object@x_F0[i] <- subStrings[[1]][i + 1]

		.Object@rho_a			<-	ReadNumeric(f, "rho_a: %f");
		.Object@beta_sbm		<-	ReadNumeric(f, "beta_sbm: %f");
		.Object@tau				<-	ReadNumeric(f, "tau: %i");
		.Object@phi				<-	ReadNumeric(f, "phi: %i");
		.Object@learningSteps	<-	ReadNumeric(f, "learning steps: %i");
		.Object@alpha			<-	ReadNumeric(f, "alpha: %f");

		if(.Object@taFileFormatVersion >= 1.00) {
			readLines(f, n = 1)
		}

		.Object@moduleNum		<-	ReadNumeric(f, "module number: %i");

		.Object@phis <- vector(mode = "numeric", length = .Object@moduleNum)
		if(.Object@phi != -1) {
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- .Object@phi
		} else {
			l <- readLines(f, n = 1)
			subStrings <- strsplit(l, split = " ")
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- as.numeric(subStrings[[1]][i + 1])
		}

		.Object@modules <- vector(mode = "list", length = 0)	
		for(i in seq_len(.Object@moduleNum))
			.Object@modules[[i]] <- new("TopoARTModule", "Episodic TopoART", f, i, 1)

		close(f)

		.Object
	})

	setMethod("SaveNetworkPlot", "EpisodicTopoART", function(this)
	{
		if(this@x_F0_len != 2) {
			warning("Incompatible input length")
		} else {
			colorShift <- 4
			maxClusterNum <- max(this@modules[[this@moduleNum]]@clusterNum, 2)
			colors <- rainbow(maxClusterNum)
			colors[1] <- "#00A000FF"
			colors[2] <- "#ffff80FF"
			letters <- c("a", "b", "c", "d", "e")

			for(m in seq_len(this@moduleNum)) {
				tmpString <- sprintf("images/ETA_%s.pdf", letters[m])
				pdf(file = tmpString)
				palette(colors)
				par(cex.axis = 1.5, cex.main = 1.6)
				plot(NULL, NULL, xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "")
				grid()

				phiSubscript <- ifelse(this@phi != -1, "", paste("_", letters[m], sep=""))

				moduleString <- sprintf("ETA %s:", letters[m])
				rhoString <- sprintf("%.3f", this@modules[[m]]@rho)
				betaSbmString <- sprintf("%.2f", this@beta_sbm)
				phiSubscript <- ifelse(this@phi != -1, "", letters[m])
				titleString <- bquote(.(moduleString)~rho[.(letters[m])]~"="~.(rhoString)*","~beta[sbm]~"="~.(betaSbmString)*","~phi[.(phiSubscript)]~"="~.(this@phis[m])*","~tau~"="~.(this@tau)*","~t^max~"="~.(this@t_max))
				title(main = titleString, font.main = 2, adj = 0.75)

				for(n in seq_len(this@modules[[m]]@nodeNum)) {
					if(this@modules[[m]]@nodes[[n]]@clusterID > 0) {
						PlotTAWeights(this@modules[[m]]@nodes[[n]]@weights, (this@modules[[m]]@nodes[[n]]@clusterID - 1 + colorShift) %% maxClusterNum + 1)
					}
				}

				dev.off()
			}
		}
	})

#--------------------------------------------------------------------------------------------------

	setClass("HypersphereTopoART", 
		representation(
			fileFormatVersion	=	"numeric",
			R					=	"numeric"
		), 
		prototype(
			fileFormatVersion	=	-1,
			R					=	-1
		),
		contains = "TopoART"
	)

	setMethod("initialize", "HypersphereTopoART", function(.Object, path)
	{
		tmpString <- sprintf("Load Hypersphere TopoART network: %s", path)
		print(tmpString)

		f <- file(path, "r")
		readLines(f, n = 1)
		l <- readLines(f, n = 1)
		if(!(l == "*  Hypersphere TopoART network  *")) {
			warning("No Hypersphere TopoART text file")
			close(f)
			return(.Object)
		}

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = "v")
		versionString <- substr(subStrings[[1]][2], 1, 4)
		.Object@LibTopoART_version <- as.numeric(versionString)
		tmpString <- sprintf("LibTopoART v%.2f", .Object@LibTopoART_version)
		print(tmpString)
		readLines(f, n = 1)

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		versionString <- substr(subStrings[[1]][4], 1, 4)
		.Object@fileFormatVersion <- as.numeric(versionString)
		versionString <- substr(subStrings[[1]][5], 1, 4)
		.Object@taFileFormatVersion <- as.numeric(versionString)
		if(((.Object@fileFormatVersion != 0.01) & (.Object@fileFormatVersion != 1.00)) | ((.Object@taFileFormatVersion != 0.10) & (.Object@taFileFormatVersion != 0.11) & (.Object@taFileFormatVersion != 1.00))) {
			warning("File format version not supported")
			close(f)
			return(.Object)
		}

		readLines(f, n = 3)

		.Object@R <- ReadNumeric(f, "R: %f");

		readLines(f, n = 1)

		.Object@x_F0_len <- ReadNumeric(f, "x^F0 length: %i")

		.Object@x_F0 <- vector(mode = "numeric", length = .Object@x_F0_len)
		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		for(i in seq_len(.Object@x_F0_len))
			.Object@x_F0[i] <- subStrings[[1]][i + 1]

		.Object@rho_a			<-	ReadNumeric(f, "rho_a: %f");
		.Object@beta_sbm		<-	ReadNumeric(f, "beta_sbm: %f");
		.Object@tau				<-	ReadNumeric(f, "tau: %i");
		.Object@phi				<-	ReadNumeric(f, "phi: %i");
		.Object@learningSteps	<-	ReadNumeric(f, "learning steps: %i");
		.Object@alpha			<-	ReadNumeric(f, "alpha: %f");

		if(.Object@taFileFormatVersion >= 1.00) {
			readLines(f, n = 1)
		}

		.Object@moduleNum		<-	ReadNumeric(f, "module number: %i");

		.Object@phis <- vector(mode = "numeric", length = .Object@moduleNum)
		if(.Object@phi != -1) {
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- .Object@phi
		} else {
			l <- readLines(f, n = 1)
			subStrings <- strsplit(l, split = " ")
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- as.numeric(subStrings[[1]][i + 1])
		}

		.Object@modules <- vector(mode = "list", length = 0)	
		for(i in seq_len(.Object@moduleNum))
			.Object@modules[[i]] <- new("TopoARTModule", "Hypersphere TopoART", f, i)

		close(f)

		.Object
	})

	setMethod("SaveNetworkPlot", "HypersphereTopoART", function(this)
	{
		if(this@x_F0_len != 2) {
			warning("Incompatible input length")
		} else {
			library(plotrix)

			colorShift <- 4
			maxClusterNum <- max(this@modules[[this@moduleNum]]@clusterNum, 2)
			letters <- c("a", "b", "c", "d", "e")

			for(m in seq_len(this@moduleNum)) {
				tmpString <- sprintf("images/HTA_%s.pdf", letters[m])
				pdf(file = tmpString)
				palette(rainbow(maxClusterNum))
				par(cex.axis = 1.5, cex.main = 1.6)
				plot(NULL, NULL, xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "")
				grid()

				phiSubscript <- ifelse(this@phi != -1, "", paste("_", letters[m], sep=""))

				moduleString <- sprintf("HTA %s:", letters[m])
				rhoString <- sprintf("%.2f", this@modules[[m]]@rho)
				betaSbmString <- sprintf("%.2f", this@beta_sbm)
				rString <- sprintf("%.3f", this@R)
				phiSubscript <- ifelse(this@phi != -1, "", letters[m])
				titleString <- bquote(.(moduleString)~rho[.(letters[m])]~"="~.(rhoString)*","~beta[sbm]~"="~.(betaSbmString)*","~phi[.(phiSubscript)]~"="~.(this@phis[m])*","~tau~"="~.(this@tau)*","~bar(R)~"="~.(rString))
				title(main = titleString, font.main = 2, adj = 0.75)

				for(n in seq_len(this@modules[[m]]@nodeNum)) {
					if(this@modules[[m]]@nodes[[n]]@clusterID > 0) {
						PlotHTAWeights(this@modules[[m]]@nodes[[n]]@weights, (this@modules[[m]]@nodes[[n]]@clusterID - 1 + colorShift) %% maxClusterNum + 1)
					}
				}

				dev.off()
			}
		}
	})

#--------------------------------------------------------------------------------------------------

	setClass("TopoARTAM", 
		representation(
			fileFormatVersion	=	"numeric",
			key1Len				=	"numeric",
			key2Len				=	"numeric"
		), 
		prototype(
			fileFormatVersion	=	-1,
			key1Len				=	-1,
			key2Len				=	-1
		),
		contains = "TopoART"
	)

	setMethod("initialize", "TopoARTAM", function(.Object, path)
	{
		tmpString <- sprintf("Load TopoART-AM network: %s", path)
		print(tmpString)

		f <- file(path, "r")
		readLines(f, n = 1)
		l <- readLines(f, n = 1)
		if(!(l == "*      TopoART-AM network       *")) {
			warning("No TopoART-AM text file")
			close(f)
			return(.Object)
		}

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = "v")
		versionString <- substr(subStrings[[1]][2], 1, 4)
		.Object@LibTopoART_version <- as.numeric(versionString)
		tmpString <- sprintf("LibTopoART v%.2f", .Object@LibTopoART_version)
		print(tmpString)
		readLines(f, n = 1)

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		versionString <- substr(subStrings[[1]][4], 1, 4)
		.Object@fileFormatVersion <- as.numeric(versionString)
		versionString <- substr(subStrings[[1]][5], 1, 4)
		.Object@taFileFormatVersion <- as.numeric(versionString)
		if(((.Object@fileFormatVersion != 0.01) | ((.Object@taFileFormatVersion != 0.10) & (.Object@taFileFormatVersion != 0.11) & (.Object@taFileFormatVersion != 1.00))) & ((.Object@fileFormatVersion != 1.00) | (.Object@taFileFormatVersion != 1.00))) {
			warning("File format version not supported")
			close(f)
			return(.Object)
		}

		readLines(f, n = 3)

		if(.Object@fileFormatVersion < 1.00) {
			.Object@key1Len <- ReadNumeric(f, "key_1 length: %i");
			.Object@key2Len <- ReadNumeric(f, "key_2 length: %i");
		} else {
			.Object@key1Len <- ReadNumeric(f, "key 1 length: %i");
			.Object@key2Len <- ReadNumeric(f, "key 2 length: %i");
		}

		readLines(f, n = 1)

		.Object@x_F0_len <- ReadNumeric(f, "x^F0 length: %i")

		if(.Object@key1Len + .Object@key2Len != .Object@x_F0_len) {
			warning("Input length mismatch")
			close(f)
			return(.Object)
		}

		.Object@x_F0 <- vector(mode = "numeric", length = .Object@x_F0_len)
		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		for(i in seq_len(.Object@x_F0_len))
			.Object@x_F0[i] <- subStrings[[1]][i + 1]

		.Object@rho_a			<-	ReadNumeric(f, "rho_a: %f");
		.Object@beta_sbm		<-	ReadNumeric(f, "beta_sbm: %f");
		.Object@tau				<-	ReadNumeric(f, "tau: %i");
		.Object@phi				<-	ReadNumeric(f, "phi: %i");
		.Object@learningSteps	<-	ReadNumeric(f, "learning steps: %i");
		.Object@alpha			<-	ReadNumeric(f, "alpha: %f");

		if(.Object@taFileFormatVersion >= 1.00) {
			readLines(f, n = 1)
		}

		.Object@moduleNum		<-	ReadNumeric(f, "module number: %i");

		.Object@phis <- vector(mode = "numeric", length = .Object@moduleNum)
		if(.Object@phi != -1) {
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- .Object@phi
		} else {
			l <- readLines(f, n = 1)
			subStrings <- strsplit(l, split = " ")
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- as.numeric(subStrings[[1]][i + 1])
		}

		.Object@modules <- vector(mode = "list", length = 0)	
		for(i in seq_len(.Object@moduleNum))
			.Object@modules[[i]] <- new("TopoARTModule", "TopoART-AM", f, i)

		close(f)

		.Object
	})
	
	setGeneric("SaveNetworkPlotKey1", function(this) standardGeneric("SaveNetworkPlotKey1"))
	setMethod("SaveNetworkPlotKey1", "TopoARTAM", function(this)
	{
		if((this@key1Len != 2) || (this@key2Len != 2)) {
			warning("Incompatible input length")
		} else {
			colorShift <- 4
			maxClusterNum <- max(this@modules[[this@moduleNum]]@clusterNum, 2)
			colors <- rainbow(maxClusterNum)
			colors[1] <- "#00A000FF"
			colors[2] <- "#ffff80FF"
			letters <- c("a", "b", "c", "d", "e")

			for(m in seq_len(this@moduleNum)) {
				tmpString <- sprintf("images/TAM_%s_key1.pdf", letters[m])
				pdf(file = tmpString)
				palette(colors)
				par(cex.axis = 1.5, cex.main = 1.6)
				plot(NULL, NULL, xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "")
				grid()

				phiSubscript <- ifelse(this@phi != -1, "", paste("_", letters[m], sep=""))

				moduleString <- sprintf("TAM %s (key 1):", letters[m])
				rhoString <- sprintf("%.3f", this@modules[[m]]@rho)
				betaSbmString <- sprintf("%.2f", this@beta_sbm)
				phiSubscript <- ifelse(this@phi != -1, "", letters[m])
				titleString <- bquote(.(moduleString)~rho[.(letters[m])]~"="~.(rhoString)*","~beta[sbm]~"="~.(betaSbmString)*","~phi[.(phiSubscript)]~"="~.(this@phis[m])*","~tau~"="~.(this@tau))
				title(main = titleString, font.main = 2, adj = 0.75)

				for(n in seq_len(this@modules[[m]]@nodeNum)) {
					if(this@modules[[m]]@nodes[[n]]@clusterID > 0) {
						PlotTAWeights(this@modules[[m]]@nodes[[n]]@weights, (this@modules[[m]]@nodes[[n]]@clusterID - 1 + colorShift) %% maxClusterNum + 1, 0, this@key2Len)
					}
				}

				dev.off()
			}
		}
	})

	setGeneric("SaveNetworkPlotKey2", function(this) standardGeneric("SaveNetworkPlotKey2"))
	setMethod("SaveNetworkPlotKey2", "TopoARTAM", function(this)
	{
		if((this@key1Len != 2) || (this@key2Len != 2)) {
			warning("Incompatible input length")
		} else {
			colorShift <- 4
			maxClusterNum <- max(this@modules[[this@moduleNum]]@clusterNum, 2)
			colors <- rainbow(maxClusterNum)
			colors[1] <- "#00A000FF"
			colors[2] <- "#ffff80FF"
			letters <- c("a", "b", "c", "d", "e")

			for(m in seq_len(this@moduleNum)) {
				tmpString <- sprintf("images/TAM_%s_key2.pdf", letters[m])
				pdf(file = tmpString)
				palette(colors)
				par(cex.axis = 1.5, cex.main = 1.6)
				plot(NULL, NULL, xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "")
				grid()

				phiSubscript <- ifelse(this@phi != -1, "", paste("_", letters[m], sep=""))

				moduleString <- sprintf("TAM %s (key 2):", letters[m])
				rhoString <- sprintf("%.3f", this@modules[[m]]@rho)
				betaSbmString <- sprintf("%.2f", this@beta_sbm)
				phiSubscript <- ifelse(this@phi != -1, "", letters[m])
				titleString <- bquote(.(moduleString)~rho[.(letters[m])]~"="~.(rhoString)*","~beta[sbm]~"="~.(betaSbmString)*","~phi[.(phiSubscript)]~"="~.(this@phis[m])*","~tau~"="~.(this@tau))
				title(main = titleString, font.main = 2, adj = 0.75)

				for(n in seq_len(this@modules[[m]]@nodeNum)) {
					if(this@modules[[m]]@nodes[[n]]@clusterID > 0) {
						PlotTAWeights(this@modules[[m]]@nodes[[n]]@weights, (this@modules[[m]]@nodes[[n]]@clusterID - 1 + colorShift) %% maxClusterNum + 1, this@key1Len)
					}
				}

				dev.off()
			}
		}
	})	

#--------------------------------------------------------------------------------------------------

	setClass("TopoARTC", 
		representation(
			fileFormatVersion	=	"numeric",
			nu					=	"numeric"
		), 
		prototype(
			fileFormatVersion	=	-1,
			nu					=	-1
		),
		contains = "TopoART"
	)

	setMethod("initialize", "TopoARTC", function(.Object, path)
	{
		tmpString <- sprintf("Load TopoART-C network: %s", path)
		print(tmpString)

		f <- file(path, "r")
		readLines(f, n = 1)
		l <- readLines(f, n = 1)
		if(!(l == "*       TopoART-C network       *")) {
			warning("No TopoART-C text file")
			close(f)
			return(.Object)
		}

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = "v")
		versionString <- substr(subStrings[[1]][2], 1, 4)
		.Object@LibTopoART_version <- as.numeric(versionString)
		tmpString <- sprintf("LibTopoART v%.2f", .Object@LibTopoART_version)
		print(tmpString)
		l <- readLines(f, n = 1)

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		versionString <- substr(subStrings[[1]][4], 1, 4)
		.Object@fileFormatVersion <- as.numeric(versionString)
		versionString <- substr(subStrings[[1]][5], 1, 4)
		.Object@taFileFormatVersion <- as.numeric(versionString)
		if(((.Object@fileFormatVersion != 0.01) & (.Object@fileFormatVersion != 1.00)) | ((.Object@taFileFormatVersion != 0.10) & (.Object@taFileFormatVersion != 0.11) & (.Object@taFileFormatVersion != 1.00))) {
			warning("File format version not supported")
			close(f)
			return(.Object)
		}

		readLines(f, n = 3)

		if(.Object@fileFormatVersion >= 1.00) {
			.Object@nu <- ReadNumeric(f, "nu: %i")
			readLines(f, n = 1)
		}

		.Object@x_F0_len <- ReadNumeric(f, "x^F0 length: %i")

		.Object@x_F0 <- vector(mode = "numeric", length = .Object@x_F0_len)
		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		for(i in seq_len(.Object@x_F0_len))
			.Object@x_F0[i] <- subStrings[[1]][i + 1]

		.Object@rho_a			<-	ReadNumeric(f, "rho_a: %f");
		.Object@beta_sbm		<-	ReadNumeric(f, "beta_sbm: %f");
		.Object@tau				<-	ReadNumeric(f, "tau: %i");
		.Object@phi				<-	ReadNumeric(f, "phi: %i");
		.Object@learningSteps	<-	ReadNumeric(f, "learning steps: %i");
		.Object@alpha			<-	ReadNumeric(f, "alpha: %f");

		if(.Object@taFileFormatVersion >= 1.00) {
			readLines(f, n = 1)
		}

		.Object@moduleNum		<-	ReadNumeric(f, "module number: %i");

		.Object@phis <- vector(mode = "numeric", length = .Object@moduleNum)
		if(.Object@phi != -1) {
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- .Object@phi
		} else {
			l <- readLines(f, n = 1)
			subStrings <- strsplit(l, split = " ")
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- as.numeric(subStrings[[1]][i + 1])
		}

		.Object@modules <- vector(mode = "list", length = 0)	
		for(i in seq_len(.Object@moduleNum))
			.Object@modules[[i]] <- new("TopoARTModule", "TopoART-C", f, i, 2)

		close(f)

		.Object
	})

	setMethod("SaveNetworkPlot", "TopoARTC", function(this)
	{
		if(this@x_F0_len != 2) {
			warning("Incompatible input length")
		} else {
			colorShift <- 4
			maxClusterNum <- max(this@modules[[this@moduleNum]]@clusterNum, 2)
			letters <- c("a", "b", "c", "d", "e")

			minClassID <- .Machine$integer.max
			maxClassID <- -.Machine$integer.max - 1
			for(m in seq_len(this@moduleNum)) {
				minClassID <- min(this@modules[[m]]@minClassID, minClassID)
				maxClassID <- max(this@modules[[m]]@maxClassID, maxClassID)
			}

			for(m in seq_len(this@moduleNum)) {
				tmpString <- sprintf("images/TAC_%s.pdf", letters[m])
				pdf(file = tmpString)
				palette(rainbow(maxClusterNum))
				par(cex.axis = 1.5, cex.main = 1.6)
				plot(NULL, NULL, xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "")
				grid()

				phiSubscript <- ifelse(this@phi != -1, "", paste("_", letters[m], sep=""))

				moduleString <- sprintf("TAC %s:", letters[m])
				rhoString <- sprintf("%.2f", this@modules[[m]]@rho)
				betaSbmString <- sprintf("%.2f", this@beta_sbm)
				phiSubscript <- ifelse(this@phi != -1, "", letters[m])
				titleString <- bquote(.(moduleString)~rho[.(letters[m])]~"="~.(rhoString)*","~beta[sbm]~"="~.(betaSbmString)*","~phi[.(phiSubscript)]~"="~.(this@phis[m])*","~tau~"="~.(this@tau))
				title(main = titleString, font.main = 2)

				for(n in seq_len(this@modules[[m]]@nodeNum)) {
					if(this@modules[[m]]@nodes[[n]]@clusterID > 0) {
						PlotTAWeights(this@modules[[m]]@nodes[[n]]@weights, (this@modules[[m]]@nodes[[n]]@clusterID - 1 + colorShift) %% maxClusterNum + 1)
					}
				}

				dev.off()

				tmpString <- sprintf("images/TAC_%s_class_IDs.pdf", letters[m])
				pdf(file = tmpString)
				palette(rainbow(maxClassID + 1 - minClassID))
				par(cex.axis = 1.5, cex.main = 1.6)
				plot(NULL, NULL, xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "")
				grid()

				phiSubscript <- ifelse(this@phi != -1, "", paste("_", letters[m], sep=""))

				moduleString <- sprintf("TAC %s:", letters[m])
				rhoString <- sprintf("%.2f", this@modules[[m]]@rho)
				betaSbmString <- sprintf("%.2f", this@beta_sbm)
				phiSubscript <- ifelse(this@phi != -1, "", letters[m])
				titleString <- bquote(.(moduleString)~rho[.(letters[m])]~"="~.(rhoString)*","~beta[sbm]~"="~.(betaSbmString)*","~phi[.(phiSubscript)]~"="~.(this@phis[m])*","~tau~"="~.(this@tau))
				title(main = titleString, font.main = 2)

				for(n in seq_len(this@modules[[m]]@nodeNum)) {
					if(this@modules[[m]]@nodes[[n]]@clusterID > 0) {
						PlotTAWeights(this@modules[[m]]@nodes[[n]]@weights, (this@modules[[m]]@nodes[[n]]@classID - minClassID + colorShift) %% (maxClassID + 1 - minClassID) + 1)
					}
				}

				dev.off()
			}
		}
	})	

#--------------------------------------------------------------------------------------------------

	setClass("HypersphereTopoARTC", 
		representation(
			baseFileFormatVersion	=	"numeric",
			nu						=	"numeric"
		), 
		prototype(
			baseFileFormatVersion	=	-1,
			nu						=	-1
		),
		contains = "HypersphereTopoART"
	)

	setMethod("initialize", "HypersphereTopoARTC", function(.Object, path)
	{
		tmpString <- sprintf("Load Hypersphere TopoART-C network: %s", path)
		print(tmpString)

		f <- file(path, "r")
		readLines(f, n = 1)
		l <- readLines(f, n = 1)
		if(!(l == "* Hypersphere TopoART-C network *")) {
			warning("No Hypersphere TopoART-C text file")
			close(f)
			return(.Object)
		}

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = "v")
		versionString <- substr(subStrings[[1]][2], 1, 4)
		.Object@LibTopoART_version <- as.numeric(versionString)
		tmpString <- sprintf("LibTopoART v%.2f", .Object@LibTopoART_version)
		print(tmpString)
		readLines(f, n = 1)

		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		versionString <- substr(subStrings[[1]][4], 1, 4)
		.Object@fileFormatVersion <- as.numeric(versionString)
		versionString <- substr(subStrings[[1]][5], 1, 4)
		.Object@baseFileFormatVersion <- as.numeric(versionString)
		versionString <- substr(subStrings[[1]][6], 1, 4)
		.Object@taFileFormatVersion <- as.numeric(versionString)
		if(((.Object@fileFormatVersion != 0.01) & (.Object@fileFormatVersion != 1.00)) | ((.Object@baseFileFormatVersion != 0.01) & (.Object@baseFileFormatVersion != 1.00)) | ((.Object@taFileFormatVersion != 0.10) & (.Object@taFileFormatVersion != 0.11) & (.Object@taFileFormatVersion != 1.00))) {
			warning("File format version not supported")
			close(f)
			return(.Object)
		}

		readLines(f, n = 3)

		.Object@R <- ReadNumeric(f, "R: %f");

		readLines(f, n = 1)

		if(.Object@fileFormatVersion >= 1.00) {
			.Object@nu <- ReadNumeric(f, "nu: %i")
			readLines(f, n = 1)
		}

		.Object@x_F0_len <- ReadNumeric(f, "x^F0 length: %i")

		.Object@x_F0 <- vector(mode = "numeric", length = .Object@x_F0_len)
		l <- readLines(f, n = 1)
		subStrings <- strsplit(l, split = " ")
		for(i in seq_len(.Object@x_F0_len))
			.Object@x_F0[i] <- subStrings[[1]][i + 1]

		.Object@rho_a			<-	ReadNumeric(f, "rho_a: %f");
		.Object@beta_sbm		<-	ReadNumeric(f, "beta_sbm: %f");
		.Object@tau				<-	ReadNumeric(f, "tau: %i");
		.Object@phi				<-	ReadNumeric(f, "phi: %i");
		.Object@learningSteps	<-	ReadNumeric(f, "learning steps: %i");
		.Object@alpha			<-	ReadNumeric(f, "alpha: %f");

		if(.Object@taFileFormatVersion >= 1.00) {
			readLines(f, n = 1)
		}

		.Object@moduleNum		<-	ReadNumeric(f, "module number: %i");

		.Object@phis <- vector(mode = "numeric", length = .Object@moduleNum)
		if(.Object@phi != -1) {
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- .Object@phi
		} else {
			l <- readLines(f, n = 1)
			subStrings <- strsplit(l, split = " ")
			for(i in seq_len(.Object@moduleNum))
				.Object@phis[i] <- as.numeric(subStrings[[1]][i + 1])
		}

		.Object@modules <- vector(mode = "list", length = 0)	
		for(i in seq_len(.Object@moduleNum))
			.Object@modules[[i]] <- new("TopoARTModule", "Hypersphere TopoART-C", f, i, 2)

		close(f)

		.Object
	})

	setMethod("SaveNetworkPlot", "HypersphereTopoARTC", function(this)
	{
		if(this@x_F0_len != 2) {
			warning("Incompatible input length")
		} else {
			library(plotrix)

			colorShift <- 4
			maxClusterNum <- max(this@modules[[this@moduleNum]]@clusterNum, 2)
			letters <- c("a", "b", "c", "d", "e")

			minClassID <- .Machine$integer.max
			maxClassID <- -.Machine$integer.max - 1
			for(m in seq_len(this@moduleNum)) {
				minClassID <- min(this@modules[[m]]@minClassID, minClassID)
				maxClassID <- max(this@modules[[m]]@maxClassID, maxClassID)
			}

			for(m in seq_len(this@moduleNum)) {
				tmpString <- sprintf("images/HTAC_%s.pdf", letters[m])
				pdf(file = tmpString)
				palette(rainbow(maxClusterNum))
				par(cex.axis = 1.5, cex.main = 1.6)
				plot(NULL, NULL, xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "")
				grid()

				phiSubscript <- ifelse(this@phi != -1, "", paste("_", letters[m], sep=""))

				moduleString <- sprintf("HTAC %s:", letters[m])
				rhoString <- sprintf("%.2f", this@modules[[m]]@rho)
				betaSbmString <- sprintf("%.2f", this@beta_sbm)
				rString <- sprintf("%.3f", this@R)
				phiSubscript <- ifelse(this@phi != -1, "", letters[m])
				titleString <- bquote(.(moduleString)~rho[.(letters[m])]~"="~.(rhoString)*","~beta[sbm]~"="~.(betaSbmString)*","~phi[.(phiSubscript)]~"="~.(this@phis[m])*","~tau~"="~.(this@tau)*","~bar(R)~"="~.(rString))
				title(main = titleString, font.main = 2, adj = 0.75)

				for(n in seq_len(this@modules[[m]]@nodeNum)) {
					if(this@modules[[m]]@nodes[[n]]@clusterID > 0) {
						PlotHTAWeights(this@modules[[m]]@nodes[[n]]@weights, (this@modules[[m]]@nodes[[n]]@clusterID - 1 + colorShift) %% maxClusterNum + 1)
					}
				}

				dev.off()

				tmpString <- sprintf("images/HTAC_%s_class_IDs.pdf", letters[m])
				pdf(file = tmpString)
				palette(rainbow(maxClassID + 1 - minClassID))
				par(cex.axis = 1.5, cex.main = 1.6)
				plot(NULL, NULL, xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "")
				grid()

				phiSubscript <- ifelse(this@phi != -1, "", paste("_", letters[m], sep=""))

				moduleString <- sprintf("HTAC %s:", letters[m])
				rhoString <- sprintf("%.2f", this@modules[[m]]@rho)
				betaSbmString <- sprintf("%.2f", this@beta_sbm)
				rString <- sprintf("%.3f", this@R)
				phiSubscript <- ifelse(this@phi != -1, "", letters[m])
				titleString <- bquote(.(moduleString)~rho[.(letters[m])]~"="~.(rhoString)*","~beta[sbm]~"="~.(betaSbmString)*","~phi[.(phiSubscript)]~"="~.(this@phis[m])*","~tau~"="~.(this@tau)*","~bar(R)~"="~.(rString))
				title(main = titleString, font.main = 2, adj = 0.75)

				for(n in seq_len(this@modules[[m]]@nodeNum)) {
					if(this@modules[[m]]@nodes[[n]]@clusterID > 0) {
						PlotHTAWeights(this@modules[[m]]@nodes[[n]]@weights, (this@modules[[m]]@nodes[[n]]@classID - minClassID + colorShift) %% (maxClassID + 1 - minClassID) + 1)
					}
				}

				dev.off()
			}
		}
	})

#--------------------------------------------------------------------------------------------------
# Helper classes
#--------------------------------------------------------------------------------------------------

	setClass("EpisodicTopoARTRecallViewer",
		representation(
			path = "character"
		),
		prototype(
			path = ""
		)
	)

	setMethod("initialize", "EpisodicTopoARTRecallViewer", function(.Object, path)
	{
		.Object@path <- path
		.Object
	})

	setGeneric("SaveRecallPlot", function(this, maxInterSteps = -1, maxIntraSteps = -1) standardGeneric("SaveRecallPlot"))
	setMethod("SaveRecallPlot", "EpisodicTopoARTRecallViewer", function(this, maxInterSteps, maxIntraSteps)
	{

#--------------------------------------------------------------------------------------------------
# Local helper functions
#--------------------------------------------------------------------------------------------------

		CountImages <- function() 
		{
			filename <- sprintf("%sinter_image_%03i.jpg", this@path, interNum + 1)

			while(file.exists(filename)) {
				intraNum <- 0
				filename <- sprintf("%sintra_image_%03i_%03i.jpg", this@path, interNum + 1, intraNum + 1)

				while(file.exists(filename)) {
					intraNum	<-	intraNum + 1
					filename	<-	sprintf("%sintra_image_%03i_%03i.jpg", this@path, interNum + 1, intraNum + 1)
				}

				intraNumArray	<<-	c(intraNumArray, intraNum)
				maxIntraNum		<<-	max(intraNum, maxIntraNum)
				interNum		<<-	interNum + 1
				filename		<-	sprintf("%sinter_image_%03i.jpg", this@path, interNum + 1)
			}
		}

		ShowInterEpisodeRecallResults <- function() 
		{
			if(plotInterNum == 0)
				return()

			interYPos1		<-	plotYShift - (plotInterNum + 1) * stimulusDim[1] - plotInterNum * imageDist - yOff - imageBox - plotPYOff
			interYPos2		<-	plotYShift - stimulusDim[1] - imageDist - yOff + imageBox
			interTextXPos	<-	xOff - imageBox - lArrowOff - recallTextOff / 2
			interTextYPos	<-	interYPos1 - (interYPos1 - interYPos2) / 2
			arrowList		<-	list(NULL, NULL, NULL, NULL)

			if(interYPos2 - interYPos1 >= recallTextMinSize) {
				text(
					interTextXPos,
					interTextYPos,
					"inter-episode recall", adj = c(0.5, 0.5), cex = plotCex, col = darkRed, srt = 90)
			}

			if(interYPos2 > interYPos1) {
				rect(
					xOff - imageBox,
					interYPos1,
					stimulusDim[2] + xOff + imageBox,
					interYPos2,
					col = lightRed,
					border = darkRed)

				interArrowXPos <- xOff - imageBox - lArrowOff / 2

				arrows(
					interArrowXPos,
					interYPos2,
					interArrowXPos,
					interYPos1,
					col = darkRed,
					length = lArrowLengthBounded)
			}

			if(plotInterNum > 0) {

				# Draw small arrows
				for(i in seq_len(ifelse(plotInterNum < interNum, plotInterNum + 1, plotInterNum))) {
					arrowList[[1]] <- c(arrowList[[1]], xOff + stimulusDim[2] / 2)
					arrowList[[2]] <- c(arrowList[[2]], plotYShift - i * stimulusDim[1] - (i - 1) * imageDist - yOff - 1)
					arrowList[[3]] <- c(arrowList[[3]], xOff + stimulusDim[2] / 2)
					arrowList[[4]] <- c(arrowList[[4]], plotYShift - i * stimulusDim[1] - (i - 1) * imageDist - yOff - imageDist + 1)
				}
				arrows(arrowList[[1]], arrowList[[2]], arrowList[[3]], arrowList[[4]], col = black, length = sArrowLengthBounded);

				# Show ...
				if(plotInterNum < interNum) {
					text(
						xOff + stimulusDim[2] / 2,
						plotYShift - (plotInterNum + 1) * (stimulusDim[1] + imageDist) - yOff - pointsYOff / 2,	
						pointsString, adj = c(0.5, 0.5), cex = plotCex, col = black)
				}

				# Load and show images	
				for(i in seq_len(plotInterNum)) {
					filename <- sprintf("%sinter_image_%03i.jpg", this@path, i)
					interImage <- readJPEG(filename, TRUE);
					rasterImage(interImage, 
						xOff, 
						plotYShift - (i + 1) * stimulusDim[1] - i * imageDist - yOff, 
						stimulusDim[2] + xOff, 
						plotYShift - i * stimulusDim[1] - i * imageDist - yOff)
				}
			}
		}

		ShowIntraEpisodeRecallResults <- function() 
		{
			if(plotInterNum == 0 || plotIntraNum == 0)
				return()

			intraXPos1		<-	stimulusDim[2] + imageDist + xOff - imageBox
			intraXPos2		<-	(plotIntraNum + 1) * stimulusDim[2] + plotIntraNum * imageDist + xOff + imageBox + plotPXOff
			intraTextXPos	<-	intraXPos1 + (intraXPos2 - intraXPos1) / 2
			intraTextYPos	<-	plotYShift - yOff - stimulusDim[1] - imageDist + imageBox + lArrowOff + recallTextOff / 2
			arrowList		<-	list(NULL, NULL, NULL, NULL)

			if(intraXPos2 - intraXPos1 >= recallTextMinSize) {
				text(
					intraTextXPos,
					intraTextYPos,
					"intra-episode recall", adj = c(0.5, 0.5), cex = plotCex, col = darkBlue)
			}

			if(intraXPos2 > intraXPos1) {
				intraArrowYPos <- plotYShift - yOff - stimulusDim[1] - imageDist + imageBox + lArrowOff / 2

				arrows(
					intraXPos1,
					intraArrowYPos,
					intraXPos2,
					intraArrowYPos,
					col = darkBlue,
					length = lArrowLengthBounded)
			}

			# Inter-episode recall loop
			for(i in seq_len(plotInterNum)) {
				stepIntraNum <- min(intraNumArray[i], plotIntraNum)

				if(stepIntraNum > 0) {
					stepPlotPXoff	<-	ifelse(stepIntraNum < intraNumArray[i], plotPXOff, 0)
					intraXPos2		<-	(stepIntraNum + 1) * stimulusDim[2] + stepIntraNum * imageDist + xOff + imageBox + stepPlotPXoff
					intraYPos1		<-	plotYShift - yOff - (i + 1) * stimulusDim[1] - i * imageDist - imageBox
					intraYPos2		<-	plotYShift - yOff - i * (stimulusDim[1] + imageDist) + imageBox

					rect(
						intraXPos1,
						intraYPos1,
						intraXPos2,
						intraYPos2,
						col = lightBlue,
						border = darkBlue)

					# Draw small arrows
					for(j in seq_len(ifelse(plotIntraNum < intraNumArray[i], stepIntraNum + 1, stepIntraNum))) {
						arrowList[[1]] <- c(arrowList[[1]], xOff + j * stimulusDim[2] + (j - 1) * imageDist + 1)
						arrowList[[2]] <- c(arrowList[[2]], plotYShift - i * (stimulusDim[1] + imageDist) - stimulusDim[1] / 2 - yOff)
						arrowList[[3]] <- c(arrowList[[3]], xOff + j * (stimulusDim[2] + imageDist) - 1)
						arrowList[[4]] <- c(arrowList[[4]], plotYShift - i * (stimulusDim[1] + imageDist) - stimulusDim[1] / 2 - yOff)
					}
					arrows(arrowList[[1]], arrowList[[2]], arrowList[[3]], arrowList[[4]], col = black, length = sArrowLengthBounded);	

					# Show ...
					if(plotIntraNum < intraNumArray[i]) {
						text(
							xOff + (plotIntraNum + 1) * (stimulusDim[2] + imageDist) + pointsXOff / 2,
							plotYShift - i * (stimulusDim[1] + imageDist) - stimulusDim[1] / 2 - yOff,
							pointsString, adj = c(0.5, 0.5), cex = plotCex, col = black)
					}

					# Load and show images	
					for(j in seq_len(stepIntraNum)) {
						filename <- sprintf("%sintra_image_%03i_%03i.jpg", this@path, i, j)
						intraImage <- readJPEG(filename, TRUE)
						rasterImage(intraImage, 
							j * stimulusDim[2] + j * imageDist + xOff, 
							plotYShift - (i + 1) * stimulusDim[1] - i * imageDist - yOff, 
							(j + 1) * stimulusDim[2] + j * imageDist + xOff, 
							plotYShift - i * stimulusDim[1] - i * imageDist - yOff)
					}
				}
			}
		}

		ShowStimulus <- function() 
		{
			text(xOff - imageBox, plotYShift - yOff + stimulusTextYOff, "stimulus", adj = c(0, 1), cex = plotCex, col = darkGreen)

			rect(
				xOff - imageBox,
				plotYShift - stimulusDim[1] - yOff - imageBox,
				stimulusDim[2] + xOff + imageBox,
				plotYShift - yOff + imageBox,
				col = lightGreen,
				border = darkGreen)

			rasterImage(stimulus, 
				xOff, 
				plotYShift - stimulusDim[1] - yOff, 
				stimulusDim[2] + xOff, 
				plotYShift - yOff)
		}

#--------------------------------------------------------------------------------------------------

		library(jpeg)

		# Count available images
		interNum		<-	0
		intraNumArray	<-	NULL
		maxIntraNum		<-	0
		CountImages()

		# Incorporate maximum values
		plotInterNum	<-	ifelse(maxInterSteps < 0, interNum, min(interNum, maxInterSteps))
		plotIntraNum	<-	ifelse(maxInterSteps == 0, 0, ifelse(maxIntraSteps < 0, maxIntraNum, min(maxIntraNum, maxIntraSteps)))

		filename 	<-	sprintf("%sstimulus.jpg", this@path)
		stimulus 	<-	readJPEG(filename, TRUE)
		stimulusDim	<-	dim(stimulus)

		# Colours
		lightBlue	<-	"#f0f0ff"
		darkBlue	<-	"#7070bf"
		lightGreen	<-	"#f0fff0"
		darkGreen 	<-	"#70bf70"	
		lightRed	<-	"#fff0f0"
		darkRed 	<-	"#bf7070"
		black		<-	"#000000"

		# Image parameters
		imageDist	<-	20
		imageBox	<-	5

		# Large arrow parameters
		lArrowOff		<-	ifelse(interNum > 0, 20, 0)
		lArrowLength	<-	8

		# Small arrow parameters
		sArrowLength	<-	6

		# Text parameters
		recallTextOff		<-	ifelse(interNum > 0, 3, 0)
		stimulusTextYOff	<-	20
		recallTextMinSize	<-	120

		# ... parameters
		pointsXOff		<-	30
		pointsYOff		<-	20
		pointsString	<-	"..."

		xOff	<-	imageBox + ifelse(maxInterSteps == 0, 0, lArrowOff + recallTextOff)
		yOff	<-	imageBox + stimulusTextYOff

		# Plot parameters
		plotDPI		<-	150
		plotCex		<-	0.5
		plotPXOff	<-	ifelse(maxInterSteps == 0, 0, ifelse(plotIntraNum > 0 && plotIntraNum < maxIntraNum, imageDist + pointsXOff, 0))
		plotPYOff	<-	ifelse(plotInterNum > 0 && plotInterNum < interNum, imageDist + pointsYOff, 0)
		plotXSize	<-	stimulusDim[2] * (plotIntraNum + 1) + imageDist * plotIntraNum + imageBox + xOff + plotPXOff
		plotYSize	<-	stimulusDim[1] * (plotInterNum + 1) + imageDist * plotInterNum + imageBox + yOff + plotPYOff
		plotYShift	<-	plotYSize - 1
		plotXMargin	<-	0.0
		plotYMargin	<-	0.1
		plotWidth	<-	plotXSize / plotDPI + 2 * plotXMargin
		plotHeight	<-	plotYSize / plotDPI + 2 * plotYMargin

		pdf(file = "images/ETA_recall.pdf", width = plotWidth, height = plotHeight)
		par(bty = "n", xaxt = "n", yaxt = "n", mai = c(0, 0, 0, 0), omi = c(plotYMargin, plotXMargin, plotYMargin, plotXMargin))
		plot(NULL, NULL, xlim = c(0, plotXSize), ylim = c(0, plotYSize), xlab = "", ylab = "", asp = 1)

		lArrowLengthBounded	<-	min(lArrowLength / plotDPI, lArrowOff / (2 * plotDPI))
		sArrowLengthBounded	<-	min(sArrowLength / plotDPI, imageDist / (2 * plotDPI))

		ShowStimulus()
		ShowInterEpisodeRecallResults()
		ShowIntraEpisodeRecallResults()

		dev.off()
	})

#--------------------------------------------------------------------------------------------------

}
