diff --git a/configure.ac b/configure.ac
index a9bd36d47f78316399d1bd155314fcd8fac03b01..e430e8a7c38b1e633573f62ca97ffe6ac9ecd2fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,10 +12,13 @@ AM_INIT_AUTOMAKE([foreign -Wall -Werror subdir-objects])
 
 # Checks for programs.
 AC_PROG_CC
+AM_PROG_AR
+AC_PROG_LIBTOOL
 
 PKG_CHECK_MODULES([CHECK], [check >= 0.9.4])
 
 # Checks for libraries.
+LT_INIT()
 
 # Checks for header files.
 AC_CHECK_HEADER([errno.h])
@@ -33,6 +36,7 @@ AC_CHECK_HEADER([string.h])
 # Makefiles
 AC_CONFIG_FILES([Makefile
 		 src/Makefile
+		 src/lib/Makefile
 		 tests/Makefile])
 
 AC_OUTPUT
diff --git a/sefht.geany b/sefht.geany
index f9ef171a1038c811594907eb073086f2a7c08cd6..6f236307e69a94987d47bee0a8f6d60e2f2da749 100644
--- a/sefht.geany
+++ b/sefht.geany
@@ -28,33 +28,34 @@ long_line_behaviour=1
 long_line_column=72
 
 [files]
-current_page=2
-FILE_NAME_0=607;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fconfigure.ac;0;8
-FILE_NAME_1=384;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2FMakefile.am;0;8
-FILE_NAME_2=811;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmain.c;0;8
-FILE_NAME_3=1280;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fcms.c;0;8
-FILE_NAME_4=1148;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fcms.h;0;8
-FILE_NAME_5=4036;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fdata.c;0;8
-FILE_NAME_6=1099;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fdata.h;0;8
-FILE_NAME_7=1500;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ffragment.c;0;8
-FILE_NAME_8=1058;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ffragment.h;0;8
-FILE_NAME_9=1420;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fnode_fragment.c;0;8
-FILE_NAME_10=1574;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fnode_fragment.h;0;8
-FILE_NAME_11=25433;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ftext.c;0;8
-FILE_NAME_12=3011;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ftext.h;0;8
-FILE_NAME_13=1351;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fvalidator.c;0;8
-FILE_NAME_14=1130;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fvalidator.h;0;8
-FILE_NAME_15=994;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ferror.h;0;4
-FILE_NAME_16=881;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flog.h;0;4
-FILE_NAME_17=938;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmacro.h;0;8
-FILE_NAME_18=847;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fsefht.h;0;8
-FILE_NAME_19=1089;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8
-FILE_NAME_20=1113;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8
-FILE_NAME_21=3059;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8
-FILE_NAME_22=8535;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_node_fragment.c;0;8
-FILE_NAME_23=11889;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8
-FILE_NAME_24=960;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
-FILE_NAME_25=55;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
+current_page=20
+FILE_NAME_0=923;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fconfigure.ac;0;8
+FILE_NAME_1=73;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2FMakefile.am;0;8
+FILE_NAME_2=943;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmain.c;0;8
+FILE_NAME_3=1138;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2FMakefile.am;0;8
+FILE_NAME_4=1280;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fcms.c;0;8
+FILE_NAME_5=1021;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fcms.h;0;8
+FILE_NAME_6=4036;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fdata.c;0;8
+FILE_NAME_7=1645;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fdata.h;0;8
+FILE_NAME_8=1500;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment.c;0;8
+FILE_NAME_9=2729;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment.h;0;8
+FILE_NAME_10=1420;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.c;0;8
+FILE_NAME_11=1461;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.h;0;8
+FILE_NAME_12=25433;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.c;0;8
+FILE_NAME_13=3332;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.h;0;8
+FILE_NAME_14=1351;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator.c;0;8
+FILE_NAME_15=1818;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator.h;0;8
+FILE_NAME_16=987;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ferror.h;0;8
+FILE_NAME_17=1259;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Flog.h;0;4
+FILE_NAME_18=1077;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fmacro.h;0;8
+FILE_NAME_19=1063;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fsefht.h;0;8
+FILE_NAME_20=1329;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8
+FILE_NAME_21=1113;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8
+FILE_NAME_22=3059;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8
+FILE_NAME_23=13535;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_node_fragment.c;0;8
+FILE_NAME_24=11889;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8
+FILE_NAME_25=960;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
+FILE_NAME_26=55;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
 
 [VTE]
 last_dir=/home/jonathan/Dokumente/projekte/prgm/internet/web/SeFHT/tests
diff --git a/src/Makefile.am b/src/Makefile.am
index f720509f6f670fa580e327d27fa41fec0f7468ef..211dd58bd9a275df055225ff186f97962d4a016e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,20 +1,13 @@
 ## Process this file with automake to produce Makefile.in
 
+SUBDIRS = lib
+
 AM_CFLAGS = -Wall -Wextra
 
-bin_PROGRAMS = sefht.fcgi
+bin_PROGRAMS = sefht_demo
 
-sefht_fcgi_SOURCES =
-sefht_fcgi_SOURCES += main.c
-sefht_fcgi_SOURCES += macro.h
-sefht_fcgi_SOURCES += sefht.h
-sefht_fcgi_SOURCES += error.h
-sefht_fcgi_SOURCES += log.h
-sefht_fcgi_SOURCES += cms.c cms.h
-sefht_fcgi_SOURCES += data.c data.h
-sefht_fcgi_SOURCES += fragment.c fragment.h
-sefht_fcgi_SOURCES += node_fragment.c node_fragment.h
-sefht_fcgi_SOURCES += text.c text.h
-sefht_fcgi_SOURCES += validator.c validator.h
+sefht_demo_SOURCES =
+sefht_demo_SOURCES += main.c
 
-sefht_fcgi_LDADD = -lm
+sefht_demo_CPPFLAGS = -I$(srcdir)/lib
+sefht_demo_LDADD = -lm lib/libsefht.la
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..84f2a2cd350c7dcc70ecfa8b90cd884161857538
--- /dev/null
+++ b/src/lib/Makefile.am
@@ -0,0 +1,32 @@
+## Process this file with automake to produce Makefile.in
+
+AM_CFLAGS = -Wall -Wextra
+
+lib_LTLIBRARIES = libsefht.la
+
+libsefht_la_SOURCES =
+libsefht_la_SOURCES += sefht/macro.h
+libsefht_la_SOURCES += sefht/sefht.h
+libsefht_la_SOURCES += sefht/error.h
+libsefht_la_SOURCES += sefht/log.h
+libsefht_la_SOURCES += sefht/cms.c sefht/cms.h
+libsefht_la_SOURCES += sefht/data.c sefht/data.h
+libsefht_la_SOURCES += sefht/fragment.c sefht/fragment.h
+libsefht_la_SOURCES += sefht/node_fragment.c sefht/node_fragment.h
+libsefht_la_SOURCES += sefht/text.c sefht/text.h
+libsefht_la_SOURCES += sefht/validator.c sefht/validator.h
+
+nobase_include_HEADERS =
+nobase_include_HEADERS += sefht/macro.h
+nobase_include_HEADERS += sefht/sefht.h
+nobase_include_HEADERS += sefht/error.h
+nobase_include_HEADERS += sefht/log.h
+nobase_include_HEADERS += sefht/cms.h
+nobase_include_HEADERS += sefht/data.h
+nobase_include_HEADERS += sefht/fragment.h
+nobase_include_HEADERS += sefht/node_fragment.h
+nobase_include_HEADERS += sefht/text.h
+nobase_include_HEADERS += sefht/validator.h
+
+libsefht_la_CPPFLAGS = -DLIB_SEFHT_COMPILATION
+libsefht_la_LDFLAGS = -version_info 0:0:0
diff --git a/src/cms.c b/src/lib/sefht/cms.c
similarity index 100%
rename from src/cms.c
rename to src/lib/sefht/cms.c
diff --git a/src/cms.h b/src/lib/sefht/cms.h
similarity index 63%
rename from src/cms.h
rename to src/lib/sefht/cms.h
index 683f0cbc10e56d8d3086bce60edab3fb916176c7..d9fca6a05655957ba6199f2207c6164120b9fc39 100644
--- a/src/cms.h
+++ b/src/lib/sefht/cms.h
@@ -22,23 +22,38 @@
  */
 
 
-#ifndef _CMS_H
-#define _CMS_H
+#ifndef __CMS_H__
+#define __CMS_H__
+
+#if !defined (__SEFHT_H_INSIDE__) && !defined (LIB_SEFHT_COMPILATION)
+#error "Only <sefht/sefht.h> can be included directly."
+#endif
 
 #include "error.h"
 
 #include "data.h"
 
 
+#ifdef LIB_SEFHT_COMPILATION
+
 struct SH_Cms
 {
 	struct SH_Data * data;
 };
 
-struct SH_Cms * SH_Cms_new (struct SH_Error * error);
-void SH_Cms_free (struct SH_Cms * cms, struct SH_Error * error);
+#endif /* LIB_SEFHT_COMPILATION */
+
+typedef struct SH_Cms SH_Cms;
+
+
+SH_Cms *
+SH_Cms_new (struct SH_Error * error);
+
+void
+SH_Cms_free (SH_Cms * cms, struct SH_Error * error);
 
-page_t SH_Cms_register_page (struct SH_Cms * cms, const char * name,
-			     struct SH_Error * error);
+page_t
+SH_Cms_register_page (SH_Cms * cms, const char * name,
+                      struct SH_Error * error);
 
-#endif /* _CMS_H */
+#endif /* __CMS_H__ */
diff --git a/src/data.c b/src/lib/sefht/data.c
similarity index 100%
rename from src/data.c
rename to src/lib/sefht/data.c
diff --git a/src/data.h b/src/lib/sefht/data.h
similarity index 69%
rename from src/data.h
rename to src/lib/sefht/data.h
index 4b502d308f62163ba27aafb5ac09812882b7d21d..22e75530a0644d3cf135c8a04dae281151b81beb 100644
--- a/src/data.h
+++ b/src/lib/sefht/data.h
@@ -22,8 +22,12 @@
  */
 
 
-#ifndef _DATA_H
-#define _DATA_H
+#ifndef __DATA_H__
+#define __DATA_H__
+
+#if !defined (__SEFHT_H_INSIDE__) && !defined (LIB_SEFHT_COMPILATION)
+#error "Only <sefht/sefht.h> can be included directly."
+#endif
 
 #include <limits.h>
 
@@ -36,6 +40,9 @@ typedef unsigned int page_t;
 #define PAGE_ERR 0
 #define PAGE_MIN 1
 #define PAGE_MAX UINT_MAX
+
+#ifdef LIB_SEFHT_COMPILATION
+
 #define NEXT_PAGE(page) page++
 
 struct SH_Page
@@ -52,11 +59,19 @@ struct SH_Data
 	page_t last_page;
 };
 
-struct SH_Data * SH_Data_new (struct SH_Error * error);
-void SH_Data_free (struct SH_Data * data, struct SH_Error * error);
+#endif /* LIB_SEFHT_COMPILATION */
+
+typedef struct SH_Data SH_Data;
+
+
+SH_Data *
+SH_Data_new (struct SH_Error * error);
 
+void
+SH_Data_free (SH_Data * data, struct SH_Error * error);
 
-page_t SH_Data_register_page (struct SH_Data * data, const char * name,
-			      struct SH_Error * error);
+page_t
+SH_Data_register_page (SH_Data * data, const char * name,
+                       struct SH_Error * error);
 
-#endif /* _DATA_H */
+#endif /* __DATA_H__ */
diff --git a/src/error.h b/src/lib/sefht/error.h
similarity index 82%
rename from src/error.h
rename to src/lib/sefht/error.h
index f8e2e5ec2b31d79116ea91949ffe1780f7c0f1a1..a8ded626966f498ecd6b88bfb174f2acc03ad8fd 100644
--- a/src/error.h
+++ b/src/lib/sefht/error.h
@@ -22,8 +22,12 @@
  */
 
 
-#ifndef _ERROR_H
-#define _ERROR_H
+#ifndef __ERROR_H__
+#define __ERROR_H__
+
+#if !defined (__SEFHT_H_INSIDE__) && !defined (LIB_SEFHT_COMPILATION)
+#error "Only <sefht/sefht.h> can be included directly."
+#endif
 
 
 enum SH_ErrorType
@@ -40,4 +44,4 @@ struct SH_Error
 	enum SH_ErrorType type;
 };
 
-#endif /* _ERROR_H */
+#endif /* __ERROR_H__ */
diff --git a/src/fragment.c b/src/lib/sefht/fragment.c
similarity index 100%
rename from src/fragment.c
rename to src/lib/sefht/fragment.c
diff --git a/src/fragment.h b/src/lib/sefht/fragment.h
similarity index 73%
rename from src/fragment.h
rename to src/lib/sefht/fragment.h
index c15ed290142b7fa58697f4d6689019c12b4a98a6..30de47ff2ecfb42c288e98e1d22036fe56c1ee09 100644
--- a/src/fragment.h
+++ b/src/lib/sefht/fragment.h
@@ -22,8 +22,12 @@
  */
 
 
-#ifndef _FRAGMENT_H
-#define _FRAGMENT_H
+#ifndef __FRAGMENT_H__
+#define __FRAGMENT_H__
+
+#if !defined (__SEFHT_H_INSIDE__) && !defined (LIB_SEFHT_COMPILATION)
+#error "Only <sefht/sefht.h> can be included directly."
+#endif
 
 #include "data.h"
 #include "text.h"
@@ -35,6 +39,8 @@ enum HTML_MODE
 	WRAP
 };
 
+#ifdef LIB_SEFHT_COMPILATION
+
 enum SH_FRAGMENT_TYPE
 {
 	NODE
@@ -108,21 +114,24 @@ get_type (struct SH_Fragment * fragment)
 	return fragment->type;
 }
 
+#endif /* LIB_SEFHT_COMPILATION */
+
+typedef struct SH_Fragment SH_Fragment;
 
-struct SH_Fragment *
-SH_Fragment_copy (struct SH_Fragment * fragment,
-		  struct SH_Error * error);
+SH_Fragment *
+SH_Fragment_copy (SH_Fragment * fragment,
+                  struct SH_Error * error);
 
 void
-SH_Fragment_free (struct SH_Fragment * fragment,
-		  struct SH_Error * error);
-
-struct SH_Text *
-SH_Fragment_to_html (struct SH_Fragment * fragment,
-		     enum HTML_MODE mode,
-		     unsigned int indent_base,
-		     unsigned int indent_step,
-		     char * indent_char,
-		     struct SH_Error * error);
-
-#endif /* _FRAGMENT_H */
+SH_Fragment_free (SH_Fragment * fragment,
+                  struct SH_Error * error);
+
+SH_Text *
+SH_Fragment_to_html (SH_Fragment * fragment,
+                     enum HTML_MODE mode,
+                     unsigned int indent_base,
+                     unsigned int indent_step,
+                     char * indent_char,
+                     struct SH_Error * error);
+
+#endif /* __FRAGMENT_H__ */
diff --git a/src/log.h b/src/lib/sefht/log.h
similarity index 84%
rename from src/log.h
rename to src/lib/sefht/log.h
index 8e5c3a7c8d95ac096118975f85277d5911044ba1..684fc6730c77ae30717b263b940ad2f102f36eac 100644
--- a/src/log.h
+++ b/src/lib/sefht/log.h
@@ -22,8 +22,12 @@
  */
 
 
-#ifndef _LOG_H
-#define _LOG_H
+#ifndef __LOG_H__
+#define __LOG_H__
+
+#if !defined (__SEFHT_H_INSIDE__) && !defined (LIB_SEFHT_COMPILATION)
+#error "Only <sefht/sefht.h> can be included directly."
+#endif
 
 #include <stdio.h>
 
@@ -33,4 +37,4 @@
 #define ERROR3(message, arg1, arg2) printf (message, arg1, arg2)
 #define ERROR4(message, arg1, arg2, arg3) printf (message, arg1, arg2, arg3)
 
-#endif /* _LOG_H */
+#endif /* __LOG_H__ */
diff --git a/src/macro.h b/src/lib/sefht/macro.h
similarity index 81%
rename from src/macro.h
rename to src/lib/sefht/macro.h
index 844daa805a74ab15b2c89c9bcfc649f7971155f6..23dd36ae5d9ec908534004e3c008691905d2fcca 100644
--- a/src/macro.h
+++ b/src/lib/sefht/macro.h
@@ -22,12 +22,16 @@
  */
 
 
-#ifndef _MACRO_H
-#define _MACRO_H
+#ifndef __MACRO_H__
+#define __MACRO_H__
+
+#if !defined (__SEFHT_H_INSIDE__) && !defined (LIB_SEFHT_COMPILATION)
+#error "Only <sefht/sefht.h> can be included directly."
+#endif
 
 #include <stdbool.h>
 
 #define TRUE (bool) 1
 #define FALSE (bool) 0
 
-#endif /* _MACRO_H */
+#endif /* __MACRO_H__ */
diff --git a/src/node_fragment.c b/src/lib/sefht/node_fragment.c
similarity index 100%
rename from src/node_fragment.c
rename to src/lib/sefht/node_fragment.c
diff --git a/src/lib/sefht/node_fragment.h b/src/lib/sefht/node_fragment.h
new file mode 100644
index 0000000000000000000000000000000000000000..7f29ed5c7fc6a20df7f1469113077e50b048267e
--- /dev/null
+++ b/src/lib/sefht/node_fragment.h
@@ -0,0 +1,117 @@
+/*
+ * node_fragment.h
+ *
+ * Copyright 2022 Jonathan Schöbel <jonathan@Ubermos-2019>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+
+#ifndef __NODE_FRAGMENT_H__
+#define __NODE_FRAGMENT_H__
+
+#if !defined (__SEFHT_H_INSIDE__) && !defined (LIB_SEFHT_COMPILATION)
+#error "Only <sefht/sefht.h> can be included directly."
+#endif
+
+#include "data.h"
+#include "text.h"
+
+#include "fragment.h"
+
+
+#ifdef LIB_SEFHT_COMPILATION
+
+struct SH_NodeFragment;
+struct SH_NodeFragment
+{
+	struct SH_Fragment base;
+
+	char * tag;
+
+	size_t child_n;
+	struct SH_Fragment ** childs;
+};
+
+#define OPEN_TAG_BEGIN "<"
+#define OPEN_TAG_END ">"
+#define CLOSE_TAG_BEGIN "</"
+#define CLOSE_TAG_END ">"
+
+//~ #define INDENT_TEXT "\t"
+#define NEWLINE "\n"
+
+#endif /* LIB_SEFHT_COMPILATION */
+
+/* TODO: no-export */
+#define INDENT_TEXT "\t"
+
+typedef struct SH_NodeFragment SH_NodeFragment;
+
+
+SH_Fragment *
+SH_NodeFragment_new (const char * tag,
+                     SH_Data * data,
+                     struct SH_Error * error);
+
+void
+SH_NodeFragment_free (SH_NodeFragment * fragment,
+                      struct SH_Error * error);
+
+SH_Fragment *
+SH_NodeFragment_copy (SH_NodeFragment * fragment,
+                      struct SH_Error * error);
+
+SH_Fragment *
+SH_NodeFragment_deepcopy (SH_NodeFragment * fragment,
+                          struct SH_Error * error);
+
+bool
+SH_Fragment_is_NodeFragment (SH_Fragment * fragment);
+
+char *
+SH_NodeFragment_get_tag (SH_NodeFragment * fragment,
+                         struct SH_Error * error);
+
+SH_Fragment *
+SH_NodeFragment_get_child (SH_NodeFragment * fragment,
+                           size_t index,
+                           struct SH_Error * error);
+
+bool
+SH_NodeFragment_is_child (SH_NodeFragment * fragment,
+                          SH_Fragment * child);
+
+bool
+SH_NodeFragment_is_descendant (SH_NodeFragment * fragment,
+                               SH_Fragment * child);
+
+bool
+SH_NodeFragment_append_child (SH_NodeFragment * fragment,
+			      SH_Fragment * child,
+                              struct SH_Error * error);
+
+SH_Text *
+SH_NodeFragment_to_html (SH_NodeFragment * fragment,
+                         enum HTML_MODE mode,
+                         unsigned int indent_base,
+                         unsigned int indent_step,
+                         char * indent_char,
+                         struct SH_Error * error);
+
+#endif /* __NODE_FRAGMENT_H__ */
diff --git a/src/sefht.h b/src/lib/sefht/sefht.h
similarity index 72%
rename from src/sefht.h
rename to src/lib/sefht/sefht.h
index 74f46dbd5ba8f931e6e3a18d1a58c777900f805b..5787fe548fcc2a5e86fdd5f48dc3088b0a8674d0 100644
--- a/src/sefht.h
+++ b/src/lib/sefht/sefht.h
@@ -22,7 +22,22 @@
  */
 
 
-#ifndef _SEFHT_H
-#define _SEFHT_H
+#ifndef __SEFHT_H__
+#define __SEFHT_H__
 
-#endif /* _SEFHT_H */
+#define __SEFHT_H_INSIDE__
+
+#include "error.h"
+#include "log.h"
+#include "macro.h"
+
+#include "cms.h"
+#include "data.h"
+#include "fragment.h"
+#include "node_fragment.h"
+#include "text.h"
+#include "validator.h"
+
+#undef __SEFHT_H_INSIDE__
+
+#endif /* __SEFHT_H__ */
diff --git a/src/text.c b/src/lib/sefht/text.c
similarity index 100%
rename from src/text.c
rename to src/lib/sefht/text.c
diff --git a/src/text.h b/src/lib/sefht/text.h
similarity index 90%
rename from src/text.h
rename to src/lib/sefht/text.h
index 2b5e74e0eaa4edc5a68d704744ba19e74e0cd067..8dcd7bdc9f367bddb77753efcb34a5e9d28e2645 100644
--- a/src/text.h
+++ b/src/lib/sefht/text.h
@@ -22,14 +22,20 @@
  */
 
 
-#ifndef _TEXT_H
-#define _TEXT_H
+#ifndef __TEXT_H__
+#define __TEXT_H__
+
+#if !defined (__SEFHT_H_INSIDE__) && !defined (LIB_SEFHT_COMPILATION)
+#error "Only <sefht/sefht.h> can be included directly."
+#endif
 
 #include <stdbool.h>
 
 #include "error.h"
 
 
+#ifdef LIB_SEFHT_COMPILATION
+
 #ifndef CHUNK_SIZE
 #define CHUNK_SIZE 64
 #endif /* CHUNK_SIZE */
@@ -54,6 +60,11 @@ struct SH_Text
 	/*@notnull@*/ struct text_segment * data;
 };
 
+#endif /* LIB_SEFHT_COMPILATION */
+
+typedef /*@abstract@*/ struct SH_Text SH_Text;
+
+
 /*@null@*/
 /*@only@*/
 struct SH_Text *
@@ -119,4 +130,4 @@ SH_Text_join (struct SH_Text * text,
 void
 SH_Text_print (const struct SH_Text * text);
 
-#endif /* _TEXT_H */
+#endif /* __TEXT_H__ */
diff --git a/src/validator.c b/src/lib/sefht/validator.c
similarity index 100%
rename from src/validator.c
rename to src/lib/sefht/validator.c
diff --git a/src/validator.h b/src/lib/sefht/validator.h
similarity index 59%
rename from src/validator.h
rename to src/lib/sefht/validator.h
index f0fd7beca52d4dd695271471c1bf1dfeb547ccc3..902d1ac7b934071a83eee1206f44a4c7769b85e0 100644
--- a/src/validator.h
+++ b/src/lib/sefht/validator.h
@@ -22,17 +22,26 @@
  */
 
 
-#ifndef _VALIDATOR_H
-#define _VALIDATOR_H
+#ifndef __VALIDATOR_H__
+#define __VALIDATOR_H__
+
+#if !defined (__SEFHT_H_INSIDE__) && !defined (LIB_SEFHT_COMPILATION)
+#error "Only <sefht/sefht.h> can be included directly."
+#endif
 
 #include <limits.h>
 #include <stdbool.h>
 
+#include "error.h"
+
 
 typedef unsigned int tag_t;
 #define TAG_ERR 0
 #define TAG_MIN 1
 #define TAG_MAX UINT_MAX
+
+#ifdef LIB_SEFHT_COMPILATION
+
 #define NEXT_TAG(tag) tag++
 
 struct SH_Tag
@@ -48,16 +57,26 @@ struct SH_Validator
 	tag_t last_tag;
 };
 
-struct SH_Validator * SH_Validator_new (struct SH_Error * error);
-void SH_Validator_free (struct SH_Validator * validator,
-			struct SH_Error * error);
+#endif /* LIB_SEFHT_COMPILATION */
+
+typedef struct SH_Validator SH_Validator;
+
+
+SH_Validator *
+SH_Validator_new (struct SH_Error * error);
+
+void
+SH_Validator_free (SH_Validator * validator,
+                   struct SH_Error * error);
 
-tag_t SH_Validator_register_tag (struct SH_Validator * validator,
-				 const char * tag,
-				 struct SH_Error * error);
+tag_t
+SH_Validator_register_tag (SH_Validator * validator,
+                           const char * tag,
+                           struct SH_Error * error);
 
 
-bool SH_Validator_check_tag (struct SH_Validator * validator,
-			     const char * tag);
+bool
+SH_Validator_check_tag (SH_Validator * validator,
+                        const char * tag);
 
-#endif /* _VALIDATOR_H */
+#endif /* __VALIDATOR_H__ */
diff --git a/src/main.c b/src/main.c
index 804fc9fcba8c5d9841d1f08c80e7cda54e00d6b3..0fa442c07b6351b4cdeff3da36be1e032d7001f2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -24,18 +24,15 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include "cms.h"
-#include "data.h"
-#include "fragment.h"
-#include "node_fragment.h"
-#include "text.h"
+
+#include <sefht/sefht.h>
 
 int main(int argc, char **argv)
 {
 	page_t page;
 
 	/* startup */
-	struct SH_Cms * cms = SH_Cms_new (NULL);
+	SH_Cms * cms = SH_Cms_new (NULL);
 	/* startup */
 
 	page = SH_Cms_register_page (cms, "Startpage", NULL);
@@ -45,11 +42,11 @@ int main(int argc, char **argv)
 	/* shutdown */
 
 
-	struct SH_Data * data;
-	struct SH_Fragment * root;
-	struct SH_Fragment * child1;
-	struct SH_Fragment * child2;
-	struct SH_Text * text;
+	SH_Data * data;
+	SH_Fragment * root;
+	SH_Fragment * child1;
+	SH_Fragment * child2;
+	SH_Text * text;
 
 	data = SH_Data_new (NULL);
 
diff --git a/src/node_fragment.h b/src/node_fragment.h
deleted file mode 100644
index fecfafe6f108d1163d92126f2abcf2c9b614df82..0000000000000000000000000000000000000000
--- a/src/node_fragment.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * node_fragment.h
- *
- * Copyright 2022 Jonathan Schöbel <jonathan@Ubermos-2019>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- *
- */
-
-
-#ifndef _NODE_FRAGMENT_H
-#define _NODE_FRAGMENT_H
-
-#include "data.h"
-#include "text.h"
-
-#include "fragment.h"
-
-
-struct SH_NodeFragment;
-struct SH_NodeFragment
-{
-	struct SH_Fragment base;
-
-	char * tag;
-
-	size_t child_n;
-	struct SH_Fragment ** childs;
-};
-
-#define OPEN_TAG_BEGIN "<"
-#define OPEN_TAG_END ">"
-#define CLOSE_TAG_BEGIN "</"
-#define CLOSE_TAG_END ">"
-
-#define INDENT_TEXT "\t"
-#define NEWLINE "\n"
-
-struct SH_Fragment *
-SH_NodeFragment_new (const char * tag,
-		     struct SH_Data * data,
-		     struct SH_Error * error);
-
-void
-SH_NodeFragment_free (struct SH_NodeFragment * fragment,
-		      struct SH_Error * error);
-
-struct SH_Fragment *
-SH_NodeFragment_copy (struct SH_NodeFragment * fragment,
-		      struct SH_Error * error);
-
-struct SH_Fragment *
-SH_NodeFragment_deepcopy (struct SH_NodeFragment * fragment,
-			  struct SH_Error * error);
-
-bool
-SH_Fragment_is_NodeFragment (struct SH_Fragment * fragment);
-
-char *
-SH_NodeFragment_get_tag (struct SH_NodeFragment * fragment,
-			 struct SH_Error * error);
-
-struct SH_Fragment *
-SH_NodeFragment_get_child (struct SH_NodeFragment * fragment,
-			   size_t index,
-			   struct SH_Error * error);
-
-bool
-SH_NodeFragment_is_child (struct SH_NodeFragment * fragment,
-			  struct SH_Fragment * child);
-
-bool
-SH_NodeFragment_is_descendant (struct SH_NodeFragment * fragment,
-			       struct SH_Fragment * child);
-
-bool
-SH_NodeFragment_append_child (struct SH_NodeFragment * fragment,
-			      struct SH_Fragment * child,
-			      struct SH_Error * error);
-
-struct SH_Text *
-SH_NodeFragment_to_html (struct SH_NodeFragment * fragment,
-			 enum HTML_MODE mode,
-			 unsigned int indent_base,
-			 unsigned int indent_step,
-			 char * indent_char,
-			 struct SH_Error * error);
-
-#endif /* _NODE_FRAGMENT_H */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 20e43f99444ce8664aea86e0a6ebe21af1775144..d0a8894ed6736692fb91b02f73cfb41431a8fca1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -12,30 +12,33 @@ TESTS += sefht_validator_test
 check_PROGRAMS = $(TESTS)
 
 AM_CPPFLAGS =
-AM_CPPFLAGS += -I$(top_srcdir)/src
+AM_CPPFLAGS += -DLIB_SEFHT_COMPILATION
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/sefht
 
 LDADD = $(CHECK_LIBS)
 
+OBJECT_PREFIX = $(top_builddir)/src/lib/sefht/libsefht_la-
+
 sefht_cms_test_SOURCES = test_cms.c
 sefht_cms_test_LDADD =
-sefht_cms_test_LDADD += $(top_builddir)/src/cms.o
-sefht_cms_test_LDADD += $(top_builddir)/src/data.o
-sefht_cms_test_LDADD += $(top_builddir)/src/validator.o
+sefht_cms_test_LDADD += $(OBJECT_PREFIX)cms.o
+sefht_cms_test_LDADD += $(OBJECT_PREFIX)data.o
+sefht_cms_test_LDADD += $(OBJECT_PREFIX)validator.o
 sefht_cms_test_LDADD += $(LDADD)
 
 sefht_data_test_SOURCES = test_data.c
 sefht_data_test_LDADD =
-sefht_data_test_LDADD += $(top_builddir)/src/data.o
-sefht_data_test_LDADD += $(top_builddir)/src/validator.o
+sefht_data_test_LDADD += $(OBJECT_PREFIX)data.o
+sefht_data_test_LDADD += $(OBJECT_PREFIX)validator.o
 sefht_data_test_LDADD += $(LDADD)
 
 sefht_node_fragment_test_SOURCES = test_node_fragment.c
 sefht_node_fragment_test_LDADD =
-sefht_node_fragment_test_LDADD += $(top_builddir)/src/node_fragment.o
-sefht_node_fragment_test_LDADD += $(top_builddir)/src/data.o
-sefht_node_fragment_test_LDADD += $(top_builddir)/src/fragment.o
-sefht_node_fragment_test_LDADD += $(top_builddir)/src/text.o
-sefht_node_fragment_test_LDADD += $(top_builddir)/src/validator.o
+sefht_node_fragment_test_LDADD += $(OBJECT_PREFIX)node_fragment.o
+sefht_node_fragment_test_LDADD += $(OBJECT_PREFIX)data.o
+sefht_node_fragment_test_LDADD += $(OBJECT_PREFIX)fragment.o
+sefht_node_fragment_test_LDADD += $(OBJECT_PREFIX)text.o
+sefht_node_fragment_test_LDADD += $(OBJECT_PREFIX)validator.o
 sefht_node_fragment_test_LDADD += $(LDADD)
 
 sefht_text_test_SOURCES = test_text.c