docs: async function createThingDTO(user, parentThing, thing, isSuperAdministrator) {
  
  	async function getUsersInfosAsync(thing) {
  		
  		if (!thing)
  			throw new utils.ErrorCustom(httpStatusCodes.INTERNAL_SERVER_ERROR, "Thing can't be null", 32);
  		
  		let usersInfosDTOs = [];
  		
  		for(let r of thing.usersRights) {
  
  			let userId = r.userId;
  			let username = r.username;
  		
  			if (!userId && !username)
  				throw new utils.ErrorCustom(httpStatusCodes.INTERNAL_SERVER_ERROR, "userId or username must be not empty", 33);
  		
  			let userInfoDTO = new UserInfoDTO();
  				
  			userInfoDTO.id = userId;
  			userInfoDTO.name = username;
  				
  			let user = userId ? await usersManager.findUserById(userId) : await	usersManager.findUserByUsername(username);
  			if (user) {
  				userInfoDTO.id = user._id;
  				userInfoDTO.name = user.name;
  			}
  			if (userInfoDTO.id)
  				userInfoDTO.id = userInfoDTO.id.toString();
  		
  			usersInfosDTOs.push(userInfoDTO);
  		}
  		
  		return usersInfosDTOs;
  	}
  	async function thingToThingDTO(accessThingUserClaims, thing, thingUserRights, pos) {
  		
  		if (!accessThingUserClaims)
  			throw new utils.ErrorCustom(httpStatusCodes.INTERNAL_SERVER_ERROR, "No Correct User's Thing Claims ", 31);
  		
  		let thingDTO = new ThingDTO();
  		
  		thingDTO.id = thing._id;
  		// TODO: Insert Claims control?
  		thingDTO.pos = pos;
  		
  		if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadCreationDate) != 0)
  			thingDTO.creationDate = thing.creationDate;
  		
  		if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadName) != 0)
  			thingDTO.name = thing.name;
  		
  		if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadKind) != 0)
  			thingDTO.kind = thing.kind;
  		
  		if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadDeletedStatus) != 0)
  		{
  			thingDTO.deletedStatus = thing.deletedStatus;
  			thingDTO.deletedDate = thing.deletedDate;
  		}
  		
  		if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadPublicReadClaims) != 0)
  			thingDTO.publicReadClaims = thing.publicReadClaims;
  		if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadPublicChangeClaims) != 0)
  			thingDTO.publicChangeClaims = thing.publicChangeClaims;
  		
  		if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadEveryoneReadClaims) != 0)
  			thingDTO.everyoneReadClaims = thing.everyoneReadClaims;
  		if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadEveryoneChangeClaims) != 0)
  			thingDTO.everyoneChangeClaims = thing.everyoneChangeClaims;
  		
  		if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadValue) != 0)
  			thingDTO.value = thing.value;
  		
  		if (thingUserRights && (accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadThingUserRights) != 0) {
  			if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadThingUserStates) != 0)
  				thingDTO.userStatus = thingUserRights.userStatus;
  			
  			if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadThingUserRole) != 0)
  				thingDTO.userRole = thingUserRights.userRole;
  		
  			if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadThingUserVisibility) != 0)
  				thingDTO.userVisibility = thingUserRights.userVisibility;
  		
  			if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadThingUserReadClaims) != 0)
  				thingDTO.userReadClaims = thingUserRights.userReadClaims;
  			if ((accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadThingUserChangeClaims) != 0)
  				thingDTO.userChangeClaims = thingUserRights.userChangeClaims;
  
  			// TODO: Insert Claims control? Is it useful? Test during shortPin implementation
  			thingDTO.shortPin = thingUserRights.shortPin;
  		}
  		
  		thingDTO.usersInfos = (accessThingUserClaims.read & thConstants.ThingUserReadClaims.CanReadThingUserRights) == 0 ? [] : await getUsersInfosAsync(thing);
  		
  		return thingDTO;
  	}
  
  	let loggedInThingUserClaims = getThingUserClaims(user, thing, isSuperAdministrator);
  
  	let loggedInThingUserRights = {
  		userRole : (isSuperAdministrator == true) ? thConstants.ThingUserRoles.Administrator : thConstants.ThingUserRoles.User,
  		userStatus : thConstants.ThingUserStates.Ok,
  		userVisibility : thConstants.ThingUserVisibility.Visible,
  		userReadClaims : loggedInThingUserClaims.read,
  		userChangeClaims : loggedInThingUserClaims.change,
  		// TODO: Is it useful? Test during shortPin implementation
  		shortPin : 0
  	};
  
  	if (user) {
  		let loggedInThingUserRights1 = getThingUserRights(user._id, user.username, thing);
  		if (loggedInThingUserRights1)
  		{
  			loggedInThingUserRights.userRole = loggedInThingUserRights1.userRole;
  			loggedInThingUserRights.userStatus = loggedInThingUserRights1.userStatus;
  			loggedInThingUserRights.userVisibility = loggedInThingUserRights1.userVisibility;
  			loggedInThingUserRights.shortPin = loggedInThingUserRights1.shortPin;
  			loggedInThingUserRights.userReadClaims = loggedInThingUserRights1.userReadClaims;
  			loggedInThingUserRights.userChangeClaims = loggedInThingUserRights1.userChangeClaims;
  			// TODO: Is useful? Test during shortPin implementation
  			loggedInThingUserRights.shortPin = loggedInThingUserRights1.shortPin;
  		}
  	}
  
  	let thingPosition = getThingPosition(user, parentThing, thing);
  	let thingPos = thingPosition ? thingPosition.pos : thConstants.DefaultThingPos;
  
  	return await thingToThingDTO(loggedInThingUserClaims, thing, loggedInThingUserRights, thingPos);
  }