gt:         return (BigDecimal) readNext();
context: /*-
   * See the file LICENSE for redistribution information.
   *
   * Copyright (c) 2002, 2013 Oracle and/or its affiliates.  All rights reserved.
   *
   */
  
  package com.sleepycat.persist.impl;
  
  import java.math.BigDecimal;
  import java.math.BigInteger;
  
  import com.sleepycat.compat.DbCompat;
  import com.sleepycat.persist.raw.RawObject;
  import java.util.IdentityHashMap;
  
  /**
   * Base class for EntityInput implementations that type-check RawObject
   * instances and convert them to regular persistent objects, via the
   * Format.convertRawObject method.
   *
   * The subclass implements readNext which should call checkAndConvert before
   * returning the final value.
   *
   * @author Mark Hayes
   */
  abstract class RawAbstractInput extends AbstractInput {
  
      private IdentityHashMap converted;
  
      RawAbstractInput(Catalog catalog,
                       boolean rawAccess,
                       IdentityHashMap converted) {
          super(catalog, rawAccess);
          this.converted = converted;
      }
  
      public Object readObject()
          throws RefreshException {
  
          return readNext();
      }
  
      public Object readKeyObject(Format format)
          throws RefreshException {
  
          return readNext();
      }
  
      public Object readStringObject()
          throws RefreshException {
  
          return readNext();
      }
  
      public void registerPriKeyObject(Object o) {
      }
      
      public void registerPriStringKeyObject(Object o) {
      }
  
      public int readArrayLength() {
          throw DbCompat.unexpectedState();
      }
  
      public int readEnumConstant(String[] names) {
          throw DbCompat.unexpectedState();
      }
  
      public void skipField(Format declaredFormat) {
      }
  
      abstract Object readNext()
          throws RefreshException;
  
      Object checkAndConvert(Object o, Format declaredFormat)
          throws RefreshException {
  
          if (o == null) {
              if (declaredFormat.isPrimitive()) {
                  throw new IllegalArgumentException
                      ("A primitive type may not be null or missing: " +
                       declaredFormat.getClassName());
              }
          } else if (declaredFormat.isSimple()) {
              if (declaredFormat.isPrimitive()) {
                  if (o.getClass() !=
                      declaredFormat.getWrapperFormat().getType()) {
                      throw new IllegalArgumentException
                          ("Raw value class: " + o.getClass().getName() +
                           " must be the wrapper class for a primitive type: " +
                           declaredFormat.getClassName());
                  }
              } else {
                  if (o.getClass() != declaredFormat.getType()) {
                      throw new IllegalArgumentException
                          ("Raw value class: " + o.getClass().getName() +
                           " must be the declared class for a simple type: " +
                           declaredFormat.getClassName());
                  }
              }
          } else {
              if (o instanceof RawObject) {
                  Object o2 = null;
                  if (!rawAccess) {
                      if (converted != null) {
                          o2 = converted.get(o);
                      } else {
                          converted = new IdentityHashMap();
                      }
                  }
                  if (o2 != null) {
                      o = o2;
                  } else {
                      if (!rawAccess) {
                          o = catalog.convertRawObject((RawObject) o, converted);
                      }
                  }
              } else {
                  if (!SimpleCatalog.isSimpleType(o.getClass())) {
                      throw new IllegalArgumentException
                          ("Raw value class: " + o.getClass().getName() +
                           " must be RawObject a simple type");
                  }
              }
              if (rawAccess) {
                  checkRawType(catalog, o, declaredFormat);
              } else {
                  if (!declaredFormat.getType().isAssignableFrom(o.getClass())) {
                      throw new IllegalArgumentException
                          ("Raw value class: " + o.getClass().getName() +
                           " is not assignable to type: " +
                           declaredFormat.getClassName());
                  }
              }
          }
          return o;
      }
  
      static Format checkRawType(Catalog catalog,
                                 Object o,
                                 Format declaredFormat)
          throws RefreshException {
  
          assert declaredFormat != null;
          Format format;
          if (o instanceof RawObject) {
              format = (Format) ((RawObject) o).getType();
              /* Ensure a fresh format is used, in case of Replica refresh. */
              format = catalog.getFormat(format.getId(), false /*expectStored*/);
          } else {
              format = catalog.getFormat(o.getClass(),
                                         false /*checkEntitySubclassIndexes*/);
              if (!format.isSimple() || format.isEnum()) {
                  throw new IllegalArgumentException
                      ("Not a RawObject or a non-enum simple type: " +
                       format.getClassName());
              }
          }
          if (!format.isAssignableTo(declaredFormat)) {
              throw new IllegalArgumentException
                  ("Not a subtype of the field's declared class " +
                   declaredFormat.getClassName() + ": " +
                   format.getClassName());
          }
          if (!format.isCurrentVersion()) {
              throw new IllegalArgumentException
                  ("Raw type version is not current.  Class: " +
                   format.getClassName() + " Version: " +
                   format.getVersion());
          }
          Format proxiedFormat = format.getProxiedFormat();
          if (proxiedFormat != null) {
              format = proxiedFormat;
          }
          return format;
      }
  
      /* The following methods are a subset of the methods in TupleInput. */
  
      public String readString()
          throws RefreshException {
  
          return (String) readNext();
      }
  
      public char readChar()
          throws RefreshException {
  
          return ((Character) readNext()).charValue();
      }
  
      public boolean readBoolean()
          throws RefreshException {
  
          return ((Boolean) readNext()).booleanValue();
      }
  
      public byte readByte()
          throws RefreshException {
  
          return ((Byte) readNext()).byteValue();
      }
  
      public short readShort()
          throws RefreshException {
  
          return ((Short) readNext()).shortValue();
      }
  
      public int readInt()
          throws RefreshException {
  
          return ((Integer) readNext()).intValue();
      }
  
      public long readLong()
          throws RefreshException {
  
          return ((Long) readNext()).longValue();
      }
  
      public float readSortedFloat()
          throws RefreshException {
  
          return ((Float) readNext()).floatValue();
      }
  
      public double readSortedDouble()
          throws RefreshException {
  
          return ((Double) readNext()).doubleValue();
      }
      
      public BigDecimal readSortedBigDecimal() 
          throws RefreshException {
          
  