gt: 		if (current==null) return old!=null;
context: /*
   * Hibernate, Relational Persistence for Idiomatic Java
   *
   * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
   * indicated by the @author tags or express copyright attribution
   * statements applied by the authors.  All third-party contributions are
   * distributed under license by Red Hat Middleware LLC.
   *
   * This copyrighted material is made available to anyone wishing to use, modify,
   * copy, or redistribute it subject to the terms and conditions of the GNU
   * Lesser General Public License, as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   * for more details.
   *
   * You should have received a copy of the GNU Lesser General Public License
   * along with this distribution; if not, write to:
   * Free Software Foundation, Inc.
   * 51 Franklin Street, Fifth Floor
   * Boston, MA  02110-1301  USA
   *
   */
  package org.hibernate.type;
  
  import java.io.Serializable;
  import java.lang.reflect.Method;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.util.Arrays;
  import java.util.Map;
  
  import org.dom4j.Node;
  import org.hibernate.EntityMode;
  import org.hibernate.FetchMode;
  import org.hibernate.Hibernate;
  import org.hibernate.HibernateException;
  import org.hibernate.MappingException;
  import org.hibernate.TransientObjectException;
  import org.hibernate.engine.CascadeStyle;
  import org.hibernate.engine.ForeignKeys;
  import org.hibernate.engine.Mapping;
  import org.hibernate.engine.SessionFactoryImplementor;
  import org.hibernate.engine.SessionImplementor;
  import org.hibernate.persister.entity.Joinable;
  import org.hibernate.proxy.HibernateProxyHelper;
  import org.hibernate.util.ArrayHelper;
  
  /**
   * Handles "any" mappings and the old deprecated "object" type
   * @author Gavin King
   */
  public class AnyType extends AbstractType implements AbstractComponentType, AssociationType {
  
  	private final Type identifierType;
  	private final Type metaType;
  
  	public AnyType(Type metaType, Type identifierType) {
  		this.identifierType = identifierType;
  		this.metaType = metaType;
  	}
  
  	public AnyType() {
  		this(Hibernate.STRING, Hibernate.SERIALIZABLE);
  	}
  
  	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)
  	throws HibernateException {
  		return value;
  	}
  	
  	public boolean isMethodOf(Method method) {
  		return false;
  	}
  
  	public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException {
  		return x==y;
  	}
  
  	public int compare(Object x, Object y, EntityMode entityMode) {
  		return 0; //TODO: entities CAN be compared, by PK and entity name, fix this!
  	}
  
  	public int getColumnSpan(Mapping session)
  	throws MappingException {
  		return 2;
  	}
  
  	public String getName() {
  		return "object";
  	}
  
  	public boolean isMutable() {
  		return false;
  	}
  
  	public Object nullSafeGet(ResultSet rs,	String name, SessionImplementor session, Object owner)
  	throws HibernateException, SQLException {
  
  		throw new UnsupportedOperationException("object is a multicolumn type");
  	}
  
  	public Object nullSafeGet(ResultSet rs,	String[] names,	SessionImplementor session,	Object owner)
  	throws HibernateException, SQLException {
  		return resolveAny(
  				(String) metaType.nullSafeGet(rs, names[0], session, owner),
  				(Serializable) identifierType.nullSafeGet(rs, names[1], session, owner),
  				session
  			);
  	}
  
  	public Object hydrate(ResultSet rs,	String[] names,	SessionImplementor session,	Object owner)
  	throws HibernateException, SQLException {
  		String entityName = (String) metaType.nullSafeGet(rs, names[0], session, owner);
  		Serializable id = (Serializable) identifierType.nullSafeGet(rs, names[1], session, owner);
  		return new ObjectTypeCacheEntry(entityName, id);
  	}
  
  	public Object resolve(Object value, SessionImplementor session, Object owner)
  	throws HibernateException {
  		ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) value;
  		return resolveAny(holder.entityName, holder.id, session);
  	}
  
  	public Object semiResolve(Object value, SessionImplementor session, Object owner)
  	throws HibernateException {
  		throw new UnsupportedOperationException("any mappings may not form part of a property-ref");
  	}
  	
  	private Object resolveAny(String entityName, Serializable id, SessionImplementor session)
  	throws HibernateException {
  		return entityName==null || id==null ?
  				null : session.internalLoad( entityName, id, false, false );
  	}
  
  	public void nullSafeSet(PreparedStatement st, Object value,	int index, SessionImplementor session)
  	throws HibernateException, SQLException {
  		nullSafeSet(st, value, index, null, session);
  	}
  	
  	public void nullSafeSet(PreparedStatement st, Object value,	int index, boolean[] settable, SessionImplementor session)
  	throws HibernateException, SQLException {
  
  		Serializable id;
  		String entityName;
  		if (value==null) {
  			id=null;
  			entityName=null;
  		}
  		else {
  			entityName = session.bestGuessEntityName(value);
  			id = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, value, session);
  		}
  		
  		// metaType is assumed to be single-column type
  		if ( settable==null || settable[0] ) {
  			metaType.nullSafeSet(st, entityName, index, session);
  		}
  		if (settable==null) {
  			identifierType.nullSafeSet(st, id, index+1, session);
  		}
  		else {
  			boolean[] idsettable = new boolean[ settable.length-1 ];
  			System.arraycopy(settable, 1, idsettable, 0, idsettable.length);
  			identifierType.nullSafeSet(st, id, index+1, idsettable, session);
  		}
  	}
  
  	public Class getReturnedClass() {
  		return Object.class;
  	}
  
  	public int[] sqlTypes(Mapping mapping) throws MappingException {
  		return ArrayHelper.join(
  				metaType.sqlTypes(mapping),
  				identifierType.sqlTypes(mapping)
  			);
  	}
  
  	public void setToXMLNode(Node xml, Object value, SessionFactoryImplementor factory) {
  		throw new UnsupportedOperationException("any types cannot be stringified");
  	}
  
  	public String toLoggableString(Object value, SessionFactoryImplementor factory) 
  	throws HibernateException {
  		//TODO: terrible implementation!
  		return value==null ?
  				"null" :
  				Hibernate.entity( HibernateProxyHelper.getClassWithoutInitializingProxy(value) )
  						.toLoggableString(value, factory);
  	}
  
  	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
  		throw new UnsupportedOperationException(); //TODO: is this right??
  	}
  
  	public static final class ObjectTypeCacheEntry implements Serializable {
  		String entityName;
  		Serializable id;
  		ObjectTypeCacheEntry(String entityName, Serializable id) {
  			this.entityName = entityName;
  			this.id = id;
  		}
  	}
  
  	public Object assemble(
  		Serializable cached,
  		SessionImplementor session,
  		Object owner)
  	throws HibernateException {
  
  		ObjectTypeCacheEntry e = (ObjectTypeCacheEntry) cached;
  		return e==null ? null : session.internalLoad(e.entityName, e.id, false, false);
  	}
  
  	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
  	throws HibernateException {
  		return value==null ?
  			null :
  			new ObjectTypeCacheEntry(
  						session.bestGuessEntityName(value),
  						ForeignKeys.getEntityIdentifierIfNotUnsaved( 
  								session.bestGuessEntityName(value), value, session 
  							)
  					);
  	}
  
  	public boolean isAnyType() {
  		return true;
  	}
  
  	public Object replace(
  			Object original, 
  			Object target,
  			SessionImplementor session, 
  			Object owner, 
  			Map copyCache)
  	throws HibernateException {
  		if (original==null) {
  			return null;
  		}
  		else {
  			String entityName = session.bestGuessEntityName(original);
  			Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved( 
  					entityName, 
  					original, 
  					session 
  				);
  			return session.internalLoad( 
  					entityName, 
  					id, 
  					false, 
  					false
  				);
  		}
  	}
  	public CascadeStyle getCascadeStyle(int i) {
  		return CascadeStyle.NONE;
  	}
  
  	public FetchMode getFetchMode(int i) {
  		return FetchMode.SELECT;
  	}
  
  	private static final String[] PROPERTY_NAMES = new String[] { "class", "id" };
  
  	public String[] getPropertyNames() {
  		return PROPERTY_NAMES;
  	}
  
  	public Object getPropertyValue(Object component, int i, SessionImplementor session)
  		throws HibernateException {
  
  		return i==0 ?
  				session.bestGuessEntityName(component) :
  				getIdentifier(component, session);
  	}
  
  	public Object[] getPropertyValues(Object component, SessionImplementor session)
  		throws HibernateException {
  
  		return new Object[] { session.bestGuessEntityName(component), getIdentifier(component, session) };
  	}
  
  	private Serializable getIdentifier(Object value, SessionImplementor session) throws HibernateException {
  		try {
  			return ForeignKeys.getEntityIdentifierIfNotUnsaved( session.bestGuessEntityName(value), value, session );
  		}
  		catch (TransientObjectException toe) {
  			return null;
  		}
  	}
  
  	public Type[] getSubtypes() {
  		return new Type[] { metaType, identifierType };
  	}
  
  	public void setPropertyValues(Object component, Object[] values, EntityMode entityMode)
  		throws HibernateException {
  
  		throw new UnsupportedOperationException();
  
  	}
  
  	public Object[] getPropertyValues(Object component, EntityMode entityMode) {
  		throw new UnsupportedOperationException();
  	}
  
  	public boolean isComponentType() {
  		return true;
  	}
  
  	public ForeignKeyDirection getForeignKeyDirection() {
  		//return AssociationType.FOREIGN_KEY_TO_PARENT; //this is better but causes a transient object exception...
  		return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT;
  	}
  
  	public boolean isAssociationType() {
  		return true;
  	}
  
  	public boolean useLHSPrimaryKey() {
  		return false;
  	}
  
  	public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) {
  		throw new UnsupportedOperationException("any types do not have a unique referenced persister");
  	}
  
  	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session)
  	throws HibernateException {
  