Process timezone casting and conversion.

def _process_tz(self, dt, naive, tz):
		"""Process timezone casting and conversion."""
		
		def _tz(t):
			if t in (None, 'naive'):
				return t
			
			if t == 'local':
				if __debug__ and not localtz:
					raise ValueError("Requested conversion to local timezone, but `localtz` not installed.")
				
				t = localtz
			
			if not isinstance(t, tzinfo):
				if __debug__ and not localtz:
					raise ValueError("The `pytz` package must be installed to look up timezone: " + repr(t))
				
				t = get_tz(t)
			
			if not hasattr(t, 'normalize') and get_tz:  # Attempt to handle non-pytz tzinfo.
				t = get_tz(t.tzname(dt))
			
			return t
		
		naive = _tz(naive)
		tz = _tz(tz)
		
		if not dt.tzinfo and naive:
			if hasattr(naive, 'localize'):
				dt = naive.localize(dt)
			else:
				dt = dt.replace(tzinfo=naive)
		
		if not tz:
			return dt
		
		if hasattr(tz, 'normalize'):
			dt = tz.normalize(dt.astimezone(tz))
		elif tz == 'naive':
			dt = dt.replace(tzinfo=None)
		else:
			dt = dt.astimezone(tz)  # Warning: this might not always be entirely correct!
		
		return dt