diff --git a/acompaction2/makefile b/acompaction2/makefile
new file mode 100644
index 0000000000000000000000000000000000000000..905d096b31fd2139233d69a9e7e7141a3d21e927
--- /dev/null
+++ b/acompaction2/makefile
@@ -0,0 +1,128 @@
+SHELL:=/bin/bash
+EXECUTABLE:=acompaction2
+
+define NEW_LINE
+
+
+endef
+
+export NEW_LINE
+
+LDFLAGS_DEBUG:=-L../alib2data/lib-debug -L../alib2algo/lib-debug -rdynamic -lxml2 -lalib2data -lalib2algo -Wl,-rpath,.
+
+LDFLAGS_RELEASE:=-L../alib2data/lib-release -L../alib2algo/lib-release -rdynamic -lxml2 -lalib2data -lalib2algo -Wl,-rpath,.
+
+OBJECTS_DEBUG:=$(patsubst src/%.cpp, obj-debug/%.o, $(shell find src/ -name *cpp))
+
+OBJECTS_RELEASE:=$(patsubst src/%.cpp, obj-release/%.o, $(shell find src/ -name *cpp))
+
+.PHONY: all build-debug clean-debug doc
+
+all:
+	@echo "What to do master?"
+
+obj%/makefile: makefile
+	mkdir -p $(dir $@)
+	echo "\
+	SHELL:=/bin/bash$${NEW_LINE}\
+	SRCDIR:=$${NEW_LINE}\
+	DEPTH:=$${NEW_LINE}\
+	OBJECTS_BASE_DIR:=$${NEW_LINE}\
+	$${NEW_LINE}\
+	define NEW_LINE$${NEW_LINE}\
+	$${NEW_LINE}\
+	$${NEW_LINE}\
+	endef$${NEW_LINE}\
+	$${NEW_LINE}\
+	export NEW_LINE$${NEW_LINE}\
+	$${NEW_LINE}\
+	CXXFLAGS:= -std=c++11 \$$(CXX_OTHER_FLAGS) -c -Wall -pedantic -Wextra -fPIC -I/usr/include/libxml2/ -I../../\$$(DEPTH)alib2data/src/ -I../../\$$(DEPTH)alib2algo/src/$${NEW_LINE}\
+	$${NEW_LINE}\
+	SOURCES:= \$$(shell find ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR) -maxdepth 1 -type f -name \"*.cpp\")$${NEW_LINE}\
+	DEPENDENCIES:= \$$(patsubst ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d, \$$(SOURCES))$${NEW_LINE}\
+	OBJECTS:= \$$(patsubst %.d, %.o, \$$(DEPENDENCIES))$${NEW_LINE}\
+	SOURCES_DIRS:= \$$(shell find ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR) -maxdepth 1 -mindepth 1 -type d)$${NEW_LINE}\
+	OBJECTS_DIRS:= \$$(patsubst ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%, %/, \$$(SOURCES_DIRS))$${NEW_LINE}\
+	OBJECTS_DIRS_MAKEFILES:= \$$(patsubst %, %makefile, \$$(OBJECTS_DIRS))$${NEW_LINE}\
+	$${NEW_LINE}\
+	.PHONY: all$${NEW_LINE}\
+	.PRECIOUS: \$$(DEPENDECIES) \$$(OBJECTS_DIRS_MAKEFILES)$${NEW_LINE}\
+	$${NEW_LINE}\
+	all: \$$(OBJECTS_DIRS) \$$(OBJECTS)$${NEW_LINE}\
+	$${NEW_LINE}\
+	%.d: makefile$${NEW_LINE}\
+		@echo \"\\$${NEW_LINE}\
+		\$$(shell sha1sum <<< \"\$$@\" | sed \"s/  -//g\") = \\$$\$$(shell (\\$$\$$(CXX) -MM \\$$\$$(CXXFLAGS) \$$(patsubst ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d,../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$@) 2>/dev/null || echo \\\"\$$(patsubst ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d,../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$@) FORCE\\\") | sed \\\"s/.*://g;s/\\\\\\\\\\\\\\\\//g\\\")\$$\$${NEW_LINE}\\$${NEW_LINE}\
+		\$$(patsubst %.d,%.o, \$$@): \\$$\$$(\$$(shell sha1sum <<< \"\$$@\" | sed \"s/  -//g\")) makefile\$$\$${NEW_LINE}\\$${NEW_LINE}\
+			\\$$\$$(CXX) \\$$\$$(CXXFLAGS) \\$$\$$< -o \$$(patsubst %.d,%.o, \$$@)\$$\$${NEW_LINE}\\$${NEW_LINE}\
+		\" > \$$@$${NEW_LINE}\
+	$${NEW_LINE}\
+	%/makefile: makefile$${NEW_LINE}\
+		mkdir -p \$$(dir \$$@)$${NEW_LINE}\
+		cp makefile \$$@$${NEW_LINE}\
+	$${NEW_LINE}\
+	%/: FORCE | %/makefile$${NEW_LINE}\
+		@accesstime=\`stat -c %Y \$$@\` && \\$${NEW_LINE}\
+		\$$(MAKE) -C \$$@ SRCDIR=\$$(SRCDIR)\$$(notdir \$$(patsubst %/, %, \$$@))/ DEPTH=\$$(DEPTH)../ OBJECTS_BASE_DIR=\$$(OBJECTS_BASE_DIR) SOURCES_BASE_DIR=\$$(SOURCES_BASE_DIR) CXX_OTHER_FLAGS=\"\$$(CXX_OTHER_FLAGS)\" && \\$${NEW_LINE}\
+		accesstime2=\`stat -c %Y \$$@\` && \\$${NEW_LINE}\
+		if [ "\$$\$$accesstime" -ne "\$$\$$accesstime2" ]; then \\$${NEW_LINE}\
+			touch .; \\$${NEW_LINE}\
+		fi$${NEW_LINE}\
+	$${NEW_LINE}\
+	FORCE:$${NEW_LINE}\
+	$${NEW_LINE}\
+	-include \$$(DEPENDENCIES)" > $@
+
+debug: build-debug
+
+release: build-release
+
+clean: clean-debug clean-release
+	$(RM) -r doc
+
+
+
+bin-debug/$(EXECUTABLE): obj-debug/ $(OBJECTS_DEBUG)
+	mkdir -p $(dir $@)
+	$(CXX) $(OBJECTS_DEBUG) -o $@ $(LDFLAGS_DEBUG)
+
+bin-release/$(EXECUTABLE): obj-release/ $(OBJECTS_RELEASE)
+	mkdir -p $(dir $@)
+	$(CXX) $(OBJECTS_RELEASE) -o $@ $(LDFLAGS_RELEASE)
+
+
+
+obj-debug/: FORCE | obj-debug/makefile
+	$(MAKE) -C $@ OBJECTS_BASE_DIR=obj-debug SOURCES_BASE_DIR=src CXX_OTHER_FLAGS="-g -O0"
+
+obj-release/: FORCE | obj-release/makefile
+	$(MAKE) -C $@ OBJECTS_BASE_DIR=obj-release SOURCES_BASE_DIR=src CXX_OTHER_FLAGS="-O3"
+
+
+
+$(OBJECTS_DEBUG): obj-debug/
+
+$(OBJECTS_RELEASE): obj-release/
+
+
+build-debug: bin-debug/$(EXECUTABLE)
+
+build-release: bin-release/$(EXECUTABLE)
+
+
+
+clean-debug:
+	$(RM) -r *.o *.d bin-debug obj-debug
+
+clean-release:
+	$(RM) -r *.o *.d bin-release obj-release
+
+
+
+FORCE:
+
+
+
+doc:
+	doxygen
+
diff --git a/acompaction2/src/acompaction.cpp b/acompaction2/src/acompaction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bf1e8fb96f344250d2ec336f8f681649f6179e56
--- /dev/null
+++ b/acompaction2/src/acompaction.cpp
@@ -0,0 +1,48 @@
+/*
+ * acompaction.cpp
+ *
+ *  Created on: 2. 11. 2014
+ *      Author: Tomas Pecka
+ */
+
+#include <iostream>
+#include <tclap/CmdLine.h>
+
+#include "exception/AlibException.h"
+#include "factory/XmlDataFactory.hpp"
+#include "automaton/transform/Compaction.h"
+
+int main(int argc, char** argv) {
+
+	try {
+		TCLAP::CmdLine cmd("Automaton compaction binary", ' ', "0.01");
+
+		TCLAP::ValueArg<std::string> input(	"i",	"input",	"Automaton to compactify",		false,	"-",		"file");
+		cmd.add( input );
+
+		cmd.parse(argc, argv);
+
+		std::list<sax::Token> tokens;
+		if(input.isSet()) {
+			if(input.getValue() == "-") {
+				sax::SaxParseInterface::parseStdin(tokens);
+			} else {
+				sax::SaxParseInterface::parseFile(input.getValue(), tokens);
+			}
+		} else {
+			sax::SaxParseInterface::parseStdin(tokens);
+		}
+
+		alib::XmlDataFactory::toStdout(automaton::transform::Compaction::convert(alib::XmlDataFactory::fromTokens<automaton::Automaton>(tokens)));
+		return 0;
+
+	} catch (const exception::AlibException& exception) {
+		alib::XmlDataFactory::toStdout(exception);
+		return 1;
+	} catch(const TCLAP::ArgException& exception) {
+		std::cout << exception.error() << std::endl;
+		return 2;
+	} catch(...) {
+		return 127;
+	}
+}
diff --git a/alib2algo/src/automaton/transform/Compaction.cpp b/alib2algo/src/automaton/transform/Compaction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aee716ea161f81b9f810f08946fca11aff7e1633
--- /dev/null
+++ b/alib2algo/src/automaton/transform/Compaction.cpp
@@ -0,0 +1,141 @@
+/*
+ * Compaction.cpp
+ *
+ *  Created on: 2. 11. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "Compaction.h"
+
+#include <exception/AlibException.h>
+
+#include <automaton/common/State.h>
+#include <automaton/FSM/CompactNFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <stack>
+#include <tuple>
+
+namespace automaton {
+
+namespace transform {
+
+automaton::Automaton Compaction::convert(const automaton::Automaton& automaton) {
+	automaton::Automaton* out = NULL;
+	automaton.getData().Accept((void*) &out, Compaction::COMPACTION);
+	automaton::Automaton res(std::move(*out));
+	delete out;
+	return res;
+}
+
+automaton::CompactNFA Compaction::convert(const automaton::CompactNFA& automaton)
+{
+	return automaton;
+}
+
+automaton::CompactNFA Compaction::convert(const automaton::DFA& automaton)
+{
+	automaton::CompactNFA res(automaton.getInitialState());
+	res.setInputAlphabet(automaton.getInputAlphabet());
+
+	string::LinearString path;
+	path.setAlphabet(automaton.getInputAlphabet());
+
+	std::map<automaton::State, bool> visited;
+	for(const auto& state : automaton.getStates())
+		visited.insert(std::make_pair(state, automaton.getInitialState() == state));
+
+	std::stack<std::tuple<automaton::State, automaton::State, alphabet::Symbol>> stack; // state x lastFork x symbol we used to go to that state
+	for(const auto& transition: automaton.getTransitionsFromState(automaton.getInitialState()))
+	{
+		stack.push(std::make_tuple(transition.second, automaton.getInitialState(), transition.first.second));
+	}
+
+	if(automaton.getFinalStates().count(automaton.getInitialState()) > 0)
+		res.addFinalState(automaton.getInitialState());
+
+	while(!stack.empty())
+	{
+		const automaton::State q = std::get<0>(stack.top());
+		const automaton::State lastFork = std::get<1>(stack.top());
+		const alphabet::Symbol symbol = std::get<2>(stack.top());
+		stack.pop();
+
+		path.appendSymbol(symbol);
+
+		// only 1 child and nonfinal
+		if(automaton.getTransitionsFromState(q).size() == 1 && automaton.getFinalStates().count(q) == 0 && automaton.getInitialState() != q)
+		{
+			const auto& transition = * automaton.getTransitionsFromState(q).begin();
+
+			stack.push(std::make_tuple(transition.second, lastFork, transition.first.second));
+		}
+		else // fork or final state
+		{
+			res.addState(q);
+
+			if(automaton.getFinalStates().count(q))
+				res.addFinalState(q);
+
+			res.addTransition(lastFork, path, q);
+			path.setContent({});
+
+			for(const auto& transition : automaton.getTransitionsFromState(q))
+			{
+				if(visited.find(transition.second)->second == false)
+				{
+					stack.push(std::make_tuple(transition.second, q, transition.first.second));
+					visited.find(transition.second)->second = true;
+				}
+			}
+		}
+	}
+
+	return res;
+}
+
+automaton::CompactNFA Compaction::convert(const automaton::NFA& automaton)
+{
+	automaton::CompactNFA res(automaton.getInitialState());
+	// TODO
+	return res;
+}
+
+void Compaction::Visit(void* data, const CompactNFA& automaton) const
+{
+	automaton::Automaton*& out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->convert(automaton));
+}
+
+void Compaction::Visit(void* data, const DFA& automaton) const
+{
+	automaton::Automaton*& out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->convert(automaton));
+}
+
+void Compaction::Visit(void*, const EpsilonNFA&) const
+{
+	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
+}
+
+void Compaction::Visit(void*, const ExtendedNFA&) const
+{
+	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
+}
+
+void Compaction::Visit(void*, const MultiInitialStateNFA&) const
+{
+	throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA");
+}
+
+void Compaction::Visit(void* data, const NFA& automaton) const
+{
+	automaton::Automaton*& out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->convert(automaton));
+}
+
+const Compaction Compaction::COMPACTION;
+
+} /* namespace transform */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/automaton/transform/Compaction.h b/alib2algo/src/automaton/transform/Compaction.h
new file mode 100644
index 0000000000000000000000000000000000000000..520ad9a028d9dfb1f26b97bcfdb061a97e8a0066
--- /dev/null
+++ b/alib2algo/src/automaton/transform/Compaction.h
@@ -0,0 +1,48 @@
+/*
+ * Compaction.h
+ *
+ *  Created on: 2. 11. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef COMPACTION_H_
+#define COMPACTION_H_
+
+#include "automaton/Automaton.h"
+
+namespace automaton {
+
+namespace transform {
+
+/**
+ * Transforms FSM to CompactNFA
+ */
+class Compaction : public VisitableConstFSMBase {
+public:
+	static automaton::CompactNFA convert( const automaton::DFA& automaton);
+	static automaton::CompactNFA convert( const automaton::NFA& automaton);
+	static automaton::CompactNFA convert( const automaton::CompactNFA& automaton);
+
+	/**
+	 * Transforms
+	 * @param automaton FSM to transform
+	 * @return CompactNFA equivalent to given automaton
+	 */
+	static automaton::Automaton convert( const automaton::Automaton & automaton );
+
+private:
+	void Visit(void*, const CompactNFA& automaton) const;
+	void Visit(void*, const DFA& automaton) const;
+	void Visit(void*, const EpsilonNFA& automaton) const;
+	void Visit(void*, const ExtendedNFA& automaton) const;
+	void Visit(void*, const MultiInitialStateNFA& automaton) const;
+	void Visit(void*, const NFA& automaton) const;
+
+	static const Compaction COMPACTION;
+};
+
+} /* namespace transform */
+
+} /* namespace automaton */
+
+#endif /* COMPACTION_H_ */
diff --git a/makefile b/makefile
index fc64ef68283bac6da8acd3a05b102fb8bf5079dc..89afbc69f21c028a9becac570a24260d21cec8d6 100644
--- a/makefile
+++ b/makefile
@@ -7,6 +7,7 @@ SUBDIRS_LIBS = alib2algo
 SUBDIRS_BINS = aecho2 \
 		aconversions2 \
 		aconvert2 \
+		acompaction2 \
 		aderivation2 \
 		adeterminize2 \
 		acompare2 \