156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes/* Licensed to the Apache Software Foundation (ASF) under one or more 256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * contributor license agreements. See the NOTICE file distributed with 356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * this work for additional information regarding copyright ownership. 456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * The ASF licenses this file to You under the Apache License, Version 2.0 556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * (the "License"); you may not use this file except in compliance with 656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * the License. You may obtain a copy of the License at 79997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes * 856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 99997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes * 1056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * Unless required by applicable law or agreed to in writing, software 1156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 1256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * See the License for the specific language governing permissions and 1456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * limitations under the License. 1556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes */ 1656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 17e5fea3d504609d22337a5311d3ce0e72314bceeeNarayan Kamathpackage org.apache.harmony.tests.java.nio.charset; 1856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 1956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.io.IOException; 2056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.BufferOverflowException; 2156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.ByteBuffer; 2256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.CharBuffer; 2356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.Charset; 2456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.CharsetDecoder; 2556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.CharsetEncoder; 2656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.CoderMalfunctionError; 2756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.CoderResult; 2856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 2956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport junit.framework.TestCase; 3056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 31e5fea3d504609d22337a5311d3ce0e72314bceeeNarayan Kamathpublic class CharsetEncoder2Test extends TestCase { 3256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 3356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes /** 3456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * @tests java.nio.charset.CharsetEncoder.CharsetEncoder( 3556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * java.nio.charset.Charset, float, float) 3656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes */ 3756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public void test_ConstructorLjava_nio_charset_CharsetFF() { 3856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes // Regression for HARMONY-141 3956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes try { 4056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes Charset cs = Charset.forName("UTF-8"); //$NON-NLS-1$ 4156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes new MockCharsetEncoderForHarmony141(cs, 1.1f, 1); 4256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes fail("Assert 0: Should throw IllegalArgumentException."); //$NON-NLS-1$ 4356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } catch (IllegalArgumentException e) { 4456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes // expected 4556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 4656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 4756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes try { 4856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes Charset cs = Charset.forName("ISO8859-1"); //$NON-NLS-1$ 4956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes new MockCharsetEncoderForHarmony141(cs, 1.1f, 1, 5056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes new byte[] { 0x1a }); 5156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes fail("Assert 1: Should throw IllegalArgumentException."); //$NON-NLS-1$ 5256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } catch (IllegalArgumentException e) { 5356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes // expected 5456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 5556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 5656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 5756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes /** 5856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * @tests java.nio.charset.CharsetEncoder.CharsetEncoder( 5956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * java.nio.charset.Charset, float, float) 6056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes */ 6156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public void test_ConstructorLjava_nio_charset_CharsetNull() { 6256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes // Regression for HARMONY-491 6356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes CharsetEncoder ech = new MockCharsetEncoderForHarmony491(null, 1, 1); 6456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes assertNull(ech.charset()); 6556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 6656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 6756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes /** 6856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * Helper for constructor tests 6956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes */ 7056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 7156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public static class MockCharsetEncoderForHarmony141 extends CharsetEncoder { 7256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 7356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes protected MockCharsetEncoderForHarmony141(Charset cs, 7456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes float averageBytesPerChar, float maxBytesPerChar) { 7556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes super(cs, averageBytesPerChar, maxBytesPerChar); 7656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 7756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 7856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public MockCharsetEncoderForHarmony141(Charset cs, 7956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes float averageBytesPerChar, float maxBytesPerChar, 8056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes byte[] replacement) { 8156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes super(cs, averageBytesPerChar, maxBytesPerChar, replacement); 8256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 8356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 8456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) { 8556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes return null; 8656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 8756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 8856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 8956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public static class MockCharsetEncoderForHarmony491 extends CharsetEncoder { 9056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 9156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public MockCharsetEncoderForHarmony491(Charset arg0, float arg1, 9256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes float arg2) { 9356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes super(arg0, arg1, arg2); 9456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 9556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 9656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes protected CoderResult encodeLoop(CharBuffer arg0, ByteBuffer arg1) { 9756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes return null; 9856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 9956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 10056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public boolean isLegalReplacement(byte[] arg0) { 10156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes return true; 10256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 10356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 10456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 10556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes /* 10656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * Test malfunction encode(CharBuffer) 10756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes */ 10856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public void test_EncodeLjava_nio_CharBuffer() throws Exception { 10956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes MockMalfunctionCharset cs = new MockMalfunctionCharset("mock", null); 11056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes try { 11156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes cs.encode(CharBuffer.wrap("AB")); 11256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes fail("should throw CoderMalfunctionError");// NON-NLS-1$ 11356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } catch (CoderMalfunctionError e) { 11456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes // expected 11556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 11656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 11756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 11856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes /* 11956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * Mock charset class with malfunction decode & encode. 12056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes */ 12156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes static final class MockMalfunctionCharset extends Charset { 12256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 12356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public MockMalfunctionCharset(String canonicalName, String[] aliases) { 12456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes super(canonicalName, aliases); 12556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 12656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 12756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public boolean contains(Charset cs) { 12856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes return false; 12956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 13056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 13156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public CharsetDecoder newDecoder() { 13256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes return Charset.forName("UTF-8").newDecoder(); 13356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 13456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 13556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public CharsetEncoder newEncoder() { 13656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes return new MockMalfunctionEncoder(this); 13756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 13856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 13956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 14056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes /* 14156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * Mock encoder. encodeLoop always throws unexpected exception. 14256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes */ 14356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes static class MockMalfunctionEncoder extends java.nio.charset.CharsetEncoder { 14456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 14556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public MockMalfunctionEncoder(Charset cs) { 14656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes super(cs, 1, 3, new byte[] { (byte) '?' }); 14756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 14856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 14956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) { 15056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes throw new BufferOverflowException(); 15156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 15256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 15356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 15456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes /* 15556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * Test reserve bytes encode(CharBuffer,ByteBuffer,boolean) 15656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes */ 1579997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes public void test_EncodeLjava_nio_CharBufferLjava_nio_ByteBufferB() throws Exception { 1589997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes Charset utf8 = Charset.forName("utf-8"); 1599997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes CharsetEncoder encoder = utf8.newEncoder(); 1606ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes CharBuffer char1 = CharBuffer.wrap("\ud800"); 1616ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes CharBuffer char2 = CharBuffer.wrap("\udc00"); 1626ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes ByteBuffer bytes = ByteBuffer.allocate(4); 16356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes encoder.reset(); 1649997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes 1659997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes // If we supply just the high surrogate... 1666ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes CoderResult result = encoder.encode(char1, bytes, false); 1679997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes // ...we're not done... 16856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes assertTrue(result.isUnderflow()); 1696ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes assertEquals(4, bytes.remaining()); 1709997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes // ...but if we then supply the low surrogate... 1716ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes result = encoder.encode(char2, bytes, true); 1726ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes assertTrue(result.isUnderflow()); 1739997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes // ...we're done. Note that the RI loses its state in 1749997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes // between the two characters, so it can't do this. 1756ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes assertEquals(0, bytes.remaining()); 1766ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes 1776ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes // Did we get the UTF-8 for U+10000? 1786ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes assertEquals(4, bytes.limit()); 1796ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes assertEquals((byte) 0xf0, bytes.get(0)); 1806ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes assertEquals((byte) 0x90, bytes.get(1)); 1816ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes assertEquals((byte) 0x80, bytes.get(2)); 1826ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes assertEquals((byte) 0x80, bytes.get(3)); 1839997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes 1849997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes // See what we got in the output buffer by decoding and checking that we 1859997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes // get back the same surrogate pair. 1866ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes bytes.flip(); 1876ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes CharBuffer chars = utf8.newDecoder().decode(bytes); 1886ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes assertEquals(0, bytes.remaining()); 1896ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes assertEquals(2, chars.limit()); 1909997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes assertEquals(0xd800, chars.get(0)); 1919997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes assertEquals(0xdc00, chars.get(1)); 19256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 19356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 19456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes /** 19556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * @tests {@link java.nio.charset.Charset#encode(java.nio.CharBuffer) 19656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes */ 19756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes public void testUtf8Encoding() throws IOException { 19856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes byte[] orig = new byte[] { (byte) 0xed, (byte) 0xa0, 19956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes (byte) 0x80 }; 20056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes String s = new String(orig, "UTF-8"); 20156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes assertEquals(1, s.length()); 20256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes assertEquals(55296, s.charAt(0)); 20356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes Charset.forName("UTF-8").encode(CharBuffer.wrap(s)); 2049997a91c8624c5abd10a8da33f36debf0d773235Elliott Hughes// ByteBuffer buf = <result> 20556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes// for (byte o : orig) { 20656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes// byte b = 0; 20756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes// buf.get(b); 20856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes// assertEquals(o, b); 20956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes// } 21056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes } 21156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes 21256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes} 213