carnold 2005/07/18 09:19:26
Modified: . build.properties.sample
src/java/org/apache/log4j Level.java
tests/src/java/org/apache/log4j CoreTestSuite.java
tests/src/java/org/apache/log4j/spi LoggingEventTest.java
Added: tests/src/java/org/apache/log4j LevelTest.java
tests/src/java/org/apache/log4j/util
SerializationTestHelper.java
tests/witness/serialization info.bin
Log:
Bug 26433: Level serialization
Revision Changes Path
1.27 +1 -1 logging-log4j/build.properties.sample
Index: build.properties.sample
===================================================================
RCS file: /home/cvs/logging-log4j/build.properties.sample,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- build.properties.sample 22 May 2005 07:32:17 -0000 1.26
+++ build.properties.sample 18 Jul 2005 16:16:52 -0000 1.27
@@ -29,7 +29,7 @@
servlet-api.jar=${lib.home.dir}/jakarta-tomcat-5.5.9/common/lib/servlet-api.jar
# SLF4J api
-slf4j-api.jar=${lib.home.dir}/slf4j-1.0-beta3/slf4j-nop.jar
+slf4j-api.jar=${lib.home.dir}/slf4j-1.0-beta4/slf4j-nop.jar
# The templates for the creation of the web-pages are inherited
# from the parent project.
1.16 +65 -4 logging-log4j/src/java/org/apache/log4j/Level.java
Index: Level.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/Level.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- Level.java 1 Dec 2004 07:58:08 -0000 1.15
+++ Level.java 18 Jul 2005 16:17:08 -0000 1.16
@@ -17,6 +17,11 @@
// Contributors: Kitching Simon <[EMAIL PROTECTED]>
// Nicholas Wolff
package org.apache.log4j;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
/**
@@ -31,7 +36,7 @@
@author Ceki Gülcü
@author Yoav Shapira
*/
-public class Level {
+public class Level implements Serializable {
/**
* OFF level integer value.
*/
@@ -124,17 +129,23 @@
/**
* The integer value of this Level instance.
*/
- int level;
+ transient int level;
/**
* The label of this Level instance.
*/
- String levelStr;
+ transient String levelStr;
/**
* The UNIX SysLog equivalent value of this Level instance.
*/
- int syslogEquivalent;
+ transient int syslogEquivalent;
+
+ /**
+ * Serialization version id.
+ */
+ static final long serialVersionUID = 3491141966387921974L;
+
/**
* Instantiate a level object.
@@ -215,6 +226,8 @@
*
* <p>You should think twice before overriding the default
* implementation of <code>isGreaterOrEqual</code> method.</p>
+ * @param r other level, may not be null.
+ * @return true if this level is equal or higher to other level.
*/
public boolean isGreaterOrEqual(Level r) {
return level >= r.level;
@@ -245,6 +258,7 @@
/**
* Returns the integer representation of this level.
+ * @return integer representation of level.
*/
public final int toInt() {
return level;
@@ -331,6 +345,53 @@
return defaultLevel;
}
+
+ /**
+ * Custom deserialization of Level.
+ * @param s serialization stream.
+ * @throws IOException if IO exception.
+ * @throws ClassNotFoundException if class not found.
+ */
+ private void readObject(final ObjectInputStream s) throws IOException,
ClassNotFoundException {
+ s.defaultReadObject();
+ level = s.readInt();
+ syslogEquivalent = s.readInt();
+ levelStr = s.readUTF();
+ if (levelStr == null) {
+ levelStr = "";
+ }
+ }
+
+ /**
+ * Serialize level.
+ * @param s serialization stream.
+ * @throws IOException if exception during serialization.
+ */
+ private void writeObject(final ObjectOutputStream s) throws IOException {
+ s.defaultWriteObject();
+ s.writeInt(level);
+ s.writeInt(syslogEquivalent);
+ s.writeUTF(levelStr);
+ }
+
+ /**
+ * Resolved deserialized level to one of the stock instances.
+ * May be overriden in classes derived from Level.
+ * @return resolved object.
+ * @throws ObjectStreamException if exception during resolution.
+ */
+ private Object readResolve() throws ObjectStreamException {
+ //
+ // if the deserizalized object is exactly an instance of Level
+ //
+ if (getClass() == Level.class) {
+ return toLevel(level);
+ }
+ //
+ // extension of Level can't substitute stock item
+ //
+ return this;
+ }
}
// End of class: Level.java
1.5 +1 -0
logging-log4j/tests/src/java/org/apache/log4j/CoreTestSuite.java
Index: CoreTestSuite.java
===================================================================
RCS file:
/home/cvs/logging-log4j/tests/src/java/org/apache/log4j/CoreTestSuite.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- CoreTestSuite.java 2 Jun 2005 05:48:57 -0000 1.4
+++ CoreTestSuite.java 18 Jul 2005 16:17:35 -0000 1.5
@@ -38,6 +38,7 @@
s.addTestSuite(org.apache.log4j.pattern.PatternParserTest.class);
s.addTestSuite(org.apache.log4j.rolling.helper.FileNamePatternTestCase.class);
s.addTestSuite(org.apache.log4j.pattern.FormattingInfoTest.class);
+ s.addTestSuite(org.apache.log4j.LevelTest.class);
return s;
}
}
1.1
logging-log4j/tests/src/java/org/apache/log4j/LevelTest.java
Index: LevelTest.java
===================================================================
/*
* Copyright 1999,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j;
import junit.framework.TestCase;
import org.apache.log4j.util.SerializationTestHelper;
/**
* Tests of Level.
*
* @author Curt Arnold
* @since 1.3
*/
public class LevelTest extends TestCase {
/**
* Constructs new instance of test.
* @param name test name.
*/
public LevelTest(final String name) {
super(name);
}
/**
* Serialize Level.INFO and check against witness.
* @throws Exception if exception during test.
*
*/
public void testSerializeINFO() throws Exception {
int[] skip = new int[] { };
SerializationTestHelper.assertSerializationEquals(
"witness/serialization/info.bin", Level.INFO, skip, Integer.MAX_VALUE);
}
/**
* Deserialize witness and see if resolved to Level.INFO.
* @throws Exception if exception during test.
*/
public void testDeserializeINFO() throws Exception {
Object obj =
SerializationTestHelper.deserializeStream(
"witness/serialization/info.bin");
assertTrue(obj instanceof Level);
assertTrue(obj == Level.INFO);
}
/**
* Tests that a custom level can be serialized and deserialized
* and is not resolved to a stock level.
*
* @throws Exception if exception during test.
*/
public void testCustomLevelSerialization() throws Exception {
CustomLevel custom = new CustomLevel();
Object obj = SerializationTestHelper.serializeClone(custom);
assertTrue(obj instanceof CustomLevel);
CustomLevel clone = (CustomLevel) obj;
assertEquals(Level.INFO.level, clone.level);
assertEquals(Level.INFO.levelStr, clone.levelStr);
assertEquals(Level.INFO.syslogEquivalent, clone.syslogEquivalent);
}
/**
* Custom level to check that custom levels are
* serializable, but not resolved to a plain Level.
*/
private static class CustomLevel extends Level {
/**
* Create an instance of CustomLevel.
*/
public CustomLevel() {
super(
Level.INFO.level, Level.INFO.levelStr, Level.INFO.syslogEquivalent);
}
}
}
1.5 +151 -185
logging-log4j/tests/src/java/org/apache/log4j/spi/LoggingEventTest.java
Index: LoggingEventTest.java
===================================================================
RCS file:
/home/cvs/logging-log4j/tests/src/java/org/apache/log4j/spi/LoggingEventTest.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- LoggingEventTest.java 25 May 2005 05:17:42 -0000 1.4
+++ LoggingEventTest.java 18 Jul 2005 16:18:21 -0000 1.5
@@ -17,13 +17,14 @@
package org.apache.log4j.spi;
import junit.framework.TestCase;
+
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
import org.apache.log4j.NDC;
import org.apache.log4j.spi.location.LocationInfo;
+import org.apache.log4j.util.SerializationTestHelper;
-import java.io.*;
/**
* Tests LoggingEvent.
@@ -32,188 +33,153 @@
* @since 1.3
*/
public class LoggingEventTest extends TestCase {
-
- /**
- * Create LoggingEventTest.
- *
- * @param name test name.
- */
- public LoggingEventTest(final String name) {
- super(name);
- }
-
-
- /**
- * Serialize a simple logging event and check it against
- * a witness.
- *
- */
- public void testSerializationSimple() throws Exception {
- Logger root = Logger.getRootLogger();
- LoggingEvent event = new LoggingEvent(root.getClass().getName(),
- root, Level.INFO, "Hello, world.", null);
- event.prepareForDeferredProcessing();
- int[] skip = new int[] { 358, 359, 360, 361, 362 };
- assertSerializationEquals("witness/serialization/simple.bin", event,
skip, Integer.MAX_VALUE);
- }
-
- /**
- * Serialize a logging event with an exception and check it against
- * a witness.
- *
- */
- public void testSerializationWithException() throws Exception {
- Logger root = Logger.getRootLogger();
- Exception ex = new Exception("Don't panic");
- LoggingEvent event = new LoggingEvent(root.getClass().getName(),
- root, Level.INFO, "Hello, world.", ex);
- event.prepareForDeferredProcessing();
- int[] skip = new int[] { 358, 359, 360, 361, 362, 600, 735, 1511};
- assertSerializationEquals("witness/serialization/exception.bin",
event, skip, 1089);
- }
-
- /**
- * Serialize a logging event with an exception and check it against
- * a witness.
- *
- */
- public void testSerializationWithLocation() throws Exception {
- Logger root = Logger.getRootLogger();
- LoggingEvent event = new LoggingEvent(root.getClass().getName(),
- root, Level.INFO, "Hello, world.", null);
- LocationInfo info = event.getLocationInformation();
- event.prepareForDeferredProcessing();
- int[] skip = new int[] { 354, 355, 356, 357, 358, 359, 360, 361, 362 };
- assertSerializationEquals("witness/serialization/location.bin", event,
skip, Integer.MAX_VALUE);
- }
-
- /**
- * Serialize a logging event with ndc.
- *
- */
- public void testSerializationNDC() throws Exception {
- Logger root = Logger.getRootLogger();
- NDC.push("ndc test");
- LoggingEvent event = new LoggingEvent(root.getClass().getName(),
- root, Level.INFO, "Hello, world.", null);
- event.prepareForDeferredProcessing();
- int[] skip = new int[] { 354, 355, 356, 357, 358, 359, 360, 361, 362 };
- assertSerializationEquals("witness/serialization/ndc.bin", event,
skip, Integer.MAX_VALUE);
- }
-
- /**
- * Serialize a logging event with mdc.
- *
- */
- public void testSerializationMDC() throws Exception {
- Logger root = Logger.getRootLogger();
- MDC.put("mdckey", "mdcvalue");
- LoggingEvent event = new LoggingEvent(root.getClass().getName(),
- root, Level.INFO, "Hello, world.", null);
- event.prepareForDeferredProcessing();
- int[] skip = new int[] { 354, 355, 356, 357, 358, 359, 360, 361, 362 };
- assertSerializationEquals("witness/serialization/mdc.bin", event,
skip, Integer.MAX_VALUE);
- }
-
-
- /**
- * Deserialize a simple logging event.
- *
- */
- public void testDeserializationSimple() throws Exception {
- Object obj = deserializeStream("witness/serialization/simple.bin");
- assertTrue(obj instanceof LoggingEvent);
- LoggingEvent event = (LoggingEvent) obj;
- assertEquals("Hello, world.", event.getMessage());
- assertEquals(Level.INFO, event.getLevel());
- }
-
- /**
- * Deserialize a logging event with an exception.
- *
- */
- public void testDeserializationWithException() throws Exception {
- Object obj =
deserializeStream("witness/serialization/exception.bin");
- assertTrue(obj instanceof LoggingEvent);
- LoggingEvent event = (LoggingEvent) obj;
- assertEquals("Hello, world.", event.getMessage());
- assertEquals(Level.INFO, event.getLevel());
- }
-
- /**
- * Deserialize a logging event with an exception.
- *
- */
- public void testDeserializationWithLocation() throws Exception {
- Object obj = deserializeStream("witness/serialization/location.bin");
- assertTrue(obj instanceof LoggingEvent);
- LoggingEvent event = (LoggingEvent) obj;
- assertEquals("Hello, world.", event.getMessage());
- assertEquals(Level.INFO, event.getLevel());
- }
-
-
-
- private static Object deserializeStream(final String witness)
- throws Exception {
- FileInputStream fileIs = new FileInputStream(witness);
- ObjectInputStream objIs = new ObjectInputStream(fileIs);
- return objIs.readObject();
- }
-
-
-
- private static void assertSerializationEquals(final String witness,
- final LoggingEvent event,
- final int[] skip,
- final int endCompare)
throws Exception {
-
- ByteArrayOutputStream memOut = new ByteArrayOutputStream();
- ObjectOutputStream objOut = new ObjectOutputStream(memOut);
- objOut.writeObject(event);
- objOut.close();
-
- assertStreamEquals(witness,
- memOut.toByteArray(),
- skip, endCompare);
-
- }
-
- private static void assertStreamEquals(final String witness,
- final byte[] actual,
- final int[] skip,
- final int endCompare)
- throws IOException {
- File witnessFile = new File(witness);
- if (witnessFile.exists()) {
- int skipIndex = 0;
- byte[] expected = new byte[actual.length];
- FileInputStream is = new FileInputStream(witnessFile);
- int bytesRead = is.read(expected);
- is.close();
- assertEquals(bytesRead, actual.length);
- int endScan = actual.length;
- if (endScan > endCompare) {
- endScan = endCompare;
- }
- for (int i = 0; i < endScan; i++) {
- if (skipIndex < skip.length && skip[skipIndex] == i) {
- skipIndex++;
- } else {
- if (expected[i] != actual[i]) {
- assertEquals("Difference at offset " + i,
expected[i], actual[i]);
- }
- }
- }
-
- } else {
- //
- // if the file doesn't exist then
- // assume that we are setting up and need to write it
- FileOutputStream os = new FileOutputStream(witnessFile);
- os.write(actual);
- os.close();
- fail("Writing witness file " + witness);
- }
- }
+ /**
+ * Create LoggingEventTest.
+ *
+ * @param name test name.
+ */
+ public LoggingEventTest(final String name) {
+ super(name);
+ }
+
+ /**
+ * Serialize a simple logging event and check it against
+ * a witness.
+ * @throws Exception if exception during test.
+ */
+ public void testSerializationSimple() throws Exception {
+ Logger root = Logger.getRootLogger();
+ LoggingEvent event =
+ new LoggingEvent(
+ root.getClass().getName(), root, Level.INFO, "Hello, world.", null);
+ event.prepareForDeferredProcessing();
+
+ int[] skip = new int[] { 358, 359, 360, 361, 362 };
+ SerializationTestHelper.assertSerializationEquals(
+ "witness/serialization/simple.bin", event, skip, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Serialize a logging event with an exception and check it against
+ * a witness.
+ * @throws Exception if exception during test.
+ *
+ */
+ public void testSerializationWithException() throws Exception {
+ Logger root = Logger.getRootLogger();
+ Exception ex = new Exception("Don't panic");
+ LoggingEvent event =
+ new LoggingEvent(
+ root.getClass().getName(), root, Level.INFO, "Hello, world.", ex);
+ event.prepareForDeferredProcessing();
+
+ int[] skip = new int[] { 358, 359, 360, 361, 362, 600, 734, 735, 1511 };
+ SerializationTestHelper.assertSerializationEquals(
+ "witness/serialization/exception.bin", event, skip, 1089);
+ }
+
+ /**
+ * Serialize a logging event with an exception and check it against
+ * a witness.
+ * @throws Exception if exception during test.
+ *
+ */
+ public void testSerializationWithLocation() throws Exception {
+ Logger root = Logger.getRootLogger();
+ LoggingEvent event =
+ new LoggingEvent(
+ root.getClass().getName(), root, Level.INFO, "Hello, world.", null);
+ LocationInfo info = event.getLocationInformation();
+ event.prepareForDeferredProcessing();
+
+ int[] skip = new int[] { 354, 355, 356, 357, 358, 359, 360, 361, 362 };
+ SerializationTestHelper.assertSerializationEquals(
+ "witness/serialization/location.bin", event, skip, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Serialize a logging event with ndc.
+ * @throws Exception if exception during test.
+ *
+ */
+ public void testSerializationNDC() throws Exception {
+ Logger root = Logger.getRootLogger();
+ NDC.push("ndc test");
+
+ LoggingEvent event =
+ new LoggingEvent(
+ root.getClass().getName(), root, Level.INFO, "Hello, world.", null);
+ event.prepareForDeferredProcessing();
+
+ int[] skip = new int[] { 354, 355, 356, 357, 358, 359, 360, 361, 362 };
+ SerializationTestHelper.assertSerializationEquals(
+ "witness/serialization/ndc.bin", event, skip, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Serialize a logging event with mdc.
+ * @throws Exception if exception during test.
+ *
+ */
+ public void testSerializationMDC() throws Exception {
+ Logger root = Logger.getRootLogger();
+ MDC.put("mdckey", "mdcvalue");
+
+ LoggingEvent event =
+ new LoggingEvent(
+ root.getClass().getName(), root, Level.INFO, "Hello, world.", null);
+ event.prepareForDeferredProcessing();
+
+ int[] skip = new int[] { 354, 355, 356, 357, 358, 359, 360, 361, 362 };
+ SerializationTestHelper.assertSerializationEquals(
+ "witness/serialization/mdc.bin", event, skip, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Deserialize a simple logging event.
+ * @throws Exception if exception during test.
+ *
+ */
+ public void testDeserializationSimple() throws Exception {
+ Object obj =
+ SerializationTestHelper.deserializeStream(
+ "witness/serialization/simple.bin");
+ assertTrue(obj instanceof LoggingEvent);
+
+ LoggingEvent event = (LoggingEvent) obj;
+ assertEquals("Hello, world.", event.getMessage());
+ assertEquals(Level.INFO, event.getLevel());
+ }
+
+ /**
+ * Deserialize a logging event with an exception.
+ * @throws Exception if exception during test.
+ *
+ */
+ public void testDeserializationWithException() throws Exception {
+ Object obj =
+ SerializationTestHelper.deserializeStream(
+ "witness/serialization/exception.bin");
+ assertTrue(obj instanceof LoggingEvent);
+
+ LoggingEvent event = (LoggingEvent) obj;
+ assertEquals("Hello, world.", event.getMessage());
+ assertEquals(Level.INFO, event.getLevel());
+ }
+
+ /**
+ * Deserialize a logging event with an exception.
+ * @throws Exception if exception during test.
+ *
+ */
+ public void testDeserializationWithLocation() throws Exception {
+ Object obj =
+ SerializationTestHelper.deserializeStream(
+ "witness/serialization/location.bin");
+ assertTrue(obj instanceof LoggingEvent);
+
+ LoggingEvent event = (LoggingEvent) obj;
+ assertEquals("Hello, world.", event.getMessage());
+ assertEquals(Level.INFO, event.getLevel());
+ }
}
1.1
logging-log4j/tests/src/java/org/apache/log4j/util/SerializationTestHelper.java
Index: SerializationTestHelper.java
===================================================================
/*
* Copyright 1999,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.util;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* Utiities for serialization tests.
*
* @author Curt Arnold
*/
public class SerializationTestHelper {
/**
* Private constructor.
*/
private SerializationTestHelper() {
}
/**
* Creates a clone by serializing object and
* deserializing byte stream.
* @param obj object to serialize and deserialize.
* @return clone
* @throws IOException on IO error.
* @throws ClassNotFoundException if class not found.
*/
public static Object serializeClone(final Object obj)
throws IOException, ClassNotFoundException {
ByteArrayOutputStream memOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(memOut);
objOut.writeObject(obj);
objOut.close();
ByteArrayInputStream src = new ByteArrayInputStream(memOut.toByteArray());
ObjectInputStream objIs = new ObjectInputStream(src);
return objIs.readObject();
}
/**
* Deserializes a specified file.
* @param witness serialization file, may not be null.
* @return deserialized object.
* @throws Exception thrown on IO or deserialization exception.
*/
public static Object deserializeStream(final String witness)
throws Exception {
FileInputStream fileIs = new FileInputStream(witness);
ObjectInputStream objIs = new ObjectInputStream(fileIs);
return objIs.readObject();
}
/**
* Checks the serialization of an object against an file
* containing the expected serialization.
*
* @param witness name of file containing expected serialization.
* @param obj object to be serialized.
* @param skip positions in serialized stream that should not be compared.
* @param endCompare position to stop comparison.
* @throws Exception thrown on IO or serialization exception.
*/
public static void assertSerializationEquals(
final String witness, final Object obj, final int[] skip,
final int endCompare) throws Exception {
ByteArrayOutputStream memOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(memOut);
objOut.writeObject(obj);
objOut.close();
assertStreamEquals(witness, memOut.toByteArray(), skip, endCompare);
}
/**
* Asserts the serialized form of an object.
* @param witness file name of expected serialization.
* @param actual byte array of actual serialization.
* @param skip positions to skip comparison.
* @param endCompare position to stop comparison.
* @throws IOException thrown on IO or serialization exception.
*/
public static void assertStreamEquals(
final String witness, final byte[] actual, final int[] skip,
final int endCompare) throws IOException {
File witnessFile = new File(witness);
if (witnessFile.exists()) {
int skipIndex = 0;
byte[] expected = new byte[actual.length];
FileInputStream is = new FileInputStream(witnessFile);
int bytesRead = is.read(expected);
is.close();
TestCase.assertEquals(bytesRead, actual.length);
int endScan = actual.length;
if (endScan > endCompare) {
endScan = endCompare;
}
for (int i = 0; i < endScan; i++) {
if ((skipIndex < skip.length) && (skip[skipIndex] == i)) {
skipIndex++;
} else {
if (expected[i] != actual[i]) {
TestCase.assertEquals(
"Difference at offset " + i, expected[i], actual[i]);
}
}
}
} else {
//
// if the file doesn't exist then
// assume that we are setting up and need to write it
FileOutputStream os = new FileOutputStream(witnessFile);
os.write(actual);
os.close();
TestCase.fail("Writing witness file " + witness);
}
}
}
1.1 logging-log4j/tests/witness/serialization/info.bin
<<Binary file>>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]