예제 #1
0
  public static FileDescriptor getDescriptorFromChannel(Channel channel) {
    if (SEL_CH_IMPL_GET_FD != null && SEL_CH_IMPL.isInstance(channel)) {
      // Pipe Source and Sink, Sockets, and other several other selectable channels
      try {
        return (FileDescriptor) SEL_CH_IMPL_GET_FD.invoke(channel);
      } catch (Exception e) {
        // return bogus below
      }
    } else if (FILE_CHANNEL_IMPL_FD != null && FILE_CHANNEL_IMPL.isInstance(channel)) {
      // FileChannels
      try {
        return (FileDescriptor) FILE_CHANNEL_IMPL_FD.get(channel);
      } catch (Exception e) {
        // return bogus below
      }
    } else if (FILE_DESCRIPTOR_FD != null) {
      FileDescriptor unixFD = new FileDescriptor();

      // UNIX sockets, from jnr-unixsocket
      try {
        if (channel instanceof UnixSocketChannel) {
          FILE_DESCRIPTOR_FD.set(unixFD, ((UnixSocketChannel) channel).getFD());
          return unixFD;
        } else if (channel instanceof UnixServerSocketChannel) {
          FILE_DESCRIPTOR_FD.set(unixFD, ((UnixServerSocketChannel) channel).getFD());
          return unixFD;
        }
      } catch (Exception e) {
        // return bogus below
      }
    }
    return new FileDescriptor();
  }
예제 #2
0
  @SuppressWarnings("unchecked")
  @Override
  public <T> T unwrap(Class<T> iface) throws SQLException {
    if (iface == null) {
      return null;
    }

    if (iface == Connection.class) {
      if (conn instanceof ConnectionProxy) {
        return conn.unwrap(iface);
      }

      return (T) conn;
    }

    if (iface.isInstance(conn)) {
      return (T) conn;
    }

    if (iface.isInstance(this)) {
      return (T) this;
    }

    return conn.unwrap(iface);
  }
  /**
   * Copied from Util.getAdapter (from eclipse 3.3: not available in eclipse 3.2)
   *
   * <p>If it is possible to adapt the given object to the given type, this returns the adapter.
   * Performs the following checks:
   *
   * <ol>
   *   <li>Returns <code>sourceObject</code> if it is an instance of the adapter type.
   *   <li>If sourceObject implements IAdaptable, it is queried for adapters.
   *   <li>If sourceObject is not an instance of PlatformObject (which would have already done so),
   *       the adapter manager is queried for adapters
   * </ol>
   *
   * Otherwise returns null.
   *
   * @param sourceObject object to adapt, or null
   * @param adapterType type to adapt to
   * @return a representation of sourceObject that is assignable to the adapter type, or null if no
   *     such representation exists
   */
  public static Object utilGetAdapter(Object sourceObject, Class adapterType) {
    Assert.isNotNull(adapterType);
    if (sourceObject == null) {
      return null;
    }
    if (adapterType.isInstance(sourceObject)) {
      return sourceObject;
    }

    if (sourceObject instanceof IAdaptable) {
      IAdaptable adaptable = (IAdaptable) sourceObject;

      Object result = adaptable.getAdapter(adapterType);
      if (result != null) {
        // Sanity-check
        Assert.isTrue(adapterType.isInstance(result));
        return result;
      }
    }

    if (!(sourceObject instanceof PlatformObject)) {
      Object result = Platform.getAdapterManager().getAdapter(sourceObject, adapterType);
      if (result != null) {
        return result;
      }
    }

    return null;
  }
 /**
  * Returns parent component with this type
  *
  * @param <T> searching type
  * @param component child component
  * @param type parent type
  * @return found parent
  */
 protected <T> T getParentComponent(final Component component, final Class<T> type) {
   Component comp = component;
   while (!(type.isInstance(comp)) && comp.getParent() != null) {
     comp = comp.getParent();
   }
   return (comp == null || !(type.isInstance(comp))) ? null : type.cast(comp);
 }
예제 #5
0
  /**
   * Passe un peuple se trouvant sur le jeu dans le tas
   *
   * @param peuple Peuple à remettre
   */
  public void remettreBoite(Peuple peuple) {
    // Recherche de la classe du peuple
    Iterator<Class<? extends Peuple>> it = peuplesPris.iterator();
    Class<? extends Peuple> peupleClass = null;

    while (it.hasNext() && peupleClass == null) {
      Class<? extends Peuple> tmp = it.next();

      if (tmp.isInstance(peuple)) {
        peupleClass = tmp;
      }
    }

    peuplesPris.remove(peupleClass);
    peuplesDispo.add(peupleClass);

    // Recherche de la classe du pouvoir
    Iterator<Class<? extends Pouvoir>> ite = pouvoirsPris.iterator();
    Class<? extends Pouvoir> pouvoirClass = null;

    while (ite.hasNext() && pouvoirClass == null) {
      Class<? extends Pouvoir> tmp = ite.next();

      if (tmp.isInstance(peuple.getPouvoir())) {
        pouvoirClass = tmp;
      }
    }

    pouvoirsPris.remove(pouvoirClass);
    pouvoirsDispo.add(pouvoirClass);
  }
예제 #6
0
 public static <E1 extends Exception, E2 extends Exception, E3 extends Exception>
     ValueOrException3<E1, E2, E3> downconvert(
         ValueOrException4<E1, E2, E3, BottomException> voe,
         Class<E1> exceptionClass1,
         Class<E2> exceptionClass2,
         Class<E3> exceptionClass3) {
   Exception e = voe.getException();
   if (e == null) {
     return new ValueOrException3ValueImpl<>(voe.getValue());
   }
   if (exceptionClass1.isInstance(e)) {
     return new ValueOrException3Exn1Impl<>(exceptionClass1.cast(e));
   }
   if (exceptionClass2.isInstance(e)) {
     return new ValueOrException3Exn2Impl<>(exceptionClass2.cast(e));
   }
   if (exceptionClass3.isInstance(e)) {
     return new ValueOrException3Exn3Impl<>(exceptionClass3.cast(e));
   }
   throw new IllegalStateException(
       "shouldn't reach here "
           + e.getClass()
           + " "
           + exceptionClass1
           + " "
           + exceptionClass2
           + " "
           + exceptionClass3,
       e);
 }
예제 #7
0
  /**
   * Some adapters rely on interfaces that are stateless, where the target is passed as an argument
   * to the adapter. This is not necessarily true for some interfaces we cannot control (like
   * IContentProposal).
   *
   * @param <T> The type class
   * @param obj the object which might be the adapted target
   * @param clazz the class that the target must be an instance of.
   * @return the target object
   */
  @SuppressWarnings("unchecked")
  public <T extends Object> T getTarget(Object obj, Class<T> clazz) {

    if (obj != null) {
      if (clazz.isInstance(obj)) {
        return (T) obj;
      }
      if (target != null) {
        if (clazz.isInstance(target)) {
          return (T) target;
        }
      }
      // problem !
      throw new RuntimeException("Object is not of type " + clazz.getName()); // $NON-NLS-1$
    }

    /** Target is never set unless the object is statefull. */
    if (target != null) {
      if (clazz.isInstance(target)) {
        return (T) target;
      }
      // problem !
      throw new RuntimeException("Target is not of type " + clazz.getName()); // $NON-NLS-1$
    }

    return null;
  }
예제 #8
0
 /**
  * @param <T>
  * @param source
  * @param targetType
  * @return
  * @throws NoSuchMethodException
  */
 @SuppressWarnings("unchecked")
 public static <T> T getTypeViaValueOfMethod(final String source, final Class<T> targetType)
     throws NoSuchMethodException {
   Class<?> actualTarget = targetType;
   /*
    * if this is a primitive type, use the Object class's "valueOf()"
    * method.
    */
   if (targetType.isPrimitive()) {
     actualTarget = PRIMITIVES.get(targetType);
   }
   T result = null;
   try {
     // if the type has a static "valueOf()" method, try and create the instance that way
     Method valueOf = actualTarget.getDeclaredMethod(VALUE_OF_METHOD, String.class);
     Object value = valueOf.invoke(null, source);
     if (actualTarget.equals(targetType) && targetType.isInstance(value)) {
       result = targetType.cast(value);
     }
     /*
      * handle the primitive case
      */
     else if (!actualTarget.equals(targetType) && actualTarget.isInstance(value)) {
       // because you can't use targetType.cast() with primitives.
       result = (T) value;
     }
   } catch (IllegalAccessException e) {
     throw new ExceptionAdapter(e);
   } catch (InvocationTargetException e) {
     throw new ExceptionAdapter(e);
   }
   return result;
 }
  /**
   * resolves n to node of type R, via declaration if n is an identifier, via simple cast otherwise
   * returns null if n's declaration or n can't be cast to R or S
   */
  public Pair<R, S> resolve(BaseNode n, BaseNode parent) {
    if (n instanceof IdentNode) {
      Pair<R, S> pair = resolve((IdentNode) n);
      if (pair != null) {
        assert pair.fst == null || pair.snd == null;
        parent.becomeParent(pair.fst);
        parent.becomeParent(pair.snd);
      }
      return pair;
    }

    Pair<R, S> pair = new Pair<R, S>();
    if (clsR.isInstance(n)) {
      pair.fst = clsR.cast(n);
    }
    if (clsS.isInstance(n)) {
      pair.snd = clsS.cast(n);
    }
    if (pair.fst != null || pair.snd != null) {
      assert pair.fst == null || pair.snd == null;
      return pair;
    }

    n.reportError(
        "\""
            + n
            + "\" is a "
            + n.getUseString()
            + " but a "
            + Util.getStrListWithOr(classes, BaseNode.class, "getUseStr")
            + " is expected");
    return null;
  }
예제 #10
0
  /**
   * resolves n to node of type R or S, via declaration returns null if n's declaration can't be
   * cast to R/S
   */
  private Pair<R, S> resolve(IdentNode n) {
    if (n instanceof PackageIdentNode) {
      if (!resolveOwner((PackageIdentNode) n)) {
        return null;
      }
    }

    Pair<R, S> pair = new Pair<R, S>();
    DeclNode resolved = n.getDecl();
    if (clsR.isInstance(resolved)) {
      pair.fst = clsR.cast(resolved);
    }
    if (clsS.isInstance(resolved)) {
      pair.snd = clsS.cast(resolved);
    }
    if (pair.fst != null || pair.snd != null) {
      return pair;
    }

    n.reportError(
        "\""
            + n
            + "\" is a "
            + resolved.getUseString()
            + " but a "
            + Util.getStrListWithOr(classes, BaseNode.class, "getUseStr")
            + " is expected");
    return null;
  }
예제 #11
0
 /** A clean way to specify which tests run on which platforms. */
 public boolean isPlatformSupported(DatabasePlatform platform) {
   boolean supported = false;
   boolean notSupported = false;
   if ((unsupportedPlatforms == null) && (supportedPlatforms == null)) {
     return true;
   }
   if (supportedPlatforms != null) {
     for (Iterator iterator = supportedPlatforms.iterator(); iterator.hasNext(); ) {
       Class platformClass = (Class) iterator.next();
       if (platformClass.isInstance(platform)) {
         supported = true;
       }
     }
   } else {
     supported = true;
   }
   if (unsupportedPlatforms != null) {
     for (Iterator iterator = unsupportedPlatforms.iterator(); iterator.hasNext(); ) {
       Class platformClass = (Class) iterator.next();
       if (platformClass.isInstance(platform)) {
         notSupported = true;
       }
     }
   }
   return supported && (!notSupported);
 }
예제 #12
0
  /**
   * Check the class of the container in which the attribute is to be placed. If the container is
   * not an intended one, throw an IllegalActionException.
   *
   * @param attribute The attribute to check.
   * @param container The container.
   * @param containerClass The intended class of container.
   * @param deep Whether containers of the container should be checked instead, if the container
   *     does not qualify.
   * @exception IllegalActionException If this attribute cannot be used with the given container.
   */
  public static void checkContainerClass(
      Attribute attribute,
      NamedObj container,
      Class<? extends CompositeEntity> containerClass,
      boolean deep)
      throws IllegalActionException {
    while (deep
        && container != null
        && !containerClass.isInstance(container)
        && !(container instanceof EntityLibrary)) {
      container = container.getContainer();
      if (container instanceof EntityLibrary) {
        return;
      }
    }

    if (container == null
        || !containerClass.isInstance(container) && !(container instanceof EntityLibrary)) {
      _delete(attribute);
      throw new IllegalActionException(
          attribute.getClass().getSimpleName()
              + " can only be added to "
              + containerClass.getSimpleName()
              + ".");
    }
  }
예제 #13
0
  protected void checkExceptionHandling(
      final LinkedBlockingQueue<Throwable> unexpectedExceptions,
      ExecutorTaskAgent agent,
      Future<?> future,
      Class<? extends Exception> expectedKlass,
      boolean isExpected)
      throws InterruptedException {

    try {
      future.get();
    } catch (ExecutionException ce) {
      assertTrue(expectedKlass.isInstance(ce.getCause()));
      // ok
    }
    agent.awaitPendingTasks();

    if (expectedKlass == null || isExpected) {
      assertTrue(unexpectedExceptions.size() == 0);
      return;
    } else {
      assertTrue(unexpectedExceptions.size() == 1);
      Throwable removed = unexpectedExceptions.remove();
      assertTrue(expectedKlass.isInstance(removed));
    }
  }
예제 #14
0
  public static <T> T createFromArg(Class<T> clz, Object value) {
    if (value == null) {
      return null;
    }
    ClassMeta meta = ClassMeta.classMeta(clz);
    List<ConstructorAccess> constructors = meta.oneArgumentConstructors();

    if (constructors.size() == 0) {
      return null;
    } else if (constructors.size() == 1) {
      ConstructorAccess constructorAccess = constructors.get(0);
      Class<?> arg1Type = constructorAccess.parameterTypes()[0];
      if (arg1Type.isInstance(value)) {
        return (T) constructorAccess.create(value);
      } else {
        return (T) constructorAccess.create(coerce(arg1Type, value));
      }
    } else {
      for (ConstructorAccess c : constructors) {
        Class<?> arg1Type = c.parameterTypes()[0];
        if (arg1Type.isInstance(value)) {
          return (T) c.create(value);
        }
      }

      for (ConstructorAccess c : constructors) {
        Class<?> arg1Type = c.parameterTypes()[0];
        if (arg1Type.isAssignableFrom(value.getClass())) {
          return (T) c.create(value);
        }
      }
    }
    return null;
  }
 /**
  * 检查该异常即其嵌套异常中是否包含特定的异常类型
  *
  * @param exType
  * @return
  */
 public boolean contains(Class exType) {
   if (exType == null) {
     return false;
   }
   if (exType.isInstance(this)) {
     return true;
   }
   Throwable cause = getCause();
   if (cause == this) {
     return false;
   }
   if (cause instanceof NestedRuntimeException) {
     return ((NestedRuntimeException) cause).contains(exType);
   } else {
     while (cause != null) {
       if (exType.isInstance(cause)) {
         return true;
       }
       if (cause.getCause() == cause) {
         break;
       }
       cause = cause.getCause();
     }
     return false;
   }
 }
예제 #16
0
 @Override
 public boolean run(Object a, Object b) {
   T tInstance = tK.cast(tK.isInstance(a) ? a : (tK.isInstance(b) ? b : null));
   V vInstance = vK.cast(vK.isInstance(b) ? b : (vK.isInstance(a) ? a : null));
   if (tInstance != null && vInstance != null && tInstance != vInstance) {
     return conflicts(tInstance, vInstance);
   } else return false;
 }
예제 #17
0
 public <A, T extends VoidVisitor<A>, VisType extends T, ArgType extends A> void addVoidListener(
     Class<VisType> visitorType, Class<ArgType> argType, In3<T, Node, A> listener) {
   addVoidListener(
       (vis, arg) ->
           (visitorType == null || visitorType.isInstance(vis))
               && (argType == null || argType.isInstance(arg)),
       listener);
 }
예제 #18
0
  @Test
  public void testAddGetter() throws Exception {
    final TestClassLoader loader = getTestClassLoader();
    final String targetClassName = "com.navercorp.pinpoint.profiler.interceptor.bci.TestObject3";

    loader.addTransformer(
        targetClassName,
        new TransformCallback() {

          @Override
          public byte[] doInTransform(
              Instrumentor instrumentContext,
              ClassLoader classLoader,
              String className,
              Class<?> classBeingRedefined,
              ProtectionDomain protectionDomain,
              byte[] classfileBuffer)
              throws InstrumentException {
            try {
              logger.info("modify cl:{}", classLoader);
              InstrumentClass aClass =
                  instrumentContext.getInstrumentClass(classLoader, className, classfileBuffer);

              aClass.addGetter(StringGetter.class.getName(), "value");
              aClass.addGetter(IntGetter.class.getName(), "intValue");

              return aClass.toBytecode();
            } catch (InstrumentException e) {
              throw new RuntimeException(e.getMessage(), e);
            }
          }
        });

    loader.initialize();

    Object testObject = loader.loadClass(targetClassName).newInstance();

    Class<?> stringGetter = loader.loadClass(StringGetter.class.getName());
    Class<?> intGetter = loader.loadClass(IntGetter.class.getName());

    Assert.assertTrue(stringGetter.isInstance(testObject));
    Assert.assertTrue(intGetter.isInstance(testObject));

    String value = "hehe";
    int intValue = 99;

    Method method = testObject.getClass().getMethod("setValue", String.class);
    method.invoke(testObject, value);

    Method getString = stringGetter.getMethod("_$PINPOINT$_getString");
    Assert.assertEquals(value, getString.invoke(testObject));

    Method setIntValue = testObject.getClass().getMethod("setIntValue", int.class);
    setIntValue.invoke(testObject, intValue);

    Method getInt = intGetter.getMethod("_$PINPOINT$_getInt");
    Assert.assertEquals(intValue, getInt.invoke(testObject));
  }
예제 #19
0
 public boolean is(final Class<?> type) {
   try {
     return type.isInstance(resource)
         || (Assembler.ResourceInstance.class.isInstance(resource)
             && type.isInstance(Assembler.ResourceInstance.class.cast(resource).getObject()));
   } catch (final NamingException e) {
     return false;
   }
 }
예제 #20
0
 /**
  * Replies the first nested exception of type <code>nestedClass</code> (including the root
  * exception <code>e</code>) or null, if no such exception is found.
  *
  * @param <T>
  * @param e the root exception
  * @param nestedClass the type of the nested exception
  * @return the first nested exception of type <code>nestedClass</code> (including the root
  *     exception <code>e</code>) or null, if no such exception is found.
  */
 protected static <T> T getNestedException(Exception e, Class<T> nestedClass) {
   Throwable t = e;
   while (t != null && !(nestedClass.isInstance(t))) {
     t = t.getCause();
   }
   if (t == null) return null;
   else if (nestedClass.isInstance(t)) return nestedClass.cast(t);
   return null;
 }
예제 #21
0
 public <R, A, T extends GenericVisitor<R, A>, VisType extends T, ArgType extends A>
     void addGenericListener(
         Class<VisType> visitorType, Class<ArgType> argType, In3Out1<T, Node, A, R> listener) {
   addGenericListener(
       (vis, arg) ->
           (visitorType == null || visitorType.isInstance(vis))
               && (argType == null || argType.isInstance(arg)),
       listener);
 }
예제 #22
0
 @Override
 public <T extends Tool> T getTool(final Class<T> toolClass) {
   for (final Tool tool : alwaysActiveToolList) {
     if (toolClass.isInstance(tool)) return toolClass.cast(tool);
   }
   for (final Tool tool : toolList) {
     if (toolClass.isInstance(tool)) return toolClass.cast(tool);
   }
   return null;
 }
 protected static <T> T assertInstance(Object o, Class<T> clazz, Class... cs) {
   assertNotNull("Expected " + clazz.getName() + " but got null", o);
   assertTrue(
       "Expected " + clazz.getName() + " but got " + o.getClass().getName(), clazz.isInstance(o));
   for (Class c : cs) {
     assertTrue(
         "Expected " + clazz.getName() + " but got " + o.getClass().getName(), c.isInstance(o));
   }
   return clazz.cast(o);
 }
예제 #24
0
파일: Widget.java 프로젝트: lcy03406/amber
 public <T extends Anim> void clearanims(Class<T> type) {
   for (Iterator<Anim> i = nanims.iterator(); i.hasNext(); ) {
     Anim a = i.next();
     if (type.isInstance(a)) i.remove();
   }
   for (Iterator<Anim> i = anims.iterator(); i.hasNext(); ) {
     Anim a = i.next();
     if (type.isInstance(a)) i.remove();
   }
 }
예제 #25
0
  public static List<Expression> getAllExpressions(ThingMLElement self, Class clazz) {
    List<Expression> result = new ArrayList<Expression>();
    TreeIterator<EObject> it = self.eAllContents();
    while (it.hasNext()) {
      EObject o = it.next();
      if (clazz.isInstance(o)) result.add((Expression) o);
    }

    if (clazz.isInstance(self)) result.add((Expression) self);
    return result;
  }
예제 #26
0
  /**
   * Asserts that the given code closure fails when it is evaluated and that a particular Exception
   * type can be attributed to the cause. The expected exception class is compared recursively with
   * any nested exceptions using getCause() until either a match is found or no more nested
   * exceptions exist.
   *
   * <p>If a match is found, the matching exception is returned otherwise the method will fail.
   *
   * @param expectedCause the class of the expected exception
   * @param code the closure that should fail
   * @return the cause
   */
  public static Throwable shouldFailWithCause(Class expectedCause, Closure code) {
    if (expectedCause == null) {
      fail("The expectedCause class cannot be null");
    }
    Throwable cause = null;
    Throwable orig = null;
    int level = 0;
    try {
      code.call();
    } catch (GroovyRuntimeException gre) {
      orig = ScriptBytecodeAdapter.unwrap(gre);
      cause = orig.getCause();
    } catch (Throwable e) {
      orig = e;
      cause = orig.getCause();
    }

    if (orig != null && cause == null) {
      fail(
          "Closure "
              + code
              + " was expected to fail due to a nested cause of type "
              + expectedCause.getName()
              + " but instead got a direct exception of type "
              + orig.getClass().getName()
              + " with no nested cause(s). Code under test has a bug or perhaps you meant shouldFail?");
    }

    while (cause != null
        && !expectedCause.isInstance(cause)
        && cause != cause.getCause()
        && level < MAX_NESTED_EXCEPTIONS) {
      cause = cause.getCause();
      level++;
    }

    if (orig == null) {
      fail(
          "Closure "
              + code
              + " should have failed with an exception having a nested cause of type "
              + expectedCause.getName());
    } else if (cause == null || !expectedCause.isInstance(cause)) {
      fail(
          "Closure "
              + code
              + " should have failed with an exception having a nested cause of type "
              + expectedCause.getName()
              + ", instead found these Exceptions:\n"
              + buildExceptionList(orig));
    }
    return cause;
  }
예제 #27
0
 public <T> T unwrap(Class<T> clazz) {
   if (clazz.isInstance(this)) {
     return clazz.cast(this);
   }
   if (clazz.isInstance(OptiqSchema.this)) {
     return clazz.cast(OptiqSchema.this);
   }
   if (clazz.isInstance(OptiqSchema.this.schema)) {
     return clazz.cast(OptiqSchema.this.schema);
   }
   throw new ClassCastException("not a " + clazz);
 }
 private void doTestConversionServiceInApplicationContext(String fileName, Class resourceClass) {
   ApplicationContext ctx = new ClassPathXmlApplicationContext(fileName, getClass());
   ResourceTestBean tb = ctx.getBean("resourceTestBean", ResourceTestBean.class);
   assertTrue(resourceClass.isInstance(tb.getResource()));
   assertTrue(tb.getResourceArray().length > 0);
   assertTrue(resourceClass.isInstance(tb.getResourceArray()[0]));
   assertTrue(tb.getResourceMap().size() == 1);
   assertTrue(resourceClass.isInstance(tb.getResourceMap().get("key1")));
   assertTrue(tb.getResourceArrayMap().size() == 1);
   assertTrue(tb.getResourceArrayMap().get("key1").length > 0);
   assertTrue(resourceClass.isInstance(tb.getResourceArrayMap().get("key1")[0]));
 }
예제 #29
0
 /**
  * This method uses reflection to determine if the two <code>Object</code>s are equal.
  *
  * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This
  * means that it will throw a security exception if run under a security manager, if the
  * permissions are not set up correctly. It is also not as efficient as testing explicitly.
  *
  * <p>If the testTransients parameter is set to <code>true</code>, transient members will be
  * tested, otherwise they are ignored, as they are likely derived fields, and not part of the
  * value of the <code>Object</code>.
  *
  * <p>Static fields will not be included. Superclass fields will be appended up to and including
  * the specified superclass. A null superclass is treated as java.lang.Object.
  *
  * @param lhs <code>this</code> object
  * @param rhs the other object
  * @param testTransients whether to include transient fields
  * @param reflectUpToClass the superclass to reflect up to (inclusive), may be <code>null</code>
  * @param excludeFields array of field names to exclude from testing
  * @return <code>true</code> if the two Objects have tested equals.
  * @since 2.0
  */
 public static boolean reflectionEquals(
     Object lhs,
     Object rhs,
     boolean testTransients,
     Class<?> reflectUpToClass,
     String... excludeFields) {
   if (lhs == rhs) {
     return true;
   }
   if (lhs == null || rhs == null) {
     return false;
   }
   // Find the leaf class since there may be transients in the leaf
   // class or in classes between the leaf and root.
   // If we are not testing transients or a subclass has no ivars,
   // then a subclass can test equals to a superclass.
   Class<?> lhsClass = lhs.getClass();
   Class<?> rhsClass = rhs.getClass();
   Class<?> testClass;
   if (lhsClass.isInstance(rhs)) {
     testClass = lhsClass;
     if (!rhsClass.isInstance(lhs)) {
       // rhsClass is a subclass of lhsClass
       testClass = rhsClass;
     }
   } else if (rhsClass.isInstance(lhs)) {
     testClass = rhsClass;
     if (!lhsClass.isInstance(rhs)) {
       // lhsClass is a subclass of rhsClass
       testClass = lhsClass;
     }
   } else {
     // The two classes are not related.
     return false;
   }
   EqualsBuilder equalsBuilder = new EqualsBuilder();
   try {
     reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients, excludeFields);
     while (testClass.getSuperclass() != null && testClass != reflectUpToClass) {
       testClass = testClass.getSuperclass();
       reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients, excludeFields);
     }
   } catch (IllegalArgumentException e) {
     // In this case, we tried to test a subclass vs. a superclass and
     // the subclass has ivars or the ivars are transient and
     // we are testing transients.
     // If a subclass has ivars that we are trying to test them, we get an
     // exception and we know that the objects are not equal.
     return false;
   }
   return equalsBuilder.isEquals();
 }
 /**
  * Unwraps nested wrapped writers until the given writer class is found.
  *
  * @param writerClass Class of the desired nested writer. If null, the core writer (i.e., deepest
  *     wrapped writer) will be returned.
  * @param id Id to use as a basis when unwrapping any nested {@link ImageWriter}s. If null, the
  *     current id is used.
  */
 public IFormatWriter unwrap(Class<? extends IFormatWriter> writerClass, String id)
     throws FormatException, IOException {
   IFormatWriter w = this;
   while (w instanceof WriterWrapper || w instanceof ImageWriter) {
     if (writerClass != null && writerClass.isInstance(w)) break;
     if (w instanceof ImageWriter) {
       ImageWriter iw = (ImageWriter) w;
       w = id == null ? iw.getWriter() : iw.getWriter(id);
     } else w = ((WriterWrapper) w).getWriter();
   }
   if (writerClass != null && !writerClass.isInstance(w)) return null;
   return w;
 }