private GameObject createGameObject(IGameObjectType type, Class<? extends GameObject> classType) {
		GameObject result = null;

		try {
			loadGameObjectType(type);
			if (gameObjectTypeCache.containsKey(type)) {
				Map<String, String> attributeKeyValueList = gameObjectTypeCache.get(type);

				if (attributeKeyValueList.containsKey(LOTDConstants.INI_KEY_ABILITY_CLASS_FILE_PATH)) {
					// load a specific class file instead of the general one
					String classFilePath = attributeKeyValueList.get(LOTDConstants.INI_KEY_ABILITY_CLASS_FILE_PATH);
					classFilePath = classFilePath.replaceAll("/", ".");
					Object newInstance = Class.forName(classFilePath).newInstance();
					if (newInstance instanceof GameObject)
						result = (GameObject) newInstance;
					else
						throw new Exception("Trying to create a custom gameObject that does not extend from GameObject: " + attributeKeyValueList.get(LOTDConstants.INI_KEY_ABILITY_CLASS_FILE_PATH));
				} else {
					// load the general class file
					result = classType.newInstance();
				}

				// check if unittype or itemtype has abilities to be initialized
				// if yes -> create an ability set for the result gameObject
				// this set is then filled with the ReflectionUtil
				if (attributeKeyValueList.containsKey(LOTDConstants.GAME_OBJECT_KEY_UNIT_ABILITIES) || attributeKeyValueList.containsKey(LOTDConstants.GAME_OBJECT_KEY_ITEM_ABILITIES)) {
					if (result instanceof Unit)
						((Unit) result).setAbilities(new HashSet<Ability>());
					else if (result instanceof Item)
						((Item) result).setAbilities(new HashSet<Ability>());
				}

				for (Entry<String, String> entry : attributeKeyValueList.entrySet()) {
					// initialize new unit with its default values taken from its unitType
					String attributeToSet = entry.getKey();
					if (LOTDConstants.INI_KEY_ABILITY_CLASS_FILE_PATH.equals(attributeToSet)) {
						// ignore this attribute because it is handeled above when creating 
						// the correct instance for the 'result' variable
						continue;
					}

					String attributeValueToSet = entry.getValue();

					// check for special key format that is used to initialize Map<?,?> type attributes
					// f.e. damage[NATURE]=3
					// new format should be damage=NATURE.3 for the ReflectionUtil to work
					if (attributeToSet.contains("[")) {
						String[] split = attributeToSet.split(Pattern.quote("["));
						if (split.length == 2) {
							attributeToSet = split[0];
							attributeValueToSet = split[1].substring(0, split[1].length() - 1) + "." + attributeValueToSet;
						} else
							throw new Exception("Incorrect format for initializing a Map<?,?> type attribute: " + entry.getKey());
					}

					Class<?> attributeType = null;
					Method setterMethod = null;
					Method getterMethod = null;

					if (result instanceof Hero && setterMethodsHero.containsKey(attributeToSet)) {
						SimpleEntry<Class<?>, Method> classTypeMethodPairSetter = setterMethodsHero.get(attributeToSet);
						attributeType = classTypeMethodPairSetter.getKey();
						setterMethod = classTypeMethodPairSetter.getValue();
					} else if (result instanceof Unit && setterMethodsUnit.containsKey(attributeToSet) && getterMethodsUnit.containsKey(attributeToSet)) {
						SimpleEntry<Class<?>, Method> classTypeMethodPairSetter = setterMethodsUnit.get(attributeToSet);
						attributeType = classTypeMethodPairSetter.getKey();
						setterMethod = classTypeMethodPairSetter.getValue();
						getterMethod = getterMethodsUnit.get(attributeToSet).getValue();
					} else if (result instanceof Item && setterMethodsItem.containsKey(attributeToSet)) {
						SimpleEntry<Class<?>, Method> classTypeMethodPairSetter = setterMethodsItem.get(attributeToSet);
						attributeType = classTypeMethodPairSetter.getKey();
						setterMethod = classTypeMethodPairSetter.getValue();
					} else if (result instanceof Ability && setterMethodsAbility.containsKey(attributeToSet)) {
						SimpleEntry<Class<?>, Method> classTypeMethodPairSetter = setterMethodsAbility.get(attributeToSet);
						attributeType = classTypeMethodPairSetter.getKey();
						setterMethod = classTypeMethodPairSetter.getValue();
					} else if (result instanceof Buff && setterMethodsBuff.containsKey(attributeToSet)) {
						SimpleEntry<Class<?>, Method> classTypeMethodPairSetter = setterMethodsBuff.get(attributeToSet);
						attributeType = classTypeMethodPairSetter.getKey();
						setterMethod = classTypeMethodPairSetter.getValue();
					} else if (result instanceof CollidingGameObject && setterMethodsCollidingGameObject.containsKey(attributeToSet)) {
						SimpleEntry<Class<?>, Method> classTypeMethodPairSetter = setterMethodsCollidingGameObject.get(attributeToSet);
						attributeType = classTypeMethodPairSetter.getKey();
						setterMethod = classTypeMethodPairSetter.getValue();
					} else if (setterMethodsGameObject.containsKey(attributeToSet)) {
						SimpleEntry<Class<?>, Method> classTypeMethodPairSetter = setterMethodsGameObject.get(attributeToSet);
						attributeType = classTypeMethodPairSetter.getKey();
						setterMethod = classTypeMethodPairSetter.getValue();
					}

					if (setterMethod != null && !ReflectionUtil.invokeMethod(setterMethod, getterMethod, result, attributeType, attributeToSet, attributeValueToSet))
						throw new Exception("GameObject could not be correctly initialized");
				}

				// set the correct name and description taken from the labels.properties file
				GameLogic.INSTANCE.setNameAndDescription(result);

				// and add it to the gameObjectCache for later use like collision detection, etc.
				gameObjectCache.add(result);

				// finally create the sprite if this type has a texturePath defined
				createSprite(result, attributeKeyValueList);

				if (LOGGER.isDebugEnabled() && result != null)
					LOGGER.debug("Successfully created gameObject of type '" + type + "': " + result);
			} else
				throw new Exception("Couldn't create gameObject of type '" + type + "' because the gameObjectType is not loaded");
		} catch (Exception e) {
			LOGGER.fatal("Error when trying to create gameObject of type " + type, e);
		}

		return result;
	}