public <T, K> T don( K core, Class<T> trait, boolean logical ) {
TraitFactory builder = new TraitFactory( this.getKnowledgeRuntime().getKnowledgeBase() );
TraitableBean inner;
if ( core instanceof TraitableBean) {
inner = (TraitableBean) core;
} else {
CoreWrapper<K> wrapper = builder.getCoreWrapper( core.getClass() );
if ( wrapper == null ) {
throw new UnsupportedOperationException( "Error: cannot apply a trait to non-traitable class " + core.getClass() );
}
wrapper.init( core );
inner = wrapper;
this.update( getFactHandle( core ), inner );
}
T thing;
if ( inner.hasTrait( trait.getName() ) ) {
return (T) inner.getTrait( trait.getName() );
} else {
thing = (T) builder.getProxy( inner, trait );
}
if ( ! inner.hasTrait( Thing.class.getName() ) ) {
insert( don( inner, Thing.class, false ) );
}
if ( logical ) {
insertLogical( thing );