JUNEAU-126 Serializers should serialize Iterators and Enumerations by
default.
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/DefaultSwapsTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/DefaultSwapsTest.java
new file mode 100644
index 0000000..f53e79c
--- /dev/null
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/DefaultSwapsTest.java
@@ -0,0 +1,666 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.transforms;
+
+import static org.junit.Assert.assertEquals;
+
+import java.time.*;
+import java.time.chrono.*;
+import java.time.format.*;
+import java.time.temporal.*;
+import java.util.*;
+
+import javax.xml.datatype.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.testutils.*;
+import org.apache.juneau.transform.*;
+import org.apache.juneau.utils.*;
+import org.junit.*;
+import org.junit.runners.*;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class DefaultSwapsTest {
+
+	//------------------------------------------------------------------------------------------------------------------
+	// Setup
+	//------------------------------------------------------------------------------------------------------------------
+
+	@BeforeClass
+	public static void beforeClass() {
+		TestUtils.setTimeZone("GMT-5");
+	}
+
+	@AfterClass
+	public static void afterClass() {
+		TestUtils.unsetTimeZone();
+	}
+
+	private static final WriterSerializer SERIALIZER = SimpleJsonSerializer.DEFAULT;
+
+	private void test(String expected, Object o) throws Exception {
+		assertEquals(expected, SERIALIZER.serialize(o));
+	}
+
+	private void test(String expected, Object o, PojoSwap<?,?> swap) throws Exception {
+		assertEquals(expected, SERIALIZER.builder().pojoSwaps(swap).build().serializeToString(o));
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(Enumeration.class, new EnumerationSwap());
+	//------------------------------------------------------------------------------------------------------------------
+	private static Vector<String> A = new Vector<>();
+	static {
+		A.add("foo");
+		A.add("bar");
+	}
+
+	public static class ASwap extends StringSwap<Enumeration<?>> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, Enumeration<?> o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class ABean {
+		public Enumeration<String> f1 = A.elements();
+		@Swap(ASwap.class)
+		public Enumeration<String> f2 = A.elements();
+	}
+
+	@Test
+	public void a01_Enumeration() throws Exception {
+		test("['foo','bar']", A.elements());
+	}
+
+	@Test
+	public void a02_Enumeration_overrideSwap() throws Exception {
+		test("'FOO'", A.elements(), new ASwap());
+	}
+
+	@Test
+	public void a03_Enumeration_overrideAnnotation() throws Exception {
+		test("{f1:['foo','bar'],f2:'FOO'}", new ABean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(Iterator.class, new IteratorSwap());
+	//------------------------------------------------------------------------------------------------------------------
+	private static List<String> B = new AList<String>().appendAll("foo","bar");
+
+	public static class BSwap extends StringSwap<Iterator<?>> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, Iterator<?> o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class BBean {
+		public Iterator<?> f1 = B.iterator();
+		@Swap(BSwap.class)
+		public Iterator<?> f2 = B.iterator();
+	}
+
+	@Test
+	public void b01_Iterator() throws Exception {
+		test("['foo','bar']", B.iterator());
+	}
+
+	@Test
+	public void b02_Iterator_overrideSwap() throws Exception {
+		test("'FOO'", B.iterator(), new BSwap());
+	}
+
+	@Test
+	public void b03_Iterator_overrideAnnotation() throws Exception {
+		test("{f1:['foo','bar'],f2:'FOO'}", new BBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(Locale.class, new LocaleSwap());
+	//------------------------------------------------------------------------------------------------------------------
+	private static Locale C = Locale.JAPAN;
+
+	public static class CSwap extends StringSwap<Locale> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, Locale o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class CBean {
+		public Locale f1 = C;
+		@Swap(CSwap.class)
+		public Locale f2 = C;
+	}
+
+	@Test
+	public void c01_Locale() throws Exception {
+		test("'ja-JP'", C);
+	}
+
+	@Test
+	public void c02_Locale_overrideSwap() throws Exception {
+		test("'FOO'", C, new CSwap());
+	}
+
+	@Test
+	public void c03_Locale_overrideAnnotation() throws Exception {
+		test("{f1:'ja-JP',f2:'FOO'}", new CBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(Calendar.class, new TemporalCalendarSwap.IsoOffsetDateTime());
+	//------------------------------------------------------------------------------------------------------------------
+	private static GregorianCalendar D = GregorianCalendar.from(ZonedDateTime.from(DateTimeFormatter.ISO_ZONED_DATE_TIME.parse("2012-12-21T12:34:56Z")));
+
+	public static class DSwap extends StringSwap<Calendar> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, Calendar o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class DBean {
+		public GregorianCalendar f1 = D;
+		@Swap(DSwap.class)
+		public GregorianCalendar f2 = D;
+	}
+
+	@Test
+	public void d01_Calendar() throws Exception {
+		test("'2012-12-21T12:34:56Z'", D);
+	}
+
+	@Test
+	public void d02_Calendar_overrideSwap() throws Exception {
+		test("'FOO'", D, new DSwap());
+	}
+
+	@Test
+	public void d03_Calendar_overrideAnnotation() throws Exception {
+		test("{f1:'2012-12-21T12:34:56Z',f2:'FOO'}", new DBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(Date.class, new TemporalDateSwap.IsoLocalDateTime());
+	//------------------------------------------------------------------------------------------------------------------
+	private static Date E = Date.from(Instant.from(DateTimeFormatter.ISO_INSTANT.parse("2012-12-21T12:34:56Z")));
+
+	public static class ESwap extends StringSwap<Date> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, Date o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class EBean {
+		public Date f1 = E;
+		@Swap(ESwap.class)
+		public Date f2 = E;
+	}
+
+	@Test
+	public void e01_Date() throws Exception {
+		test("'2012-12-21T07:34:56'", E);
+	}
+
+	@Test
+	public void e02_Date_overrideSwap() throws Exception {
+		test("'FOO'", E, new ESwap());
+	}
+
+	@Test
+	public void e03_Date_overrideAnnotation() throws Exception {
+		test("{f1:'2012-12-21T07:34:56',f2:'FOO'}", new EBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(Instant.class, new TemporalSwap.IsoInstant());
+	//------------------------------------------------------------------------------------------------------------------
+	private static Instant FA = Instant.parse("2012-12-21T12:34:56Z");
+
+	public static class FASwap extends StringSwap<Instant> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, Instant o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class FABean {
+		public Instant f1 = FA;
+		@Swap(FASwap.class)
+		public Instant f2 = FA;
+	}
+
+	@Test
+	public void fa01_Instant() throws Exception {
+		test("'2012-12-21T12:34:56Z'", FA);
+	}
+
+	@Test
+	public void fa02_Instant_overrideSwap() throws Exception {
+		test("'FOO'", FA, new FASwap());
+	}
+
+	@Test
+	public void fa03_Instant_overrideAnnotation() throws Exception {
+		test("{f1:'2012-12-21T12:34:56Z',f2:'FOO'}", new FABean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(ZonedDateTime.class, new TemporalSwap.IsoOffsetDateTime());
+	//------------------------------------------------------------------------------------------------------------------
+	private static ZonedDateTime FB = ZonedDateTime.parse("2012-12-21T12:34:56Z");
+
+	public static class FBSwap extends StringSwap<ZonedDateTime> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, ZonedDateTime o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class FBBean {
+		public ZonedDateTime f1 = FB;
+		@Swap(FBSwap.class)
+		public ZonedDateTime f2 = FB;
+	}
+
+	@Test
+	public void fb01_ZonedDateTime() throws Exception {
+		test("'2012-12-21T12:34:56Z'", FB);
+	}
+
+	@Test
+	public void fb02_ZonedDateTime_overrideSwap() throws Exception {
+		test("'FOO'", FB, new FBSwap());
+	}
+
+	@Test
+	public void fb03_ZonedDateTime_overrideAnnotation() throws Exception {
+		test("{f1:'2012-12-21T12:34:56Z',f2:'FOO'}", new FBBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(LocalDate.class, new TemporalSwap.IsoLocalDate());
+	//------------------------------------------------------------------------------------------------------------------
+	private static LocalDate FC = LocalDate.parse("2012-12-21");
+
+	public static class FCSwap extends StringSwap<LocalDate> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, LocalDate o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class FCBean {
+		public LocalDate f1 = FC;
+		@Swap(FCSwap.class)
+		public LocalDate f2 = FC;
+	}
+
+	@Test
+	public void fc01_LocalDate() throws Exception {
+		test("'2012-12-21'", FC);
+	}
+
+	@Test
+	public void fc02_LocalDate_overrideSwap() throws Exception {
+		test("'FOO'", FC, new FCSwap());
+	}
+
+	@Test
+	public void fc03_LocalDate_overrideAnnotation() throws Exception {
+		test("{f1:'2012-12-21',f2:'FOO'}", new FCBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(LocalDateTime.class, new TemporalSwap.IsoLocalDateTime());
+	//------------------------------------------------------------------------------------------------------------------
+	private static LocalDateTime FD = LocalDateTime.parse("2012-12-21T12:34:56");
+
+	public static class FDSwap extends StringSwap<LocalDateTime> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, LocalDateTime o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class FDBean {
+		public LocalDateTime f1 = FD;
+		@Swap(FDSwap.class)
+		public LocalDateTime f2 = FD;
+	}
+
+	@Test
+	public void fd01_LocalDateTime() throws Exception {
+		test("'2012-12-21T12:34:56'", FD);
+	}
+
+	@Test
+	public void fd02_LocalDateTime_overrideSwap() throws Exception {
+		test("'FOO'", FD, new FDSwap());
+	}
+
+	@Test
+	public void fd03_LocalDateTime_overrideAnnotation() throws Exception {
+		test("{f1:'2012-12-21T12:34:56',f2:'FOO'}", new FDBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(LocalTime.class, new TemporalSwap.IsoLocalTime());
+	//------------------------------------------------------------------------------------------------------------------
+	private static LocalTime FE = LocalTime.parse("12:34:56");
+
+	public static class FESwap extends StringSwap<LocalTime> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, LocalTime o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class FEBean {
+		public LocalTime f1 = FE;
+		@Swap(FESwap.class)
+		public LocalTime f2 = FE;
+	}
+
+	@Test
+	public void fe01_LocalTime() throws Exception {
+		test("'12:34:56'", FE);
+	}
+
+	@Test
+	public void fe02_LocalTime_overrideSwap() throws Exception {
+		test("'FOO'", FE, new FESwap());
+	}
+
+	@Test
+	public void fe03_LocalTime_overrideAnnotation() throws Exception {
+		test("{f1:'12:34:56',f2:'FOO'}", new FEBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(OffsetDateTime.class, new TemporalSwap.IsoOffsetDateTime());
+	//------------------------------------------------------------------------------------------------------------------
+	private static OffsetDateTime FF = OffsetDateTime.parse("2012-12-21T12:34:56-05:00");
+
+	public static class FFSwap extends StringSwap<OffsetDateTime> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, OffsetDateTime o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class FFBean {
+		public OffsetDateTime f1 = FF;
+		@Swap(FFSwap.class)
+		public OffsetDateTime f2 = FF;
+	}
+
+	@Test
+	public void ff01_OffsetDateTime() throws Exception {
+		test("'2012-12-21T12:34:56-05:00'", FF);
+	}
+
+	@Test
+	public void ff02_OffsetDateTime_overrideSwap() throws Exception {
+		test("'FOO'", FF, new FFSwap());
+	}
+
+	@Test
+	public void ff03_OffsetDateTime_overrideAnnotation() throws Exception {
+		test("{f1:'2012-12-21T12:34:56-05:00',f2:'FOO'}", new FFBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(OffsetTime.class, new TemporalSwap.IsoOffsetTime());
+	//------------------------------------------------------------------------------------------------------------------
+	private static OffsetTime FG = OffsetTime.parse("12:34:56-05:00");
+
+	public static class FGSwap extends StringSwap<OffsetTime> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, OffsetTime o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class FGBean {
+		public OffsetTime f1 = FG;
+		@Swap(FGSwap.class)
+		public OffsetTime f2 = FG;
+	}
+
+	@Test
+	public void fg01_OffsetTime() throws Exception {
+		test("'12:34:56-05:00'", FG);
+	}
+
+	@Test
+	public void fg02_OffsetTime_overrideSwap() throws Exception {
+		test("'FOO'", FG, new FGSwap());
+	}
+
+	@Test
+	public void fg03_OffsetTime_overrideAnnotation() throws Exception {
+		test("{f1:'12:34:56-05:00',f2:'FOO'}", new FGBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(Year.class, new TemporalSwap.IsoYear());
+	//------------------------------------------------------------------------------------------------------------------
+	private static Year FH = Year.parse("2012");
+
+	public static class FHSwap extends StringSwap<Year> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, Year o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class FHBean {
+		public Year f1 = FH;
+		@Swap(FHSwap.class)
+		public Year f2 = FH;
+	}
+
+	@Test
+	public void fh01_Year() throws Exception {
+		test("'2012'", FH);
+	}
+
+	@Test
+	public void fh02_Year_overrideSwap() throws Exception {
+		test("'FOO'", FH, new FHSwap());
+	}
+
+	@Test
+	public void fh03_Year_overrideAnnotation() throws Exception {
+		test("{f1:'2012',f2:'FOO'}", new FHBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(YearMonth.class, new TemporalSwap.IsoYearMonth());
+	//------------------------------------------------------------------------------------------------------------------
+	private static YearMonth FI = YearMonth.parse("2012-12");
+
+	public static class FISwap extends StringSwap<YearMonth> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, YearMonth o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class FIBean {
+		public YearMonth f1 = FI;
+		@Swap(FISwap.class)
+		public YearMonth f2 = FI;
+	}
+
+	@Test
+	public void fi01_YearMonth() throws Exception {
+		test("'2012-12'", FI);
+	}
+
+	@Test
+	public void fi02_YearMonth_overrideSwap() throws Exception {
+		test("'FOO'", FI, new FISwap());
+	}
+
+	@Test
+	public void fi03_YearMonth_overrideAnnotation() throws Exception {
+		test("{f1:'2012-12',f2:'FOO'}", new FIBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(Temporal.class, new TemporalSwap.IsoInstant());
+	//------------------------------------------------------------------------------------------------------------------
+	private static Temporal FJ = HijrahDate.from(FB);
+
+	public static class FJSwap extends StringSwap<Temporal> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, Temporal o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class FJBean {
+		public Temporal f1 = FJ;
+		@Swap(FJSwap.class)
+		public Temporal f2 = FJ;
+	}
+
+	@Test
+	public void fj01_Temporal() throws Exception {
+		test("'2012-12-21T05:00:00Z'", FJ);
+	}
+
+	@Test
+	public void fj02_Temporal_overrideSwap() throws Exception {
+		test("'FOO'", FJ, new FJSwap());
+	}
+
+	@Test
+	public void fj03_Temporal_overrideAnnotation() throws Exception {
+		test("{f1:'2012-12-21T05:00:00Z',f2:'FOO'}", new FJBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(TimeZone.class, new TimeZoneSwap());
+	//------------------------------------------------------------------------------------------------------------------
+	private static TimeZone G = TimeZone.getTimeZone("Z");
+
+	public static class GSwap extends StringSwap<TimeZone> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, TimeZone o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class GBean {
+		public TimeZone f1 = G;
+		@Swap(GSwap.class)
+		public TimeZone f2 = G;
+	}
+
+	@Test
+	public void g01_TimeZone() throws Exception {
+		test("'GMT'", G);
+	}
+
+	@Test
+	public void g02_TimeZone_overrideSwap() throws Exception {
+		test("'FOO'", G, new GSwap());
+	}
+
+	@Test
+	public void g03_TimeZone_overrideAnnotation() throws Exception {
+		test("{f1:'GMT',f2:'FOO'}", new GBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(XMLGregorianCalendar.class, new XMLGregorianCalendarSwap());
+	//------------------------------------------------------------------------------------------------------------------
+	private static XMLGregorianCalendar H;
+	static {
+		try {
+			H = DatatypeFactory.newInstance().newXMLGregorianCalendar("2012-12-21T12:34:56.789Z");
+		} catch (DatatypeConfigurationException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public static class HSwap extends StringSwap<XMLGregorianCalendar> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, XMLGregorianCalendar o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class HBean {
+		public XMLGregorianCalendar f1 = H;
+		@Swap(HSwap.class)
+		public XMLGregorianCalendar f2 = H;
+	}
+
+	@Test
+	public void h01_XMLGregorianCalendar() throws Exception {
+		test("'2012-12-21T12:34:56.789Z'", H);
+	}
+
+	@Test
+	public void h02_XMLGregorianCalendar_overrideSwap() throws Exception {
+		test("'FOO'", H, new HSwap());
+	}
+
+	@Test
+	public void h03_XMLGregorianCalendar_overrideAnnotation() throws Exception {
+		test("{f1:'2012-12-21T12:34:56.789Z',f2:'FOO'}", new HBean());
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	//	POJO_SWAPS.put(ZoneId.class, new ZoneIdSwap());
+	//------------------------------------------------------------------------------------------------------------------
+	private static ZoneId I = ZoneId.of("Z");
+
+	public static class ISwap extends StringSwap<ZoneId> {
+		@Override /* PojoSwap */
+		public String swap(BeanSession session, ZoneId o) throws Exception {
+			return "FOO";
+		}
+	}
+
+	public static class IBean {
+		public ZoneId f1 = I;
+		@Swap(ISwap.class)
+		public ZoneId f2 = I;
+	}
+
+	@Test
+	public void i01_ZoneId() throws Exception {
+		test("'Z'", I);
+	}
+
+	@Test
+	public void i02_ZoneId_overrideSwap() throws Exception {
+		test("'FOO'", I, new ISwap());
+	}
+
+	@Test
+	public void i03_ZoneId_overrideAnnotation() throws Exception {
+		test("{f1:'Z',f2:'FOO'}", new IBean());
+	}
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java
index 02b9c05..49a2682 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java
@@ -183,22 +183,6 @@
 	}
 
 	/**
-	 * Converts the specified object to the specified type.
-	 *
-	 * @param <T> The class type to convert the value to.
-	 * @param outer
-	 * 	If class is a member class, this is the instance of the containing class.
-	 * 	Should be <jk>null</jk> if not a member class.
-	 * @param value The value to convert.
-	 * @param type The class type to convert the value to.
-	 * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type.
-	 * @return The converted value.
-	 */
-	public static <T> T toMemberType(Object outer, Object value, Class<T> type) {
-		return session.convertToMemberType(outer, value, type);
-	}
-
-	/**
 	 * Returns <jk>true</jk> if the specified objects are equal.
 	 *
 	 * <p>
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
index ae59767..1610486 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
@@ -206,8 +206,11 @@
 		if (interfaces == null) {
 			Set<ClassInfo> s = new LinkedHashSet<>();
 			for (ClassInfo ci : getParents())
-				for (ClassInfo ci2 : ci.getDeclaredInterfaces())
+				for (ClassInfo ci2 : ci.getDeclaredInterfaces()) {
 					s.add(ci2);
+					for (ClassInfo ci3 : ci2.getInterfaces())
+						s.add(ci3);
+				}
 			interfaces = unmodifiableList(new ArrayList<>(s));
 		}
 		return interfaces;
@@ -2031,4 +2034,14 @@
 	public String toString() {
 		return t.toString();
 	}
+
+	@Override
+	public int hashCode() {
+		return t.hashCode();
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		return o == null ? false : ((ClassInfo)o).t.equals(t);
+	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/DefaultSwaps.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/DefaultSwaps.java
index 2fdeeaf..69f63a0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/DefaultSwaps.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/DefaultSwaps.java
@@ -41,13 +41,12 @@
 		POJO_SWAPS.put(LocalTime.class, new TemporalSwap.IsoLocalTime());
 		POJO_SWAPS.put(OffsetDateTime.class, new TemporalSwap.IsoOffsetDateTime());
 		POJO_SWAPS.put(OffsetTime.class, new TemporalSwap.IsoOffsetTime());
-		POJO_SWAPS.put(LocalDateTime.class, new TemporalSwap.IsoLocalDateTime());
-		POJO_SWAPS.put(LocalTime.class, new TemporalSwap.IsoLocalTime());
 		POJO_SWAPS.put(Year.class, new TemporalSwap.IsoYear());
 		POJO_SWAPS.put(YearMonth.class, new TemporalSwap.IsoYearMonth());
 		POJO_SWAPS.put(Temporal.class, new TemporalSwap.IsoInstant());
 		POJO_SWAPS.put(TimeZone.class, new TimeZoneSwap());
 		POJO_SWAPS.put(XMLGregorianCalendar.class, new XMLGregorianCalendarSwap());
+		POJO_SWAPS.put(ZoneId.class, new ZoneIdSwap());
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/TimeZoneSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/TimeZoneSwap.java
index 8501d5f..485ea68 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/TimeZoneSwap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/TimeZoneSwap.java
@@ -24,7 +24,7 @@
 
 	@Override /* PojoSwap */
 	public String swap(BeanSession session, TimeZone o) throws Exception {
-		return o.toString();
+		return o.getID();
 	}
 
 	@Override /* PojoSwap */
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/ZoneIdSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/ZoneIdSwap.java
new file mode 100644
index 0000000..45f1206
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/ZoneIdSwap.java
@@ -0,0 +1,34 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.transforms;
+
+import java.time.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link ZoneId} objects to and from {@link String Strings}.
+ */
+public class ZoneIdSwap extends StringSwap<ZoneId> {
+
+	@Override /* PojoSwap */
+	public String swap(BeanSession session, ZoneId o) throws Exception {
+		return o.getId();
+	}
+
+	@Override /* PojoSwap */
+	public ZoneId unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
+		return ZoneId.of(o);
+	}
+}
diff --git a/juneau-doc/docs/ReleaseNotes/8.0.1.html b/juneau-doc/docs/ReleaseNotes/8.0.1.html
index b911bfe..07e9ec7 100644
--- a/juneau-doc/docs/ReleaseNotes/8.0.1.html
+++ b/juneau-doc/docs/ReleaseNotes/8.0.1.html
@@ -64,6 +64,28 @@
 			<li class='jc'>{@link oaj.transforms.TemporalDateSwap} - For {@link java.util.Date}
 			<li class='jc'>{@link oaj.transforms.TemporalCalendarSwap} - For {@link java.util.Calendar}
 		</ul>
+	<li>
+		All serializers and parsers now have built-in default swaps for common class types:
+		<ul class='doctree'>
+			<li class='jc'>{@link java.util.Enumeration}
+			<li class='jc'>{@link java.util.Iterator}
+			<li class='jc'>{@link java.util.Locale}
+			<li class='jc'>{@link java.util.Calendar} - ISO offset date-time.
+			<li class='jc'>{@link java.util.Date} - Local date-time
+			<li class='jc'>{@link java.time.Instant} - ISO instant.
+			<li class='jc'>{@link java.time.ZonedDateTime} - ISO offset date-time.
+			<li class='jc'>{@link java.time.LocalDate} - ISO local date.
+			<li class='jc'>{@link java.time.LocalDateTime} - ISO local date-time.
+			<li class='jc'>{@link java.time.LocalTime} - ISO local time.
+			<li class='jc'>{@link java.time.OffsetDateTime} - ISO offset date-time.
+			<li class='jc'>{@link java.time.OffsetTime} - ISO offset time.
+			<li class='jc'>{@link java.time.Year} - ISO year.
+			<li class='jc'>{@link java.time.YearMonth} - ISO year-month.
+			<li class='jc'>{@link java.time.Temporal} - ISO instant.
+			<li class='jc'>{@link java.util.TimeZone}
+			<li class='jc'>{@link javax.xml.datatype.XMLGregorianCalendar}
+			<li class='jc'>{@link java.time.ZoneId}
+		</ul>
 </ul>
 
 <h5 class='topic w800'>juneau-config</h5>
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/11.DefaultTransforms.html b/juneau-doc/docs/Topics/02.juneau-marshall/11.DefaultTransforms.html
new file mode 100644
index 0000000..a7b95a9
--- /dev/null
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/11.DefaultTransforms.html
@@ -0,0 +1,20 @@
+<!--
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *  
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+ -->
+
+{todo} Default Transforms
+
+<p>
+	TODO
+</p>