diff --git a/czi/source_code/azgra_lib/CMakeLists.txt b/czi/source_code/azgra_lib/CMakeLists.txt
index cec0079e319d6c6c5078af3699a6f416769159e8..4c4723d32645ff12fa47caba2fbb7902a0e85153 100644
--- a/czi/source_code/azgra_lib/CMakeLists.txt
+++ b/czi/source_code/azgra_lib/CMakeLists.txt
@@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.0.0)
 
 project(azgra)
 
+set(CMAKE_CXX_FLAGS "-Wall")
+
 add_library(${PROJECT_NAME} STATIC 
     src/stream/binary_converter.cpp
     src/stream/binary_file_stream.cpp
@@ -10,8 +12,9 @@ add_library(${PROJECT_NAME} STATIC
     src/stream/memory_bit_stream.cpp
     src/utilities/Stopwatch.cpp
     src/utilities/z_order.cpp
+    src/azgra_string.cpp
     )
 
 add_library(sub::azgra ALIAS ${PROJECT_NAME})
 
-target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include)
\ No newline at end of file
+target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include)
diff --git a/czi/source_code/azgra_lib/include/azgra/azgra_string.h b/czi/source_code/azgra_lib/include/azgra/azgra_string.h
new file mode 100644
index 0000000000000000000000000000000000000000..47c0885b3b33fa7a359bf57dd659fcb0e726761f
--- /dev/null
+++ b/czi/source_code/azgra_lib/include/azgra/azgra_string.h
@@ -0,0 +1,324 @@
+#pragma once
+
+#include <stddef.h>
+#include <vector>
+#include <assert.h>
+
+namespace azgra
+{
+constexpr char AsciiCaseOffset = 'a' - 'A';
+class SimpleString
+{
+private:
+  /**
+   * @brief Internal string memory.
+   */
+  char *_string = nullptr;
+  /**
+   * @brief Length of this string.
+   */
+  size_t _length = 0;
+
+  /**
+   * @brief Allocates memory for string, with size of sizeof(char) * length
+   */
+  static char *alloc_string(const size_t &length);
+  /**
+   * @brief Reallocates memory, to bigger size, copying old content.
+   */
+  static char *realloc_string(const size_t &length, const char* oldString, const size_t oldLen);
+  /**
+   * @brief Free string memory block.
+   */
+  static void free_string(char *memory);
+
+  /**
+   * @brief Get size of c string.
+   * 
+   * @param cString String to get size of.
+   * @return size_t Size of cString
+   */
+  static size_t c_string_length(const char *cString);
+
+  /**
+   * @brief Internal concatenation function.
+   * 
+   * @param string String to add to current string.
+   * @param length Length of String.
+   */
+  void internal_concat(const char *string, const size_t length);
+
+  /**
+   * @brief Initalize this string memory and fields.
+   * 
+   * @param string String to initialize from.
+   */
+  void internal_initalize(const char *string);
+
+  /**
+   * @brief Construct a new Simple String with already allocated memory.
+   * 
+   * @param cString Allocated string.
+   * @param length Length of allocated string.
+   * @param noAlloc Must be true.
+   */
+  SimpleString(char *cString, const size_t length, bool noAlloc = false);
+public:
+  /**
+   * @brief Construct a new Simple String object.
+   * 
+   * @param cString Char array to create string from.
+   */
+  SimpleString(const char *cString);
+  
+  /**
+   * @brief Get the c string object
+   * 
+   * @return const char* Char array (C like string).
+   */
+  const char *get_c_string() const;
+  
+  /**
+   * @brief Concatenate cString to this string.
+   * 
+   * @param cString String to concatenate.
+   */
+  void concat(const char *cString);
+
+  /**
+   * @brief Get length of this string.
+   * 
+   * @return size_t Length of string.
+   */
+  size_t length() const;
+
+  /**
+   * @brief Get index of first match.
+   * 
+   * @param c Char to find.
+   * @param fromIndex Index from which search will begin.
+   * @return int Index of first match or -1 if not found.
+   */
+  int index_of(const char &c, const size_t fromIndex = 0) const;
+  
+  /**
+   * @brief Get index of first matched character in string.
+   * 
+   * @param string String to find.
+   * @param fromIndex Index from which search will begin.
+   * @return int Index of first matched character or -1 if not found.
+   */
+  int index_of(const char *string, const size_t fromIndex = 0) const;
+
+  /**
+   * @brief Get index of last match.
+   * 
+   * @param c Char to find.
+   * @param fromIndex Index from which search will begin.
+   * @return int Index of last match or -1 if not found.
+   */
+  int last_index_of(const char &c, const size_t fromIndex = 0) const;
+
+  /**
+   * @brief Get index of last match.
+   * 
+   * @param c Character to find.
+   * @param fromIndex Index from which search will begin.
+   * @param toIndex Index to which search will continue.
+   * @return int Index of last match or -1 if not found.
+   */
+  int last_index_of(const char &c, const size_t fromIndex, const size_t toIndex) const;
+
+  /**
+   * @brief Get index of last match. 
+   * 
+   * @param string String to find.
+   * @param fromIndex Index from which search will begin.
+   * @return int Index of last match or -1 if not found.
+   */
+  int last_index_of(const char *string, const size_t fromIndex = 0) const;
+
+  /**
+   * @brief Check if given character is in this string.
+   * 
+   * @param c Character to find.
+   * @return true If char was found in this string.
+   * @return false If char wasn't found in this string.
+   */
+  bool contains(const char &c) const;
+
+  /**
+   * @brief Check if given string is in this string.
+   * 
+   * @param string String to find.
+   * @return true If string was found in this string.
+   * @return false If string wasn't found in this string.
+   */
+  bool contains(const char *string) const;
+
+  /**
+   * @brief Get number of times character is contained in this string.
+   * 
+   * @param c Char to find.
+   * @return size_t Number of occurencies.
+   */
+  size_t count(const char &c) const;
+
+  /**
+   * @brief Get number of times string is contained in this string.
+   * 
+   * @param string String to find.
+   * @return size_t Number of occurencies.
+   */
+  size_t count(const char *string) const;
+
+  /**
+   * @brief Check if string starts with character.
+   * 
+   * @param c Character to check.
+   * @return true String starts with required character.
+   * @return false String doesn't start with required character.
+   */
+  bool starts_with(const char &c) const;
+
+  /**
+   * @brief Check if string starts with string.
+   * 
+   * @param c String to check.
+   * @return true String starts with required string.
+   * @return false String doesn't start with required string.
+   */
+  bool starts_with(const char *string) const;
+
+  /**
+   * @brief Check if string ends with character.
+   * 
+   * @param c Character to check.
+   * @return true String ends with required character.
+   * @return false String doesn't end with required character.
+   */
+  bool ends_with(const char &c) const;
+
+  /**
+   * @brief Check if string ends with string.
+   * 
+   * @param c String to check.
+   * @return true String ends with required string.
+   * @return false String doesn't end with required string.
+   */
+  bool ends_with(const char *string) const;
+
+  /**
+   * @brief Check if this string is equal to the another one.
+   * 
+   * @param string String to check.
+   * @return true Strings are equal.
+   * @return false Strings aren't equal.
+   */
+  bool equals(const SimpleString &string) const;
+
+  /**
+   * @brief Check if this string is equal to the another one.
+   * 
+   * @param string String to check.
+   * @return true Strings are equal.
+   * @return false Strings aren't equal.
+   */
+  bool equals(const char *string) const;
+
+  /**
+   * @brief Transform characters to upper-case.
+   */
+  void to_upper();
+
+  /**
+   * @brief Transform characters to lower-case.
+   */
+  void to_lower();
+
+  /**
+   * @brief Replace all old characters with new characters.
+   * 
+   * @param oldChar Charater to replace.
+   * @param newChar Replacement charater.
+   */
+  void replace(const char &oldChar, const char &newChar);
+
+  /**
+   * @brief Replace all old substrings with new strings.
+   * 
+   * @param oldChar Substring to replace.
+   * @param newChar Replacement string.
+   */
+  void replace(const char *oldString, const char *newString);
+
+  /**
+   * @brief Remove all occurrencies of character.
+   * 
+   * @param c Character to remove.
+   */
+  void remove(const char &c);
+
+  /**
+   * @brief Remove all occurrencies of substring.
+   * 
+   * @param c Substring to remove.
+   */
+  void remove(const char *oldString);
+
+  /**
+   * @brief Create substring from given index to end of the string.
+   * 
+   * @param fromIndex Index from which to create substring.
+   * @return SimpleString Substring from given index.
+   */
+  SimpleString substring(const size_t fromIndex) const;
+
+  /**
+   * @brief Create substring from given index with length.
+   * 
+   * @param fromIndex Index from which to create substring
+   * @param length Length of substring.
+   * @return SimpleString Substring from given index, with length.
+   */
+  SimpleString substring(const size_t fromIndex, const size_t length) const;
+
+  /**
+   * @brief Split string by separator to multiple strings.
+   * 
+   * @param separator Separator.
+   * @return std::vector<SimpleString> Vector of strings.
+   */
+  std::vector<SimpleString> split(const char &separator) const;
+
+  /**
+   * @brief Conversion to c string, char array.
+   * 
+   * @return const char* C like string
+   */
+  operator const char*() const;
+
+  /**
+   * @brief Character indexing.
+   * 
+   * @param index Index of character in string.
+   * @return char& Reference to character.
+   */
+  char &operator[](const int &index);
+  
+  void operator=(const char *cString);
+  bool operator==(const char *cString) const;
+  bool operator==(const SimpleString &string) const;
+  void operator+=(const char *cString);
+  SimpleString operator+(const char *cString) const;
+
+  /**
+   * @brief Create string by replicating.
+   * 
+   * @param cString String to replicate.
+   * @param replicationCount Number of replications.
+   * @return SimpleString Replicated string.
+   */
+  static SimpleString replicate(const char* cString, const int replicationCount);
+};
+} // namespace azgra
\ No newline at end of file
diff --git a/czi/source_code/azgra_lib/src/azgra_string.cpp b/czi/source_code/azgra_lib/src/azgra_string.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b07e37f21cef48dfd78500225a00af113be38e6d
--- /dev/null
+++ b/czi/source_code/azgra_lib/src/azgra_string.cpp
@@ -0,0 +1,496 @@
+#include "azgra_string.h"
+
+namespace azgra
+{
+//TODO: Add asserts.
+
+char *SimpleString::alloc_string(const size_t &length)
+{
+    char *memory = static_cast<char *>(::operator new(sizeof(char) * length));
+    return memory;
+}
+
+char *SimpleString::realloc_string(const size_t &length, const char* oldString, const size_t oldLen)
+{
+    char *memory = alloc_string(length);
+    for (size_t i = 0; i < oldLen; i++)
+        memory[i] = oldString[i];
+    return memory;
+}
+
+void SimpleString::free_string(char *memory)
+{
+    if (memory != nullptr)
+    {
+        ::operator delete(memory);
+        memory = nullptr;
+    }
+}
+
+size_t SimpleString::c_string_length(const char *cString)
+{
+    size_t len = 0;
+    int i = 0;
+
+    for (i = 0; cString[i] != 0; i++)
+        len++;
+
+    return len;
+}
+
+void SimpleString::internal_initalize(const char *string)
+{
+    size_t inputStringLen = c_string_length(string);
+    _length = inputStringLen;
+
+    _string = alloc_string(_length);
+
+    for (size_t i = 0; i < inputStringLen; i++)
+        _string[i] = string[i];
+}
+
+SimpleString::SimpleString(char *cString, const size_t length, bool noAlloc)
+{   
+    assert(noAlloc);
+    _string = cString;
+    _length = length;
+}
+
+SimpleString::operator const char *() const
+{
+    return _string;
+}
+
+char &SimpleString::operator[](const int &index)
+{
+    return _string[index];
+}
+
+void SimpleString::operator=(const char *cString)
+{
+    free_string(_string);
+    internal_initalize(cString);
+}
+
+void SimpleString::operator+=(const char *cString)
+{
+    concat(cString);
+}
+
+SimpleString SimpleString::operator+(const char *cString) const
+{
+    SimpleString result(_string);
+    result.concat(cString);
+    return result;
+}
+
+bool SimpleString::operator==(const char *cString) const
+{
+    return equals(cString);
+}
+bool SimpleString::operator==(const SimpleString &string) const
+{
+    return equals(string);
+}
+
+SimpleString::SimpleString(const char *cString)
+{
+    internal_initalize(cString);
+}
+
+void SimpleString::internal_concat(const char *string, const size_t length)
+{
+    size_t newLength = _length + length;
+    char *newString = realloc_string(newLength, _string, _length);
+
+    free_string(_string);
+
+    _string = newString;
+
+    for (size_t i = _length; i < newLength; i++)
+        _string[i] = string[i - _length];
+
+    _length = newLength;
+}
+
+void SimpleString::concat(const char *cString)
+{
+    size_t cStringLen = c_string_length(cString);
+    internal_concat(cString, cStringLen);
+}
+
+const char *SimpleString::get_c_string() const
+{
+    return _string;
+}
+
+size_t SimpleString::length() const
+{
+    return _length;
+}
+
+int SimpleString::index_of(const char &c, const size_t fromIndex) const
+{
+    for (size_t i = fromIndex; i < _length; i++)
+    {
+        if (_string[i] == c)
+        {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int SimpleString::index_of(const char *string, const size_t fromIndex) const
+{
+    size_t matchLen = c_string_length(string);
+    if (matchLen > _length)
+    {
+        return -1;
+    }
+
+    size_t searchFrom = fromIndex;
+    int indexOfFirstChar = index_of(string[0], searchFrom);
+    bool found = false;
+
+    while (indexOfFirstChar != -1)
+    {
+        if (indexOfFirstChar + (matchLen - 1) > _length)
+            return -1;
+
+        found = true;
+        for (size_t matchIndex = 1; matchIndex < matchLen; matchIndex++)
+        {
+            if (_string[indexOfFirstChar + matchIndex] != string[matchIndex])
+            {
+                found = false;
+                break;
+            }
+        }
+
+        if (found)
+            return indexOfFirstChar;
+        else
+        {
+            searchFrom = indexOfFirstChar + 1;
+            indexOfFirstChar = index_of(string[0], searchFrom);
+        }
+    }
+
+    return -1;
+}
+
+int SimpleString::last_index_of(const char &c, const size_t fromIndex) const
+{
+    return last_index_of(c, fromIndex, _length - 1);
+}
+
+int SimpleString::last_index_of(const char &c, const size_t fromIndex, const size_t toIndex) const
+{
+    for (int i = (int)toIndex; i >= (int)fromIndex; i--)
+    {
+        if (_string[i] == c)
+        {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int SimpleString::last_index_of(const char *string, const size_t fromIndex) const
+{
+    size_t matchLen = c_string_length(string);
+    if (matchLen > _length)
+    {
+        return -1;
+    }
+
+    size_t searchUpperBound = _length - 1;
+    int indexOfLastChar = last_index_of(string[matchLen - 1], 0, searchUpperBound);
+    bool found = false;
+
+    while (indexOfLastChar != -1)
+    {
+        if (indexOfLastChar - (matchLen - 1) < fromIndex)
+            return -1;
+
+        found = true;
+        for (size_t matchIndex = 1; matchIndex < matchLen; matchIndex++)
+        {
+            if (_string[indexOfLastChar - matchIndex] != string[matchLen - matchIndex - 1])
+            {
+                found = false;
+                break;
+            }
+        }
+
+        if (found)
+            return indexOfLastChar - (matchLen - 1);
+        else
+        {
+            searchUpperBound = indexOfLastChar - 1;
+            indexOfLastChar = last_index_of(string[matchLen - 1], 0, searchUpperBound);
+        }
+    }
+
+    return -1;
+}
+
+bool SimpleString::contains(const char &c) const
+{
+    return (index_of(c) != -1);
+}
+
+bool SimpleString::contains(const char *string) const
+{
+    return (index_of(string) != -1);
+}
+
+size_t SimpleString::count(const char &c) const
+{
+    size_t result = 0;
+    size_t fromIndex = 0;
+
+    int matchIndex = index_of(c, fromIndex);
+
+    while (matchIndex != -1)
+    {
+        ++result;
+        fromIndex = matchIndex + 1;
+        matchIndex = index_of(c, fromIndex);
+    }
+    return result;
+}
+
+size_t SimpleString::count(const char *string) const
+{
+    size_t result = 0;
+    size_t fromIndex = 0;
+    size_t matchLen = c_string_length(string);
+
+    int matchIndex = index_of(string, fromIndex);
+    while (matchIndex != -1)
+    {
+        ++result;
+        fromIndex = matchIndex + matchLen;
+        matchIndex = index_of(string, fromIndex);
+    }
+    return result;
+}
+
+bool SimpleString::starts_with(const char &c) const
+{
+    return (index_of(c) == 0);
+}
+
+bool SimpleString::starts_with(const char *string) const
+{
+    return (index_of(string) == 0);
+}
+
+bool SimpleString::ends_with(const char &c) const
+{
+    return (last_index_of(c) == (long)(_length - 1));
+}
+
+bool SimpleString::ends_with(const char *string) const
+{
+    return (last_index_of(string) == (long)(_length - c_string_length(string)));
+}
+
+bool SimpleString::equals(const SimpleString &string) const
+{
+    return equals(string._string);
+}
+
+bool SimpleString::equals(const char *string) const
+{
+    if (_length != c_string_length(string))
+        return false;
+
+    for (size_t i = 0; i < _length; i++)
+    {
+        if (_string[i] != string[i])
+            return false;
+    }
+    return true;
+}
+
+void SimpleString::to_upper()
+{
+    for (size_t i = 0; i < _length; i++)
+    {
+        char c = _string[i];
+        if (c >= 'a' && c <= 'z')
+            _string[i] -= AsciiCaseOffset;
+    }
+}
+
+void SimpleString::to_lower()
+{
+    for (size_t i = 0; i < _length; i++)
+    {
+        char c = _string[i];
+        if (c >= 'A' && c <= 'Z')
+            _string[i] += AsciiCaseOffset;
+    }
+}
+
+void SimpleString::replace(const char &oldChar, const char &newChar)
+{
+    for (size_t i = 0; i < _length; i++)
+    {
+        if (_string[i] == oldChar)
+            _string[i] = newChar;
+    }
+}
+
+// void SimpleString::replace(const SimpleString &oldString, const SimpleString &newString)
+// {
+//     replace(oldString._string, newString._string);
+// }
+
+void SimpleString::replace(const char *oldString, const char *newString)
+{
+    size_t matchLen = c_string_length(oldString);
+    size_t matchCount = count(oldString);
+    if (matchCount == 0 || matchLen == 0)
+        return;
+
+    size_t replaceStringLen = c_string_length(newString);
+    size_t newLength = _length - (matchCount * matchLen) + (matchCount * replaceStringLen);
+    char *newStringMemory = alloc_string(newLength);
+
+    size_t searchFrom = 0;
+    size_t newStringIndex = 0;
+    int index = index_of(oldString, searchFrom);
+
+    while (index != -1)
+    {
+        // Copy all in front of match.
+        for (int i = searchFrom; i < index; i++)
+            newStringMemory[newStringIndex++] = _string[i];
+
+        // Copy replace string into new string.
+        for (size_t i = 0; i < replaceStringLen; i++)
+        {
+            newStringMemory[newStringIndex++] = newString[i];
+        }
+
+        searchFrom = index + matchLen;
+        index = index_of(oldString, searchFrom);
+    }
+
+    // Copy remaining old content.
+    for (size_t i = searchFrom; i < _length; i++)
+        newStringMemory[newStringIndex++] = _string[i];
+
+    free_string(_string);
+    _string = newStringMemory;
+    _length = newLength;
+}
+
+void SimpleString::remove(const char &c)
+{
+    size_t removeCount = count(c);
+    if (removeCount == 0)
+        return;
+
+    size_t newLength = _length - removeCount;
+    char *newString = alloc_string(newLength);
+    size_t index = 0;
+    for (size_t i = 0; i < _length; i++)
+    {
+        if (_string[i] != c)
+        {
+            newString[index++] = _string[i];
+        }
+    }
+
+    free_string(_string);
+    _length = newLength;
+    _string = newString;
+}
+
+void SimpleString::remove(const char *string)
+{
+    size_t matchLen = c_string_length(string);
+    if (matchLen == 0)
+        return;
+
+    size_t matchCount = count(string);
+    size_t newLen = _length - (matchCount * matchLen);
+
+    char *newString = alloc_string(newLen);
+
+    size_t searchFrom = 0;
+    size_t newStringIndex = 0;
+    int index = index_of(string, searchFrom);
+
+    while (index != -1)
+    {
+        // Copy all in front of match.
+        for (int i = searchFrom; i < index; i++)
+            newString[newStringIndex++] = _string[i];
+
+        searchFrom = index + matchLen;
+        index = index_of(string, searchFrom);
+    }
+
+    // Copy remaining old content.
+    for (size_t i = searchFrom; i < _length; i++)
+        newString[newStringIndex++] = _string[i];
+
+    free_string(_string);
+    _string = newString;
+    _length = newLen;
+}
+SimpleString SimpleString::substring(const size_t fromIndex) const
+{
+    size_t len = _length - fromIndex;
+
+    char *subsMemory = alloc_string(len);
+    SimpleString result(subsMemory);
+    for (size_t i = fromIndex; i < _length; i++)
+    {
+        result[i - fromIndex] = _string[i];
+    }
+    return result;
+}
+
+SimpleString SimpleString::substring(const size_t fromIndex, const size_t length) const
+{
+    char *subsMemory = alloc_string(length);
+    SimpleString result(subsMemory);
+
+    for (size_t i = fromIndex; i < fromIndex + length; i++)
+    {
+        result[i - fromIndex] = _string[i];
+    }
+
+    return result;
+}
+
+SimpleString SimpleString::replicate(const char* cString, const int replicationCount)
+{
+    size_t replLen = c_string_length(cString);
+    size_t resultLen = replLen * replicationCount;
+    char* resultMemory = alloc_string(resultLen);
+
+    SimpleString result(resultMemory, resultLen, true);
+
+    for(int repl = 0; repl < replicationCount; repl++)
+    {
+        for(size_t charIndex = 0; charIndex < replLen; charIndex++)
+        {
+            result[(repl*replLen) + charIndex] = cString[charIndex];
+        }
+    }
+    return result;
+}
+
+/*
+std::vector<SimpleString> SimpleString::split(const char &separator) const;
+static SimpleString SimpleString::empty();
+*/
+} // namespace azgra