diff --git a/.gitignore b/.gitignore
index 8c277efa2dc19ddee0de9ab1ccefbe812c98ce32..9fb9db37f64008a762c83f67d82ff6c9226b69fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,3 +27,6 @@
 Doxyfile
 documentation/*
 
+bin/*
+**/bin
+**/obj
diff --git a/acat/makefile b/acat/makefile
index 2921dd1af3ec76cee85bd4c5b138981ddcea16a3..96ad4cb446cb47b648699e7bb2e69b5b9e001057 100644
--- a/acat/makefile
+++ b/acat/makefile
@@ -1,13 +1,20 @@
-APPLICATION=acat
-CXXFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src 
-LDFLAGS= -L ../alib -lxml2 -lalib
+CC=g++
+EXECUTIBLE=acat
+CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src 
+LDFLAGS= -L ../alib/bin -lxml2 -lalib
 
+SOURCES=$(shell find src/ -name *cpp)
+OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES))
 
-SOURCES = src/*.cpp
+all: $(SOURCES) bin/$(EXECUTIBLE)
 
-all:
-	g++ $(CXXFLAGS) $(SOURCES)
-	g++ $(LDFLAGS) *.o -o $(APPLICATION)
+bin/$(EXECUTIBLE): $(OBJECTS)
+	mkdir -p bin
+	$(CC) $(LDFLAGS) $(OBJECTS) -o $@
+
+obj/%.o: src/%.cpp
+	mkdir -p $(dir $@)
+	$(CC) $(CCFLAGS) $< -o $@
 
 clean:
-	$(RM) *.o *.d $(APPLICATION)
+	$(RM) -r *.o *.d bin obj
diff --git a/aconvert.dot/makefile b/aconvert.dot/makefile
index 5be1ed48cce675ba753cb980b0c3f22832e373b5..a2e1c7e6f56909ca1dc58a309125a2a24c79221b 100644
--- a/aconvert.dot/makefile
+++ b/aconvert.dot/makefile
@@ -1,13 +1,20 @@
-APPLICATION=aconvert.dot
-CXXFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src 
-LDFLAGS= -L ../alib -lxml2 -lalib
+CC=g++
+EXECUTIBLE=aconvert.dot
+CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src 
+LDFLAGS= -L ../alib/bin -lxml2 -lalib
 
+SOURCES=$(shell find src/ -name *cpp)
+OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES))
 
-SOURCES = src/*.cpp
+all: $(SOURCES) bin/$(EXECUTIBLE)
 
-all:
-	g++ $(CXXFLAGS) $(SOURCES)
-	g++ $(LDFLAGS) *.o -o $(APPLICATION)
+bin/$(EXECUTIBLE): $(OBJECTS)
+	mkdir -p bin
+	$(CC) $(LDFLAGS) $(OBJECTS) -o $@
+
+obj/%.o: src/%.cpp
+	mkdir -p $(dir $@)
+	$(CC) $(CCFLAGS) $< -o $@
 
 clean:
-	$(RM) *.o *.d $(APPLICATION)
+	$(RM) -r *.o *.d bin obj
diff --git a/aconvert.gastex/makefile b/aconvert.gastex/makefile
index 452c48558e1cbc13268820a456699ff963c37594..46efb94eceaee61285237ff86f49fa7816e06427 100644
--- a/aconvert.gastex/makefile
+++ b/aconvert.gastex/makefile
@@ -1,13 +1,20 @@
-APPLICATION=aconvert.gastex
-CXXFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src 
-LDFLAGS= -L ../alib -lxml2 -lalib
+CC=g++
+EXECUTIBLE=aconvert.gastex
+CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src 
+LDFLAGS= -L ../alib/bin -lxml2 -lalib
 
+SOURCES=$(shell find src/ -name *cpp)
+OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES))
 
-SOURCES = src/*.cpp
+all: $(SOURCES) bin/$(EXECUTIBLE)
 
-all:
-	g++ $(CXXFLAGS) $(SOURCES)
-	g++ $(LDFLAGS) *.o -o $(APPLICATION)
+bin/$(EXECUTIBLE): $(OBJECTS)
+	mkdir -p bin
+	$(CC) $(LDFLAGS) $(OBJECTS) -o $@
+
+obj/%.o: src/%.cpp
+	mkdir -p $(dir $@)
+	$(CC) $(CCFLAGS) $< -o $@
 
 clean:
-	$(RM) *.o *.d $(APPLICATION)
+	$(RM) -r *.o *.d bin obj
diff --git a/aconvert/makefile b/aconvert/makefile
index f285c3717ec843277bf4adbfd8de2a43196c2fb0..a02e63209cfa9e94c892323331fd72e16bdc7f1e 100644
--- a/aconvert/makefile
+++ b/aconvert/makefile
@@ -1,13 +1,20 @@
-APPLICATION=aconvert
-CXXFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src 
-LDFLAGS= -L ../alib -lxml2 -lalib
+CC=g++
+EXECUTIBLE=aconvert
+CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src 
+LDFLAGS= -L ../alib/bin -lxml2 -lalib
 
+SOURCES=$(shell find src/ -name *cpp)
+OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES))
 
-SOURCES = src/*.cpp
+all: $(SOURCES) bin/$(EXECUTIBLE)
 
-all:
-	g++ $(CXXFLAGS) $(SOURCES)
-	g++ $(LDFLAGS) *.o -o $(APPLICATION)
+bin/$(EXECUTIBLE): $(OBJECTS)
+	mkdir -p bin
+	$(CC) $(LDFLAGS) $(OBJECTS) -o $@
+
+obj/%.o: src/%.cpp
+	mkdir -p $(dir $@)
+	$(CC) $(CCFLAGS) $< -o $@
 
 clean:
-	$(RM) *.o *.d $(APPLICATION)
+	$(RM) -r *.o *.d bin obj
diff --git a/alib/makefile b/alib/makefile
index 6d1a3f5044f28a72b55b7a2ed38087894214d11d..73250891cf3c3a53e5638f01a4d6dfcf63a6a572 100644
--- a/alib/makefile
+++ b/alib/makefile
@@ -1,13 +1,20 @@
+CC=g++
 LIBRARY=libalib.so 
-CXXFLAGS= -std=c++11 -O2 -c -Wall -fPIC -I/usr/include/libxml2/ 
+CCFLAGS= -std=c++11 -O2 -c -Wall -fPIC -I/usr/include/libxml2/ 
 LDFLAGS= -shared -lxml2
 
+SOURCES=$(shell find src/ -name *cpp)
+OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES))
 
-SOURCES = src/automaton/*.cpp src/automaton/TM/*.cpp src/automaton/FSM/*.cpp src/automaton/PDA/*cpp src/automaton/exception/*.cpp src/regexp/*.cpp src/grammar/*.cpp src/grammar/Regular/*.cpp src/grammar/Linear/*.cpp src/grammar/Unrestricted/*.cpp src/grammar/ContextSensitive/*.cpp src/grammar/ContextFree/*.cpp src/sax/*.cpp src/alphabet/*.cpp src/*.cpp
+all: $(SOURCES) bin/$(LIBRARY)
 
-all:
-	g++ $(CXXFLAGS) $(SOURCES)
-	g++ $(LDFLAGS) *.o -o $(LIBRARY)
+bin/$(LIBRARY): $(OBJECTS) 
+	mkdir -p bin
+	$(CC) $(LDFLAGS) $(OBJECTS) -o $@
+
+obj/%.o: src/%.cpp
+	mkdir -p $(dir $@)
+	$(CC) $(CCFLAGS) $< -o $@
 
 clean:
-	$(RM) *.o *.d $(LIBRARY)
+	$(RM) -r *.o *.d bin obj
diff --git a/aminimize/aminimize b/aminimize/aminimize
new file mode 100755
index 0000000000000000000000000000000000000000..b2e934a7b987719ca5177a36bb85151f7234a035
Binary files /dev/null and b/aminimize/aminimize differ
diff --git a/aminimize/makefile b/aminimize/makefile
new file mode 100644
index 0000000000000000000000000000000000000000..386f490424c05116b84b569208da51d39ba2b383
--- /dev/null
+++ b/aminimize/makefile
@@ -0,0 +1,20 @@
+CC=g++
+EXECUTIBLE=aminimize
+CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src 
+LDFLAGS= -L ../alib/bin -lxml2 -lalib
+
+SOURCES=$(shell find src/ -name *cpp)
+OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES))
+
+all: $(SOURCES) bin/$(EXECUTIBLE)
+
+bin/$(EXECUTIBLE): $(OBJECTS)
+	mkdir -p bin
+	$(CC) $(LDFLAGS) $(OBJECTS) -o $@
+
+obj/%.o: src/%.cpp
+	mkdir -p $(dir $@)
+	$(CC) $(CCFLAGS) $< -o $@
+
+clean:
+	$(RM) -r *.o *.d bin obj
diff --git a/aminimize/src/Minimize.cpp b/aminimize/src/Minimize.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..94834d87b40134778a60245c7244628a56eabe0a
--- /dev/null
+++ b/aminimize/src/Minimize.cpp
@@ -0,0 +1,121 @@
+/*
+ * Minimize.cpp
+ *
+ *  Created on: Dec 9, 2013
+ *      Author: honza
+ */
+
+#include "Minimize.h"
+
+#include <map>
+#include <set>
+#include <sstream>
+#include <iostream>
+
+#include "alphabet/Symbol.h"
+#include "automaton/FSM/TransitionFSM.h"
+
+automaton::State fromInteger(int number) {
+  std::stringstream ss;
+  ss << number;
+  return automaton::State(ss.str());
+}
+
+automaton::FSM Minimize::minimize(automaton::FSM& fsm) {
+	std::map<automaton::State, std::map<alphabet::Symbol, automaton::State > > refactor;
+
+	for(std::set<automaton::TransitionFSM>::const_iterator iter = fsm.getTransitions().begin(); iter != fsm.getTransitions().end(); iter++) {
+		if(refactor.find(iter->getFrom()) == refactor.end()) {
+			refactor.insert(std::pair<automaton::State, std::map<alphabet::Symbol, automaton::State> >(iter->getFrom(), std::map<alphabet::Symbol, automaton::State>()));
+		}
+		refactor[iter->getFrom()].insert(std::pair<alphabet::Symbol, automaton::State>(iter->getInput(), iter->getTo()));
+	}
+
+	std::map<automaton::State, automaton::State> toEquvivalentStates1;//original state to equivalent state
+	std::map<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> > minimizedTransitionFunction1; //mapped to the original state
+
+	std::map<automaton::State, automaton::State> toEquvivalentStates2;
+	std::map<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> > minimizedTransitionFunction2;
+	
+	for(auto iter = fsm.getStates().begin(); iter != fsm.getStates().end(); iter++) {
+		if(fsm.getFinalStates().count(*iter) == 0) { // not a final state
+			toEquvivalentStates2.insert(std::pair<automaton::State, automaton::State>(*iter, automaton::State("0")));
+		} else {
+			toEquvivalentStates2.insert(std::pair<automaton::State, automaton::State>(*iter, automaton::State("1")));
+		}
+	}
+
+	for(auto iter = refactor.begin(); iter != refactor.end(); iter++) {
+		automaton::State from = toEquvivalentStates2.find(iter->first)->second;
+		std::set<std::pair<alphabet::Symbol, automaton::State> > transitionFunction;
+
+		for(auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) {
+			transitionFunction.insert(std::pair<alphabet::Symbol, automaton::State>(iter2->first, toEquvivalentStates2.find(iter2->second)->second));
+		}
+		
+		std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > > key(from, transitionFunction);
+		
+		if(minimizedTransitionFunction2.find(key) == minimizedTransitionFunction2.end()) {
+			minimizedTransitionFunction2.insert(std::pair<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> >(key, std::set<automaton::State>()));
+		}
+		minimizedTransitionFunction2[key].insert(iter->first);
+	}
+	
+	do {
+		toEquvivalentStates1 = toEquvivalentStates2;
+		minimizedTransitionFunction1 = minimizedTransitionFunction2;
+
+		toEquvivalentStates2.clear();
+		minimizedTransitionFunction2.clear();
+		
+		int number = 0;
+		for(auto iter = minimizedTransitionFunction1.begin(); iter != minimizedTransitionFunction1.end(); iter++) {
+			for(auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) {
+				toEquvivalentStates2.insert(std::pair<automaton::State, automaton::State>(*iter2, fromInteger(number)));
+			}
+			number++;
+		}
+
+		for(auto iter = refactor.begin(); iter != refactor.end(); iter++) {
+			automaton::State from = toEquvivalentStates2.find(iter->first)->second;
+			std::set<std::pair<alphabet::Symbol, automaton::State> > transitionFunction;
+			
+			for(auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) {
+				transitionFunction.insert(std::pair<alphabet::Symbol, automaton::State>(iter2->first, toEquvivalentStates2.find(iter2->second)->second));
+			}
+			
+			std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > > key(from, transitionFunction);
+			
+			if(minimizedTransitionFunction2.find(key) == minimizedTransitionFunction2.end()) {
+				minimizedTransitionFunction2.insert(std::pair<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> >(key, std::set<automaton::State>()));
+			}
+
+			minimizedTransitionFunction2[key].insert(iter->first);
+			
+		}
+
+	} while(toEquvivalentStates1 != toEquvivalentStates2);
+
+	automaton::FSM result;
+	for(auto iter = fsm.getInputAlphabet().begin(); iter != fsm.getInputAlphabet().end(); iter++) {
+		result.addInputSymbol(*iter);
+	}
+	
+	for(auto iter = minimizedTransitionFunction2.begin(); iter != minimizedTransitionFunction2.end(); iter++) {
+		result.addState(iter->first.first);
+		if(fsm.getFinalStates().find(*(iter->second.begin())) != fsm.getFinalStates().end()) {//TODO improve using intersection
+			result.addFinalState(iter->first.first);
+		}
+		if(iter->second.find(*(fsm.getInitialStates().begin())) != iter->second.end()) { //TODO improve using intersection
+			result.addInitialState(iter->first.first);
+		}
+	}
+	
+	for(auto iter = minimizedTransitionFunction2.begin(); iter != minimizedTransitionFunction2.end(); iter++) {
+		for(auto iter2 = iter->first.second.begin(); iter2 != iter->first.second.end(); iter2++) {
+			result.addTransition(iter->first.first, iter2->first, iter2->second);
+		}
+	}
+	
+	return result;
+}
diff --git a/aminimize/src/Minimize.h b/aminimize/src/Minimize.h
new file mode 100644
index 0000000000000000000000000000000000000000..51db0171dad5b1908f7fdc7f79e5600c32247a5e
--- /dev/null
+++ b/aminimize/src/Minimize.h
@@ -0,0 +1,19 @@
+/*
+ * Minimize.h
+ *
+ *  Created on: Dec 9, 2013
+ *      Author: honza
+ */
+
+#ifndef MINIMIZE_H_
+#define MINIMIZE_H_
+
+#include "automaton/FSM/FSM.h"
+
+class Minimize {
+public:
+	static automaton::FSM minimize(automaton::FSM& fsm);
+
+};
+
+#endif /* MINIMIZE_H_ */
diff --git a/aminimize/src/aminimize.cpp b/aminimize/src/aminimize.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f4e5a4e0ed7d3299407e6316f57fb7520d20b5d6
--- /dev/null
+++ b/aminimize/src/aminimize.cpp
@@ -0,0 +1,57 @@
+//============================================================================
+// Name        : aminimize.cpp
+// Author      : Jan Travnicek
+//============================================================================
+
+#include <iostream>
+#include <string>
+#include <set>
+
+#include "AutomatonFactory.h"
+#include "AlibException.h"
+#include "automaton/AutomatonParser.h"
+
+#include "Minimize.h"
+
+using namespace std;
+using namespace automaton;
+using namespace alib;
+
+int main(int argc, char** argv) {
+
+	UnknownAutomaton automaton;
+
+	try {
+
+		if (argc == 2 && string("-h").compare(argv[1]) == 0) {
+			cout << "Automaton minimize.\nUsage: aminimize automaton.xml\n";
+			return -1;
+		}
+
+		if (argc == 2) {
+			automaton = AutomatonFactory::fromFile(argv[1]);
+			if(!AutomatonFactory::isFSM(automaton)) {
+				cout << "Automaton minimize require deterministic finite automaton\n";
+				return 1;
+			}
+
+			automaton::FSM fsm = AutomatonFactory::buildFSM(automaton);
+			if(!fsm.isDeterministic()) {
+				cout << "Automaton minimize require deterministic finite automaton\n";
+				return 1;
+			}
+
+			automaton::FSM res = Minimize::minimize(fsm);
+			res.toXML(cout);
+
+			return 0;
+		}
+		cout << "Automaton minimize require finite automaton\n";
+		return 1;
+
+	} catch (AlibException& e) {
+		cout << e.getCause() << endl;
+		return 0;
+	}
+
+}
diff --git a/makefile b/makefile
index 52cc33dfa4ba118f9ea7e57a8617c7d582f6d525..86e7d04447117b75d39873517f49dc39473fd393 100644
--- a/makefile
+++ b/makefile
@@ -2,28 +2,30 @@ APPPATH = /usr/bin
 LIBPATH = /usr/lib/
 BINFOLDER = bin
 
-SUBDIRS = alib acat aconvert aconvert.dot aconvert.gastex
+SUBDIRS = alib acat aconvert aconvert.dot aconvert.gastex aminimize
 .PHONY: subdirs $(SUBDIRS)
      
 all: $(SUBDIRS) copy
+
 $(SUBDIRS):
 	$(MAKE) -C $@
 copy:
 	rm -rf $(BINFOLDER)
 	mkdir $(BINFOLDER)
-	cp alib/libalib.so $(BINFOLDER)
-	cp alib/libalib.so $(BINFOLDER)
-	cp acat/acat $(BINFOLDER)
-	cp aconvert/aconvert $(BINFOLDER)
-	cp aconvert.dot/aconvert.dot $(BINFOLDER)
-	cp aconvert.gastex/aconvert.gastex $(BINFOLDER)
+	cp alib/bin/libalib.so $(BINFOLDER)
+	cp acat/bin/acat $(BINFOLDER)
+	cp aconvert/bin/aconvert $(BINFOLDER)
+	cp aconvert.dot/bin/aconvert.dot $(BINFOLDER)
+	cp aconvert.gastex/bin/aconvert.gastex $(BINFOLDER)
+	cp aminimize/bin/aminimize $(BINFOLDER)
 
 install:
-	cp alib/libalib.so $(LIBPATH)
-	cp acat/acat $(APPPATH)
-	cp aconvert/aconvert $(APPPATH)
-	cp aconvert.dot/aconvert.dot $(APPPATH)
-	cp aconvert.gastex/aconvert.gastex $(APPPATH)
+	cp alib/bin/libalib.so $(LIBPATH)
+	cp acat/bin/acat $(APPPATH)
+	cp aconvert/bin/aconvert $(APPPATH)
+	cp aconvert.dot/bin/aconvert.dot $(APPPATH)
+	cp aconvert.gastex/bin/aconvert.gastex $(APPPATH)
+	cp aminimize/bin/aminimize $(APPPATH)
 
 uninstall:
 	rm $(LIBPATH)/libalib.so
@@ -31,3 +33,4 @@ uninstall:
 	rm $(APPPATH)/aconvert
 	rm $(APPPATH)/aconvert.dot
 	rm $(APPPATH)/aconvert.gastex
+	rm $(APPPATH)/aminimize