Really sorry about this - again a new version.
1. ==================
A test has been brought up to date with the changed contract
of ContextManager.
(Accidentially submitted the patch before the test series completed)
2. ==================
DefaultContainerManager was left without a logger as LoggerManager
was no longer put to m_containerManagerContext.
This version of the patch adds a LOGGER constant to
ContainerManagerConstants and makes ContextManager pass its
own logger to DefaultContainerManager.
This even looks a code simplification to me:
1) we no longer deal with LoggerManager in DefaultContainerManager,
only with Logger
2) in the following rare situation
(usage scenario not promoted by any examples but
theoretically possible)
ContextManager ctxm = new ContextManager( fortressConfig.getContext(),
my-unique-and-desired-logger );
ContainerManager ctnm = new DefaultContainerManager( cm );
ContainerManager will use the same logger as was
passed to the ContextManager, which is probably desirable
as ContextManager is only a spare part used by ContainerManager
and they should act as a one thing.
Without this change ContainerManager in this situation will use
loggerManager.getDefaultLogger().
I agree the example above could be rewritten as
ContextManager ctxm = new ContextManager( fortressConfig.getContext(),
my-unique-and-desired-logger
);
ContainerManager ctnm = new DefaultContainerManager( cm,
my-unique-and-desired-logger );
In this situaion both Context and Container manager will use
the desired logger even without the change, but still see
this change as bringing a 0.001% enhancment to system behavior.
WBR, Anton
P.S. Aren't you tired from my refactoring the code?
XP says it's a good thing, and what do you say? ;-)
P.P.S.
Hopefully this has been my last pass on ContextManager,
(unless someone says: oh, it was so nice to pass all the
stuff to Container via Context, not ServiceManager :-)
diff -ru
avalon-excalibur.0/event/src/java/org/apache/excalibur/event/command/CommandManager.java
avalon-excalibur/event/src/java/org/apache/excalibur/event/command/CommandManager.java
---
avalon-excalibur.0/event/src/java/org/apache/excalibur/event/command/CommandManager.java
2003-03-22 15:46:28.000000000 +0300
+++
avalon-excalibur/event/src/java/org/apache/excalibur/event/command/CommandManager.java
2003-05-28 14:09:50.000000000 +0400
@@ -130,6 +130,16 @@
}
/**
+ * Get the Command Queue so that you can enqueue and dequeue commands.
+ *
+ * @return the Sink that feeds the CommandManager
+ */
+ public final Queue getCommandQueue()
+ {
+ return m_queue;
+ }
+
+ /**
* Register a Signal with an EventHandler. The Signal is a special object
* that implements the [EMAIL PROTECTED] Signal} interface. When CommandManager
recieves
* events that match the Signal, it will send a copy of it to all the
diff -ru
avalon-excalibur.0/fortress/src/java/org/apache/avalon/fortress/ContainerManagerConstants.java
avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/ContainerManagerConstants.java
---
avalon-excalibur.0/fortress/src/java/org/apache/avalon/fortress/ContainerManagerConstants.java
2003-04-22 16:37:08.000000000 +0400
+++
avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/ContainerManagerConstants.java
2003-05-28 14:57:14.000000000 +0400
@@ -49,6 +49,7 @@
*/
package org.apache.avalon.fortress;
+import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.ServiceManager;
/**
@@ -72,6 +73,11 @@
String SERVICE_MANAGER = ServiceManager.class.getName();
/**
+ * Logger where to log our own messages.
+ */
+ String LOGGER = Logger.class.getName();
+
+ /**
* Configuration: The configuration to give to the impl.
*/
String CONFIGURATION = "impl.configuration";
diff -ru
avalon-excalibur.0/fortress/src/java/org/apache/avalon/fortress/impl/DefaultContainerManager.java
avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/DefaultContainerManager.java
---
avalon-excalibur.0/fortress/src/java/org/apache/avalon/fortress/impl/DefaultContainerManager.java
2003-05-28 10:20:10.000000000 +0400
+++
avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/DefaultContainerManager.java
2003-05-28 14:55:52.000000000 +0400
@@ -49,7 +49,6 @@
*/
package org.apache.avalon.fortress.impl;
-import org.apache.avalon.excalibur.logger.LoggerManager;
import org.apache.avalon.fortress.*;
import org.apache.avalon.fortress.util.ContextManager;
import org.apache.avalon.fortress.util.LifecycleExtensionManager;
@@ -143,8 +142,8 @@
{
try
{
- final LoggerManager loggerManager = (LoggerManager) initParameters.get(
LoggerManager.ROLE );
- return loggerManager.getDefaultLogger();
+ final Logger logger = (Logger) initParameters.get( LOGGER );
+ return logger;
}
catch ( ContextException ce )
{
@@ -205,7 +204,8 @@
ContainerUtil.enableLogging( instance, m_logger );
ContainerUtil.contextualize( instance, implContext );
- final ServiceManager serviceManager = createServiceManager( implContext );
+ final ServiceManager serviceManager =
+ (ServiceManager) getContextEntry( managerContext, SERVICE_MANAGER );
ContainerUtil.service( instance, serviceManager );
@@ -230,38 +230,6 @@
}
}
- private ServiceManager createServiceManager( final Context managerContext )
- {
- final ServiceManager smanager =
- (ServiceManager) getContextEntry( managerContext, SERVICE_MANAGER );
- final DefaultServiceManager serviceManager = new DefaultServiceManager(
smanager );
-
- addService( Queue.ROLE, managerContext, serviceManager );
- addService( LoggerManager.ROLE, managerContext, serviceManager );
- addService( PoolManager.ROLE, managerContext, serviceManager );
- addService( InstrumentManager.ROLE, managerContext, serviceManager );
- addService( MetaInfoManager.ROLE, managerContext, serviceManager );
- addService( RoleManager.ROLE, managerContext, serviceManager );
- addService( LifecycleExtensionManager.ROLE, managerContext, serviceManager );
- serviceManager.makeReadOnly();
-
- return serviceManager;
- }
-
- private void addService( final String role,
- final Context context,
- final DefaultServiceManager serviceManager )
- {
- try
- {
- final Object object = context.get( role );
- serviceManager.put( role, object );
- }
- catch ( ContextException e )
- {
- }
- }
-
/**
* Retrieve an entry from context if it exists, else return null.
*
diff -ru
avalon-excalibur.0/fortress/src/java/org/apache/avalon/fortress/util/ContextManager.java
avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/util/ContextManager.java
---
avalon-excalibur.0/fortress/src/java/org/apache/avalon/fortress/util/ContextManager.java
2003-05-28 10:20:26.000000000 +0400
+++
avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/util/ContextManager.java
2003-05-28 14:54:54.000000000 +0400
@@ -74,7 +74,6 @@
import org.apache.avalon.framework.service.DefaultServiceSelector;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.excalibur.event.Queue;
-import org.apache.excalibur.event.Sink;
import org.apache.excalibur.event.command.CommandManager;
import org.apache.excalibur.event.command.TPCThreadManager;
import org.apache.excalibur.event.command.ThreadManager;
@@ -103,20 +102,16 @@
* get an instance of the Context, it is made read-only and returned. No
* further operations will be possible on it.</p>
*
- * <p>You can get two different contexts from the ContextManager: the child
- * context and the impl manager context. The former contains all
- * managers, such as the pool manager etc. necessary for a child impl to
- * create additional child containers. The impl manager context contains
- * all of the child context, but also initialization parameters for the
- * impl, such as a Configuration object, a ComponentLocator, etc., that
- * the impl wants, but does not want to pass on to its children.</p>
+ * <p>You can get two different contexts from the ContextManager:
+ * the container context (m_childContext)
+ * and the container manager context (m_contaimerManagerContext).
*
- * <p>You would typically use the impl manager context to initialize
- * the impl manager, and let it pass the child context on to the
- * impl.</p>
+ * <p>The container manager context is used to provide the container manager
+ * with all the data needed to initialize the container.</p>
+ * <p>The container context is passed directly to the container.</p>
*
- * <p>The ContextManager will sometimes create new components, such as a
- * component manager, a pool manager, etc. It will manage these components
+ * <p>The ContextManager will sometimes create new components, such as
+ * a service manager, a pool manager, etc. It will manage these components
* and dispose of them properly when it itself is disposed .</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
@@ -139,21 +134,21 @@
/**
* The root context.
*/
- private final Context m_rootContext;
+ protected final Context m_rootContext;
/**
* The context of the new impl. This context has the rootContext
* as its parent. Put everything here that you want the new impl
* to have in its own context.
*/
- private final DefaultContext m_childContext;
+ protected final DefaultContext m_childContext;
/**
* Container manager's context. This context has the child context
* as parent. Put things here that you want the impl manager
* to see, but do not wish to expose to the impl.
*/
- private final DefaultContext m_containerManagerContext;
+ protected final DefaultContext m_containerManagerContext;
/**
* New context passed in, maybe from a FortressConfig.
@@ -161,9 +156,45 @@
* other pointers. The ContextManager inspects it for
* elements it can use to create component managers etc.
*/
- private Logger m_logger;
- private final Logger m_primordialLogger;
- private ServiceManager m_manager;
+ protected Logger m_logger;
+ protected final Logger m_primordialLogger;
+
+ /**
+ * Source resolver used to read-in the configurations.
+ * and provided as a default source resolver if the
+ * user has not supplied a ServiceManager.
+ */
+ protected SourceResolver m_defaultSourceResolver;
+
+ /**
+ * The logger manager in use.
+ * Either supplied via rootContext, or created locally.
+ */
+ protected LoggerManager m_loggerManager;
+
+ /**
+ * The Queue in use.
+ * Either supplied via rootContext or created locally.
+ */
+ protected Queue m_queue;
+
+ /**
+ * The MetaInfoManager to be used by the container.
+ * Either supplied via rootContext or created locally.
+ */
+ protected MetaInfoManager m_metaInfoManager;
+
+ /**
+ * The PoolManager to be used by the container.
+ * Either supplied via rootContext or created locally.
+ */
+ protected PoolManager m_poolManager;
+
+ /**
+ * The InstrumentManager to be used by the container.
+ * Either supplied via rootContext or created locally.
+ */
+ protected InstrumentManager m_instrumentManager;
/**
* The components that are "owned" by this context and should
@@ -219,7 +250,7 @@
*
* @throws IllegalArgumentException if the object is null.
*/
- private void assumeOwnership( final Object object )
+ protected void assumeOwnership( final Object object )
{
if ( object == null )
{
@@ -237,7 +268,7 @@
*/
public void initialize() throws Exception
{
- initializeServiceManager();
+ initializeDefaultSourceResolver();
initializeLoggerManager();
initializeMetaInfoManager();
initializeCommandQueue();
@@ -245,9 +276,12 @@
initializeContext();
initializeInstrumentManager();
initializeConfiguration();
+ initializeServiceManager();
m_childContext.makeReadOnly();
m_containerManagerContext.makeReadOnly();
+
+ m_defaultSourceResolver = null;
}
/**
@@ -295,6 +329,22 @@
getLogger().debug( "Could not copy Context parameters. This may be Ok
depending on "
+ "other configured context values." );
}
+
+ // hide from the container implementation what it does not need
+ m_childContext.put( CONFIGURATION, null );
+ m_childContext.put( CONFIGURATION_URI, null );
+ m_childContext.put( RoleManager.ROLE, null );
+ m_childContext.put( ROLE_MANAGER_CONFIGURATION, null );
+ m_childContext.put( ROLE_MANAGER_CONFIGURATION_URI, null );
+ m_childContext.put( LoggerManager.ROLE, null );
+ m_childContext.put( LOGGER_MANAGER_CONFIGURATION, null );
+ m_childContext.put( LOGGER_MANAGER_CONFIGURATION_URI, null );
+ m_childContext.put( InstrumentManager.ROLE, null );
+ m_childContext.put( INSTRUMENT_MANAGER_CONFIGURATION, null );
+ m_childContext.put( INSTRUMENT_MANAGER_CONFIGURATION_URI, null );
+ m_childContext.put( Queue.ROLE, null );
+ m_childContext.put( MetaInfoManager.ROLE, null );
+ m_childContext.put( PoolManager.ROLE, null );
}
/**
@@ -392,15 +442,13 @@
{
try
{
- m_rootContext.get( Queue.ROLE );
- return;
+ m_queue = (Queue) m_rootContext.get( Queue.ROLE );
}
catch ( ContextException ce )
{
+ // No CommandQueue specified, create a default one
+ m_queue = createCommandQueue();
}
-
- // No CommandQueue specified, create a default one
- m_childContext.put( Queue.ROLE, createCommandSink() );
}
/**
@@ -409,7 +457,7 @@
* @return a default <code>CommandQueue</code>
* @throws Exception if an error occurs
*/
- private Sink createCommandSink() throws Exception
+ private Queue createCommandQueue() throws Exception
{
final CommandManager cm = new CommandManager();
final ThreadManager tm = new TPCThreadManager();
@@ -417,11 +465,8 @@
assumeOwnership( cm );
assumeOwnership( tm );
- // Get the context Logger Manager
- final LoggerManager loggerManager = (LoggerManager) m_childContext.get(
LoggerManager.ROLE );
-
// Get the logger for the thread manager
- final Logger tmLogger = loggerManager.getLoggerForCategory(
"system.threadmgr" );
+ final Logger tmLogger = m_loggerManager.getLoggerForCategory(
"system.threadmgr" );
ContainerUtil.enableLogging( tm, tmLogger );
ContainerUtil.parameterize( tm, buildCommandQueueConfig() );
@@ -429,7 +474,7 @@
tm.register( cm );
- return cm.getCommandSink();
+ return cm.getCommandQueue();
}
/**
@@ -487,16 +532,14 @@
{
try
{
- m_rootContext.get( PoolManager.ROLE );
- return;
+ m_poolManager = (PoolManager) m_rootContext.get( PoolManager.ROLE );
}
catch ( ContextException ce )
{
+ final PoolManager pm = new DefaultPoolManager( m_queue );
+ assumeOwnership( pm );
+ m_poolManager = pm;
}
-
- final PoolManager pm = new DefaultPoolManager( (Sink) m_childContext.get(
Queue.ROLE ) );
- assumeOwnership( pm );
- m_childContext.put( PoolManager.ROLE, pm );
}
/**
@@ -534,14 +577,11 @@
return null;
}
- // Get the context Logger Manager
- final LoggerManager loggerManager = (LoggerManager) m_childContext.get(
LoggerManager.ROLE );
-
// Lookup the context class loader
final ClassLoader classLoader = (ClassLoader) m_rootContext.get(
ClassLoader.class.getName() );
// Create a logger for the role manager
- final Logger rmLogger = loggerManager.getLoggerForCategory(
+ final Logger rmLogger = m_loggerManager.getLoggerForCategory(
roleConfig.getAttribute( "logger", "system.roles" ) );
// Create a parent role manager with all the default roles
@@ -560,7 +600,17 @@
protected void initializeMetaInfoManager() throws Exception
{
- final boolean mmSupplied = entryPresent( m_rootContext, MetaInfoManager.ROLE
);
+ boolean mmSupplied = false;
+ try
+ {
+ m_metaInfoManager = (MetaInfoManager) m_rootContext.get(
MetaInfoManager.ROLE );
+ mmSupplied = true;
+ }
+ catch( ContextException ce )
+ {
+ // okay, we will create one
+ }
+
RoleManager roleManager = obtainRoleManager();
final boolean rmSupplied = roleManager != null;
@@ -575,13 +625,12 @@
}
else
{
- final LoggerManager loggerManager = (LoggerManager)m_childContext.get(
LoggerManager.ROLE );
final ClassLoader classLoader = (ClassLoader)m_rootContext.get(
ClassLoader.class.getName() );
if ( ! rmSupplied )
{
final FortressRoleManager newRoleManager = new FortressRoleManager(
null, classLoader );
-
newRoleManager.enableLogging(loggerManager.getLoggerForCategory("system.roles"));
+
newRoleManager.enableLogging(m_loggerManager.getLoggerForCategory("system.roles"));
newRoleManager.initialize();
roleManager = newRoleManager;
@@ -589,24 +638,19 @@
final ServiceMetaManager metaManager = new ServiceMetaManager( new
Role2MetaInfoManager( roleManager ), classLoader );
- metaManager.enableLogging(
loggerManager.getLoggerForCategory("system.meta") );
+ metaManager.enableLogging(
m_loggerManager.getLoggerForCategory("system.meta") );
metaManager.initialize();
assumeOwnership( metaManager );
- m_childContext.put( MetaInfoManager.ROLE, metaManager );
+ m_metaInfoManager = metaManager;
}
}
/**
- * Get a reference to the initial ComponentLocator used by the
- * ContainerManager to hold the Components used for parsing the config
- * files and setting up the environment.
- *
- * @throws Exception when there is an error.
+ * Initialize the default SrouceResolver.
*/
- protected void initializeServiceManager() throws Exception
+ protected void initializeDefaultSourceResolver() throws Exception
{
- final ServiceManager parent = (ServiceManager) get( m_rootContext,
SERVICE_MANAGER, null );
- final DefaultServiceManager manager = new DefaultServiceManager( parent );
+ final DefaultServiceManager manager = new DefaultServiceManager();
final DefaultServiceSelector selector = new DefaultServiceSelector();
final URLSourceFactory file = new URLSourceFactory();
file.enableLogging( getLogger() );
@@ -623,15 +667,41 @@
ContainerUtil.service( resolver, manager );
ContainerUtil.parameterize( resolver, new Parameters() );
- manager.put( SourceResolver.ROLE, resolver );
-
- manager.makeReadOnly();
-
- assumeOwnership( manager );
+ m_defaultSourceResolver = resolver;
+ }
+ /**
+ * Get a reference to the initial ComponentLocator used by the
+ * ContainerManager to hold the Components used for parsing the config
+ * files and setting up the environment.
+ *
+ * @throws Exception when there is an error.
+ */
+ protected void initializeServiceManager() throws Exception
+ {
+ final ServiceManager parent = (ServiceManager) get( m_rootContext,
SERVICE_MANAGER, null );
+ final DefaultServiceManager manager = new DefaultServiceManager( parent );
- m_manager = manager;
+ /**
+ * We assume that if there is a parent ServiceManager provided,
+ * there is a SourceResolver mounted there. And if there
+ * is none, then it is the true caller's intetion.
+ * However it is hard to imagine how that could be usefull
+ * except for testing purposes.
+ */
+ if ( parent == null )
+ {
+ manager.put( SourceResolver.ROLE, m_defaultSourceResolver );
+ }
+
+ manager.put( LoggerManager.ROLE, m_loggerManager );
+ manager.put( Queue.ROLE, m_queue );
+ manager.put( MetaInfoManager.ROLE, m_metaInfoManager );
+ manager.put( PoolManager.ROLE, m_poolManager );
+ manager.put( InstrumentManager.ROLE, m_instrumentManager );
- m_childContext.put( ContextManagerConstants.SERVICE_MANAGER, m_manager );
+ manager.makeReadOnly();
+
+ m_containerManagerContext.put( SERVICE_MANAGER, manager );
}
/**
@@ -668,8 +738,7 @@
Source src = null;
try
{
- resolver = (SourceResolver) m_manager.lookup( SourceResolver.ROLE );
- src = resolver.resolveURI( configUri );
+ src = m_defaultSourceResolver.resolveURI( configUri );
if ( configBuilder == null )
{
configBuilder = new DefaultConfigurationBuilder();
@@ -685,12 +754,7 @@
}
finally
{
- if ( null != resolver )
- {
- resolver.release( src );
- }
-
- m_manager.release( resolver );
+ m_defaultSourceResolver.release( src );
}
}
@@ -747,7 +811,7 @@
{
// Try copying an already existing logger manager from the override
context.
- m_childContext.put( LoggerManager.ROLE, m_rootContext.get(
LoggerManager.ROLE ) );
+ m_loggerManager = (LoggerManager) m_rootContext.get( LoggerManager.ROLE );
}
catch ( ContextException ce )
{
@@ -788,7 +852,7 @@
assumeOwnership( logManager );
- m_childContext.put( LoggerManager.ROLE, logManager );
+ m_loggerManager = logManager;
}
// Since we now have a LoggerManager, we can update the this.logger field
@@ -798,9 +862,11 @@
{
getLogger().debug( "Switching to default Logger provided by
LoggerManager." );
- final LoggerManager loggerManager = (LoggerManager) m_childContext.get(
LoggerManager.ROLE );
- m_logger = loggerManager.getDefaultLogger();
+ m_logger = m_loggerManager.getDefaultLogger();
}
+
+ // pass our own logger to the ContainerManager
+ m_containerManagerContext.put( LOGGER, m_logger );
}
/**
@@ -819,7 +885,7 @@
{
// Try copying an already existing instrument manager from the override
context.
- m_rootContext.get( InstrumentManager.ROLE );
+ m_instrumentManager = (InstrumentManager) m_rootContext.get(
InstrumentManager.ROLE );
}
catch ( ContextException ce )
{
@@ -832,11 +898,8 @@
instrumentConfig = EMPTY_CONFIG;
}
- // Get the context Logger Manager
- final LoggerManager loggerManager = (LoggerManager) m_childContext.get(
LoggerManager.ROLE );
-
// Get the logger for the instrument manager
- final Logger imLogger = loggerManager.getLoggerForCategory(
+ final Logger imLogger = m_loggerManager.getLoggerForCategory(
instrumentConfig.getAttribute( "logger", "system.instrument" ) );
// Set up the Instrument Manager
@@ -847,7 +910,7 @@
assumeOwnership( instrumentManager );
- m_childContext.put( InstrumentManager.ROLE, instrumentManager );
+ m_instrumentManager = instrumentManager;
}
}
diff -ru
avalon-excalibur.0/fortress/src/test/org/apache/avalon/fortress/util/test/ContextManagerTestCase.java
avalon-excalibur/fortress/src/test/org/apache/avalon/fortress/util/test/ContextManagerTestCase.java
---
avalon-excalibur.0/fortress/src/test/org/apache/avalon/fortress/util/test/ContextManagerTestCase.java
2003-05-15 18:19:56.000000000 +0400
+++
avalon-excalibur/fortress/src/test/org/apache/avalon/fortress/util/test/ContextManagerTestCase.java
2003-05-28 14:47:38.000000000 +0400
@@ -50,10 +50,13 @@
package org.apache.avalon.fortress.util.test;
import junit.framework.TestCase;
+import org.apache.avalon.fortress.ContainerManagerConstants;
import org.apache.avalon.fortress.util.ContextManager;
import org.apache.avalon.fortress.util.FortressConfig;
import org.apache.avalon.framework.logger.NullLogger;
import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.service.ServiceManager;
import org.apache.excalibur.instrument.manager.DefaultInstrumentManager;
import org.apache.excalibur.instrument.InstrumentManager;
@@ -63,7 +66,7 @@
* @author <a href="bloritsch.at.apache.org">Berin Loritsch</a>
* @version CVS $ Revision: 1.1 $
*/
-public class ContextManagerTestCase extends TestCase
+public class ContextManagerTestCase extends TestCase implements
ContainerManagerConstants
{
private ContextManager m_manager;
private InstrumentManager m_instrManager;
@@ -91,9 +94,14 @@
public void testContextManager() throws Exception
{
assertNotNull( m_manager.getChildContext() );
- assertNotNull( m_manager.getContainerManagerContext() );
- assertNotNull(
m_manager.getContainerManagerContext().get(InstrumentManager.ROLE));
- assertSame( m_instrManager, m_manager.getContainerManagerContext().get(
InstrumentManager.ROLE ) );
+ final Context managerContext = m_manager.getContainerManagerContext();
+ assertNotNull( managerContext );
+ final ServiceManager serviceManager = (ServiceManager)
managerContext.get(SERVICE_MANAGER);
+ assertNotNull( serviceManager );
+ final InstrumentManager instrumentManager =
+ (InstrumentManager) serviceManager.lookup( InstrumentManager.ROLE );
+ assertNotNull( instrumentManager);
+ assertSame( m_instrManager, instrumentManager );
}
public void tearDown()
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]