def _thread(obj, username, password):
			# acquire the lock until the scripts have been executed
			self._finishedResult = False
			obj._finishedLock.acquire()
			try:
				self._progressParser.reset()

				# write the profile file and run setup scripts
				util.auto_complete_values_for_join(values)

				# on unjoined DC master the nameserver must be set to the external nameserver
				if newrole == 'domaincontroller_master' and not orgValues.get('joined'):
					for i in range(1, 4):
						# overwrite these values only if they are set, because the UMC module
						# will save only changed values
						if values.get('dns/forwarder%d' % i):
							values['nameserver%d' % i] = values.get('dns/forwarder%d' % i)

				MODULE.info('saving profile values')
				util.write_profile(values)

				# unjoined DC master (that is not being converted to a basesystem) -> run the join script
				MODULE.info('runnning system setup join script')
				util.run_joinscript(self._progressParser, values, username, password, dcname, lang=str(self.locale))

				# done :)
				self._finishedResult = True

				return True
			finally:
				obj._finishedLock.release()
		def _thread(request, obj):
			# acquire the lock until the scripts have been executed
			self._finishedResult = False
			obj._finishedLock.acquire()
			try:
				subfolders = {
					'network': ['30_net'],
					'certificate': ['40_ssl'],
					'languages': ['15_keyboard', '20_language', '35_timezone'],
				}.get(request.flavor)

				self._progressParser.reset(subfolders)

				if request.flavor == 'setup':
					# adjust progress fractions for setup wizard with pre-configurred settings
					fractions = self._progressParser.fractions
					fractions['05_role/10role'] = 0
					fractions['10_basis/12domainname'] = 0
					fractions['10_basis/14ldap_basis'] = 0
					fractions['90_postjoin/10admember'] = 0
					self._progressParser.calculateFractions()

				MODULE.info('saving profile values')
				util.write_profile(values)

				if not values:
					MODULE.error('No property "values" given for save().')
					return False

				# in case of changes of the IP address, restart UMC server and web server
				# for this we ignore changes of virtual or non-default devices
				# ... no need to restart the UMC server if cleanup scripts are run anyway
				restart = False
				if not run_hooks:
					MODULE.info('Check whether ip addresses have been changed')
					for ikey, ival in values.iteritems():
						if RE_IPV4.match(ikey) or RE_IPV6_DEFAULT.match(ikey) or RE_SSL.match(ikey):
							restart = True
							break
					MODULE.info('Restart servers: %s' % restart)

				# on a joined system or on a basesystem, we can run the setup scripts
				MODULE.info('runnning system setup scripts (flavor %r)' % (request.flavor,))

				util.run_scripts(self._progressParser, restart, subfolders, lang=str(self.locale), args=script_args)

				# run cleanup scripts and appliance hooks if needed
				if run_hooks:
					util.cleanup(with_appliance_hooks=True)

				# done :)
				self._finishedResult = True
				return True
			finally:
				obj._finishedLock.release()