docs: @SuppressWarnings("unchecked")
      public <T> T unwrap(final Class<T> interfaceClass) throws SQLException 
      {
          TraceComponent tc = getTracer();
          if (tc.isEntryEnabled())
              Tr.entry(this, tc, "unwrap", interfaceClass);
  
          activate(); 
  
          Object result;
  
          // Return the current wrapper if it already implements the interface.
  
          if (interfaceClass.isInstance(this))
              result = this;
  
          // Return an existing dynamic wrapper if one already exists for the interface.
  
          else if (ifcToDynamicWrapper.containsKey(interfaceClass))
              result = ifcToDynamicWrapper.get(interfaceClass);
  
          // Otherwise, see if any of the wrapped objects implement (or themselves wrap)
          // the interface.
  
          else
              try 
              {
                  if (tc.isDebugEnabled())
                      Tr.debug(this, tc,
                               "No existing wrappers found. Need to create a new wrapper.");
  
                  Object implObject = getJDBCImplObject(interfaceClass);
  
                  if (implObject == null // Not found
                      || !interfaceClass.isInterface()) // or not an interface. 
                  {
                      throw new SQLException( 
                      AdapterUtil.getNLSMessage("NO_WRAPPED_OBJECT", this, interfaceClass.getName())); 
                  }
  
                  if (tc.isDebugEnabled())
                      Tr.debug(this, tc,
                               "Creating a wrapper for:", AdapterUtil.toString(implObject));
  
                  // An implementation object is found. Create a new wrapper for it.
                  // And then add it to the map of dynamic wrappers.
                  result = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                      public Object run() {
                          return Proxy.newProxyInstance(interfaceClass.getClassLoader(),
                                                        new Class[] { interfaceClass },
                                                        WSJdbcWrapper.this);
                      }
                  });
  
                  ifcToDynamicWrapper.put(interfaceClass, result);
                  dynamicWrapperToImpl.put(result, implObject);
              }
              catch (SQLException sqlX) {
                  FFDCFilter.processException(
                                              sqlX, getClass().getName() + ".unwrap", "441", this);
                  if (tc.isEntryEnabled())
                      Tr.exit(this, tc, "unwrap", sqlX);
                  throw WSJdbcUtil.mapException(this, sqlX);
              } catch (NullPointerException nullX) {
                  // No FFDC code needed; we might be closed.
                  throw runtimeXIfNotClosed(nullX);
              } catch (RuntimeException runX) {
                  FFDCFilter.processException(
                                              runX, getClass().getName() + ".unwrap", "451", this);
                  if (tc.isEntryEnabled())
                      Tr.exit(this, tc, "unwrap", runX);
                  throw runX;
              } catch (Error err) {
                  FFDCFilter.processException(
                                              err, getClass().getName() + ".unwrap", "458", this);
                  if (tc.isEntryEnabled())
                      Tr.exit(this, tc, "unwrap", err);
                  throw err;
              }
  
          if (tc.isEntryEnabled())
              Tr.exit(this, tc, "unwrap", result);
          return (T) result;
      }