Restore files
diff --git a/log4j-server/pom.xml b/log4j-server/pom.xml
new file mode 100644
index 0000000..5a78828
--- /dev/null
+++ b/log4j-server/pom.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>log4j-tools</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+    <relativePath>../</relativePath>
+  </parent>
+  <artifactId>log4j-server</artifactId>
+  <packaging>jar</packaging>
+  <name>Apache Log4j Server components</name>
+  <description>The Apache Log4j server components</description>
+  <properties>
+    <log4jParentDir>${basedir}/..</log4jParentDir>
+    <projectDir>/log4j-server</projectDir>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-jms</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-layout-jackson-json</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-layout-jackson-xml</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <!-- Used for JMS server (needs an implementation of course) -->
+    <dependency>
+      <groupId>org.jboss.spec.javax.jms</groupId>
+      <artifactId>jboss-jms-api_1.1_spec</artifactId>
+      <scope>provided</scope>
+      <optional>true</optional>
+    </dependency>
+    <!-- Required for JSON support -->
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <!-- Required for XML support -->
+    <dependency>
+      <groupId>com.fasterxml.jackson.dataformat</groupId>
+      <artifactId>jackson-dataformat-xml</artifactId>
+    </dependency>
+    <!-- POM for jackson-dataformat-xml 2.8.3 depends on woodstox-core 5.0.2 -->
+    <dependency>
+      <groupId>com.fasterxml.woodstox</groupId>
+      <artifactId>woodstox-core</artifactId>
+      <version>5.0.2</version>
+    </dependency>
+
+    <!-- TEST DEPENDENCIES -->
+
+    <!-- Pull in useful test classes from API -->
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.activemq</groupId>
+      <artifactId>activemq-broker</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <!-- Include the standard NOTICE and LICENSE -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>process</goal>
+            </goals>
+            <configuration>
+              <skip>false</skip>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Export-Package>org.apache.logging.log4j.core.net.*</Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-changes-plugin</artifactId>
+        <version>${changes.plugin.version}</version>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>changes-report</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+        <configuration>
+          <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate>
+          <useJql>true</useJql>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>${checkstyle.plugin.version}</version>
+        <configuration>
+          <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> -->
+          <configLocation>${log4jParentDir}/checkstyle.xml</configLocation>
+          <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation>
+          <enableRulesSummary>false</enableRulesSummary>
+          <propertyExpansion>basedir=${basedir}</propertyExpansion>
+          <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>${javadoc.plugin.version}</version>
+        <configuration>
+          <bottom><![CDATA[<p align="center">Copyright &#169; {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
+            Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
+            and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
+          <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating
+               project -->
+          <detectOfflineLinks>false</detectOfflineLinks>
+          <linksource>true</linksource>
+        </configuration>
+        <reportSets>
+          <reportSet>
+            <id>non-aggregate</id>
+            <reports>
+              <report>javadoc</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <version>${findbugs.plugin.version}</version>
+        <configuration>
+          <fork>true</fork>
+          <jvmArgs>-Duser.language=en</jvmArgs>
+          <threshold>Normal</threshold>
+          <effort>Default</effort>
+          <excludeFilterFile>${log4jParentDir}/findbugs-exclude-filter.xml</excludeFilterFile>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+        <version>${jxr.plugin.version}</version>
+        <reportSets>
+          <reportSet>
+            <id>non-aggregate</id>
+            <reports>
+              <report>jxr</report>
+            </reports>
+          </reportSet>
+          <reportSet>
+            <id>aggregate</id>
+            <reports>
+              <report>aggregate</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-pmd-plugin</artifactId>
+        <version>${pmd.plugin.version}</version>
+        <configuration>
+          <targetJdk>${maven.compiler.target}</targetJdk>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
+
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractLogEventBridge.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractLogEventBridge.java
new file mode 100644
index 0000000..5e368cb
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractLogEventBridge.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.status.StatusLogger;
+
+/**
+ * Abstract class for implementations of {@link LogEventBridge}.
+ * 
+ * @param <T>
+ *            The kind of input stream read
+ */
+public abstract class AbstractLogEventBridge<T extends InputStream> implements LogEventBridge<T> {
+
+    protected static final int END = -1;
+
+    protected static final Logger logger = StatusLogger.getLogger();
+
+    // The default is to return the same object as given.
+    @SuppressWarnings("unchecked")
+    @Override
+    public T wrapStream(final InputStream inputStream) throws IOException {
+        return (T) inputStream;
+    }
+
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractSocketServer.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractSocketServer.java
new file mode 100644
index 0000000..2024b6b
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractSocketServer.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LogEventListener;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationSource;
+import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
+import org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory;
+import org.apache.logging.log4j.core.tools.BasicCommandLineArguments;
+import org.apache.logging.log4j.core.tools.picocli.CommandLine.Option;
+import org.apache.logging.log4j.core.util.Log4jThread;
+import org.apache.logging.log4j.util.Strings;
+
+/**
+ * Abstract socket server for TCP and UDP implementations.
+ *
+ * @param <T>
+ *            The kind of input stream read
+ *
+ *            TODO Make a LifeCycle
+ */
+public abstract class AbstractSocketServer<T extends InputStream> extends LogEventListener implements Runnable {
+
+    protected static class CommandLineArguments extends BasicCommandLineArguments {
+
+        @Option(names = { "--config", "-c" }, description = "Log4j configuration file location (path or URL).")
+        private String configLocation;
+
+        @Option(names = { "--interactive", "-i" }, description = "Accepts commands on standard input (\"exit\" is the only command).")
+        private boolean interactive;
+
+        @Option(names = { "--port", "-p" }, description = "The server port number, or 0 to automatically allocate a port number.")
+        private int port;
+
+        @Option(names = { "--localbindaddress", "-a" }, description = "Server socket local bind address.")
+        private InetAddress localBindAddress;
+
+        @Option(names = {"--classes", "-C"}, description = "Additional classes to allow deserialization")
+        private List<String> allowedClasses;
+
+        String getConfigLocation() {
+            return configLocation;
+        }
+
+        int getPort() {
+            return port;
+        }
+
+        protected boolean isInteractive() {
+            return interactive;
+        }
+
+        void setConfigLocation(final String configLocation) {
+            this.configLocation = configLocation;
+        }
+
+        void setInteractive(final boolean interactive) {
+            this.interactive = interactive;
+        }
+
+        void setPort(final int port) {
+            this.port = port;
+        }
+
+        InetAddress getLocalBindAddress() {
+            return localBindAddress;
+        }
+
+        void setLocalBindAddress(final InetAddress localBindAddress) {
+            this.localBindAddress = localBindAddress;
+        }
+
+        List<String> getAllowedClasses() {
+            return allowedClasses == null ? Collections.<String>emptyList() : allowedClasses;
+        }
+
+        void setAllowedClasses(final List<String> allowedClasses) {
+            this.allowedClasses = allowedClasses;
+        }
+    }
+
+    /**
+     * Factory that creates a Configuration for the server.
+     */
+    protected static class ServerConfigurationFactory extends XmlConfigurationFactory {
+
+        private final String path;
+
+        public ServerConfigurationFactory(final String path) {
+            this.path = path;
+        }
+
+        @Override
+        public Configuration getConfiguration(final LoggerContext loggerContext, final String name,
+                final URI configLocation) {
+            if (Strings.isNotEmpty(path)) {
+                File file = null;
+                ConfigurationSource source = null;
+                try {
+                    file = new File(path);
+                    final FileInputStream is = new FileInputStream(file);
+                    source = new ConfigurationSource(is, file);
+                } catch (final FileNotFoundException ignored) {
+                    // Ignore this error
+                }
+                if (source == null) {
+                    try {
+                        final URL url = new URL(path);
+                        source = new ConfigurationSource(url.openStream(), url);
+                    } catch (final IOException ignored) {
+                        // Ignore this error
+                    }
+                }
+
+                try {
+                    if (source != null) {
+                        return new XmlConfiguration(loggerContext, source);
+                    }
+                } catch (final Exception ignored) {
+                    // Ignore this error.
+                }
+                System.err.println("Unable to process configuration at " + path + ", using default.");
+            }
+            return super.getConfiguration(loggerContext, name, configLocation);
+        }
+    }
+
+    protected static final int MAX_PORT = 65534;
+
+    private volatile boolean active = true;
+
+    protected final LogEventBridge<T> logEventInput;
+
+    protected final Logger logger;
+
+    /**
+     * Creates a new socket server.
+     *
+     * @param port
+     *            listen to this port
+     * @param logEventInput
+     *            Use this input to read log events.
+     */
+    public AbstractSocketServer(final int port, final LogEventBridge<T> logEventInput) {
+        this.logger = LogManager.getLogger(this.getClass().getName() + '.' + port);
+        this.logEventInput = Objects.requireNonNull(logEventInput, "LogEventInput");
+    }
+
+    protected boolean isActive() {
+        return this.active;
+    }
+
+    protected void setActive(final boolean isActive) {
+        this.active = isActive;
+    }
+
+    /**
+     * Start this server in a new thread.
+     *
+     * @return the new thread that running this server.
+     */
+    public Thread startNewThread() {
+        final Thread thread = new Log4jThread(this);
+        thread.start();
+        return thread;
+    }
+
+    public abstract void shutdown() throws Exception;
+
+    public void awaitTermination(final Thread serverThread) throws Exception {
+        final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+        while (true) {
+            final String line = reader.readLine();
+            if (line == null
+                || line.equalsIgnoreCase("quit")
+                || line.equalsIgnoreCase("stop")
+                || line.equalsIgnoreCase("exit")) {
+                this.shutdown();
+                serverThread.join();
+                break;
+            }
+        }
+    }
+
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/InputStreamLogEventBridge.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/InputStreamLogEventBridge.java
new file mode 100644
index 0000000..6d66303
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/InputStreamLogEventBridge.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LogEventListener;
+import org.apache.logging.log4j.core.parser.ParseException;
+import org.apache.logging.log4j.core.parser.TextLogEventParser;
+import org.apache.logging.log4j.util.Strings;
+
+/**
+ * Reads and logs {@link LogEvent}s from an {@link InputStream}.
+ */
+public abstract class InputStreamLogEventBridge extends AbstractLogEventBridge<InputStream> {
+
+    private final int bufferSize;
+
+    private final Charset charset;
+
+    private final String eventEndMarker;
+    
+    private final TextLogEventParser parser;
+    
+    public InputStreamLogEventBridge(final TextLogEventParser parser, final int bufferSize, final Charset charset, final String eventEndMarker) {
+        this.bufferSize = bufferSize;
+        this.charset = charset;
+        this.eventEndMarker = eventEndMarker;
+        this.parser = parser;
+    }
+
+    abstract protected int[] getEventIndices(final String text, int beginIndex);
+
+    @Override
+    public void logEvents(final InputStream inputStream, final LogEventListener logEventListener)
+            throws IOException, ParseException {
+        String workingText = Strings.EMPTY;
+        try {
+            // Allocate buffer once
+            final byte[] buffer = new byte[bufferSize];
+            String textRemains = workingText = Strings.EMPTY;
+            while (true) {
+                // Process until the stream is EOF.
+                final int streamReadLength = inputStream.read(buffer);
+                if (streamReadLength == END) {
+                    // The input stream is EOF
+                    break;
+                }
+                final String text = workingText = textRemains + new String(buffer, 0, streamReadLength, charset);
+                int beginIndex = 0;
+                while (true) {
+                    // Extract and log all XML events in the buffer
+                    final int[] pair = getEventIndices(text, beginIndex);
+                    final int eventStartMarkerIndex = pair[0];
+                    if (eventStartMarkerIndex < 0) {
+                        // No more events or partial XML only in the buffer.
+                        // Save the unprocessed string part
+                        textRemains = text.substring(beginIndex);
+                        break;
+                    }
+                    final int eventEndMarkerIndex = pair[1];
+                    if (eventEndMarkerIndex > 0) {
+                        final int eventEndXmlIndex = eventEndMarkerIndex + eventEndMarker.length();
+                        final String textEvent = workingText = text.substring(eventStartMarkerIndex, eventEndXmlIndex);
+                        final LogEvent logEvent = unmarshal(textEvent);
+                        logEventListener.log(logEvent);
+                        beginIndex = eventEndXmlIndex;
+                    } else {
+                        // No more events or partial XML only in the buffer.
+                        // Save the unprocessed string part
+                        textRemains = text.substring(beginIndex);
+                        break;
+                    }
+                }
+            }
+        } catch (final IOException ex) {
+            logger.error(workingText, ex);
+        }
+    }
+
+    protected LogEvent unmarshal(final String jsonEvent) throws ParseException {
+        return this.parser.parseFrom(jsonEvent);
+    }
+
+    @Override
+    public String toString() {
+        return "InputStreamLogEventBridge [bufferSize=" + bufferSize + ", charset=" + charset + ", eventEndMarker="
+                + eventEndMarker + ", parser=" + parser + "]";
+    }
+
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/JmsServer.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/JmsServer.java
new file mode 100644
index 0000000..e46632c
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/JmsServer.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.ObjectMessage;
+
+import org.apache.logging.log4j.LoggingException;
+import org.apache.logging.log4j.core.AbstractLifeCycle;
+import org.apache.logging.log4j.core.LifeCycle2;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LogEventListener;
+import org.apache.logging.log4j.core.net.JndiManager;
+import org.apache.logging.log4j.jms.appender.JmsAppender;
+import org.apache.logging.log4j.jms.appender.JmsManager;
+
+/**
+ * LogEventListener server that receives LogEvents over a JMS {@link javax.jms.Destination}.
+ *
+ * @since 2.1
+ */
+public class JmsServer extends LogEventListener implements MessageListener, LifeCycle2 {
+
+    private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
+    private final JmsManager jmsManager;
+    private MessageConsumer messageConsumer;
+
+    public JmsServer(final String connectionFactoryBindingName, final String connectionFactoryName,
+            final String providerURL, final String destinationBindingName, final String username, final char[] password,
+            final Properties jndiProperties) {
+        final String managerName = JmsServer.class.getName() + '@' + JmsServer.class.hashCode();
+        final Properties jndiManager = JndiManager.createProperties(connectionFactoryBindingName, providerURL, null,
+                null, null, jndiProperties);
+        jmsManager = JmsManager.getJmsManager(managerName, jndiManager, connectionFactoryName, destinationBindingName,
+                username, password, false, JmsAppender.Builder.DEFAULT_RECONNECT_INTERVAL_MILLIS);
+    }
+
+    @Override
+    public State getState() {
+        return state.get();
+    }
+
+    @Override
+    public void onMessage(final Message message) {
+        try {
+            if (message instanceof ObjectMessage) {
+                final Object body = ((ObjectMessage) message).getObject();
+                if (body instanceof LogEvent) {
+                    log((LogEvent) body);
+                } else {
+                    LOGGER.warn("Expected ObjectMessage to contain LogEvent. Got type {} instead.", body.getClass());
+                }
+            } else {
+                LOGGER.warn("Received message of type {} and JMSType {} which cannot be handled.", message.getClass(),
+                        message.getJMSType());
+            }
+        } catch (final JMSException e) {
+            LOGGER.catching(e);
+        }
+    }
+
+    @Override
+    public void initialize() {
+    }
+
+    @Override
+    public void start() {
+        if (state.compareAndSet(State.INITIALIZED, State.STARTING)) {
+            try {
+                messageConsumer = jmsManager.createMessageConsumer();
+                messageConsumer.setMessageListener(this);
+            } catch (final JMSException e) {
+                throw new LoggingException(e);
+            }
+        }
+    }
+
+    @Override
+    public void stop() {
+        stop(AbstractLifeCycle.DEFAULT_STOP_TIMEOUT, AbstractLifeCycle.DEFAULT_STOP_TIMEUNIT);
+    }
+
+    @Override
+    public boolean stop(final long timeout, final TimeUnit timeUnit) {
+        boolean stopped = true;
+        try {
+            messageConsumer.close();
+        } catch (final JMSException e) {
+            LOGGER.debug("Exception closing {}", messageConsumer, e);
+            stopped = false;
+        }
+        return stopped && jmsManager.stop(timeout, timeUnit);
+    }
+
+    @Override
+    public boolean isStarted() {
+        return state.get() == State.STARTED;
+    }
+
+    @Override
+    public boolean isStopped() {
+        return state.get() == State.STOPPED;
+    }
+
+    /**
+     * Starts and runs this server until the user types "exit" into standard input.
+     *
+     * @throws IOException
+     */
+    public void commandLineLoop() throws IOException {
+        System.out.println("Type \"exit\" to quit.");
+        final BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in, Charset.defaultCharset()));
+        while (true) {
+            final String line = stdin.readLine();
+            if (line == null || line.equalsIgnoreCase("exit")) {
+                System.out.println("Exiting. Kill the application if it does not exit due to daemon threads.");
+                this.stop();
+                return;
+            }
+        }
+    }
+
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/JsonInputStreamLogEventBridge.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/JsonInputStreamLogEventBridge.java
new file mode 100644
index 0000000..8444c74
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/JsonInputStreamLogEventBridge.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.jackson.json.parser.JsonLogEventParser;
+import org.apache.logging.log4j.util.Chars;
+
+/**
+ * Reads and logs JSON {@link LogEvent}s from an {@link InputStream}..
+ */
+public class JsonInputStreamLogEventBridge extends InputStreamLogEventBridge {
+
+    private static final int[] END_PAIR = new int[] { END, END };
+    private static final char EVENT_END_MARKER = '}';
+    private static final char EVENT_START_MARKER = '{';
+    private static final char JSON_ESC = '\\';
+    private static final char JSON_STR_DELIM = Chars.DQUOTE;
+
+    public JsonInputStreamLogEventBridge() {
+        this(1024, Charset.defaultCharset());
+    }
+
+    public JsonInputStreamLogEventBridge(final int bufferSize, final Charset charset) {
+        super(new JsonLogEventParser(), bufferSize, charset,
+                String.valueOf(EVENT_END_MARKER));
+    }
+
+    @Override
+    protected int[] getEventIndices(final String text, final int beginIndex) {
+        // Scan the text for the end of the next JSON object.
+        final int start = text.indexOf(EVENT_START_MARKER, beginIndex);
+        if (start == END) {
+            return END_PAIR;
+        }
+        final char[] charArray = text.toCharArray();
+        int stack = 0;
+        boolean inStr = false;
+        boolean inEsc = false;
+        for (int i = start; i < charArray.length; i++) {
+            final char c = charArray[i];
+            if (inEsc) {
+            	// Skip this char and continue
+            	inEsc = false;
+            } else {
+                switch (c) {
+                case EVENT_START_MARKER:
+                    if (!inStr) {
+                        stack++;
+                    }
+                    break;
+                case EVENT_END_MARKER:
+                    if (!inStr) {
+                        stack--;
+                    }
+                    break;
+                case JSON_STR_DELIM:
+                    inStr = !inStr;
+                    break;
+                case JSON_ESC:
+                    inEsc = true;
+                    break;
+                }
+                if (stack == 0) {
+                    return new int[] { start, i };
+                }
+            }
+        }
+        return END_PAIR;
+    }
+
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/LogEventBridge.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/LogEventBridge.java
new file mode 100644
index 0000000..7c915fd
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/LogEventBridge.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LogEventListener;
+import org.apache.logging.log4j.core.parser.ParseException;
+
+/**
+ * Reads {@link LogEvent}s from the given input stream and logs them as they are discovered on the given logger.
+ * 
+ * <p>
+ * Should be stateless.
+ * </p>
+ * 
+ * @param <T>
+ *            The kind of {@link InputStream} to wrap and read.
+ */
+public interface LogEventBridge<T extends InputStream> {
+
+    /**
+     * Reads {@link LogEvent}s from the given input stream and logs them as they are discovered on the given logger.
+     * 
+     * @param inputStream
+     *            the input stream to read
+     * @param logEventListener
+     *            TODO
+     */
+    void logEvents(T inputStream, LogEventListener logEventListener) throws IOException, ParseException;
+
+    /**
+     * Wraps the given stream if needed.
+     * 
+     * @param inputStream
+     *            the stream to wrap
+     * @return the wrapped stream or the given stream.
+     */
+    T wrapStream(InputStream inputStream) throws IOException;
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/ObjectInputStreamLogEventBridge.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/ObjectInputStreamLogEventBridge.java
new file mode 100644
index 0000000..c5ab4eb
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/ObjectInputStreamLogEventBridge.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LogEventListener;
+import org.apache.logging.log4j.util.FilteredObjectInputStream;
+import org.apache.logging.log4j.core.layout.SerializedLayout;
+
+/**
+ * Reads and logs serialized {@link LogEvent} objects (created with {@link SerializedLayout}) from an {@link ObjectInputStream}.
+ *
+ * @deprecated Java Serialization has inherent security weaknesses, see https://www.owasp.org/index.php/Deserialization_of_untrusted_data .
+ * Therefore {@link SerializedLayout} is deprecated, and so is this class. We recommend using {@link JsonInputStreamLogEventBridge} instead.
+ */
+@Deprecated
+public class ObjectInputStreamLogEventBridge extends AbstractLogEventBridge<ObjectInputStream> {
+
+    private final List<String> allowedClasses;
+
+    public ObjectInputStreamLogEventBridge() {
+        this(Collections.<String>emptyList());
+    }
+
+    /**
+     * Constructs an ObjectInputStreamLogEventBridge with additional allowed classes to deserialize.
+     *
+     * @param allowedClasses class names to also allow for deserialization
+     * @since 2.8.2
+     */
+    public ObjectInputStreamLogEventBridge(final List<String> allowedClasses) {
+        this.allowedClasses = allowedClasses;
+    }
+
+    @Override
+    public void logEvents(final ObjectInputStream inputStream, final LogEventListener logEventListener)
+        throws IOException {
+        try {
+            logEventListener.log((LogEvent) inputStream.readObject());
+        } catch (final ClassNotFoundException e) {
+            throw new IOException(e);
+        }
+    }
+
+    @Override
+    public ObjectInputStream wrapStream(final InputStream inputStream) throws IOException {
+        return new FilteredObjectInputStream(inputStream, allowedClasses);
+    }
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/SecureTcpSocketServer.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/SecureTcpSocketServer.java
new file mode 100644
index 0000000..39f2afc
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/SecureTcpSocketServer.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
+
+/**
+ * Listens for events over a secure socket connection (SSL/TLS).
+ *
+ * @param <T>
+ *        The kind of input stream read
+ */
+public class SecureTcpSocketServer<T extends InputStream> extends TcpSocketServer<T> {
+
+    public static SecureTcpSocketServer<InputStream> createJsonServer(final int port, final SslConfiguration sslConfiguration) throws IOException {
+        return new SecureTcpSocketServer<>(port, new JsonInputStreamLogEventBridge(), sslConfiguration);
+    }
+
+    public SecureTcpSocketServer(final int port, final LogEventBridge<T> logEventInput,
+            final SslConfiguration sslConfig) throws IOException {
+        super(port, logEventInput, sslConfig.getSslServerSocketFactory().createServerSocket(port));
+    }
+
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
new file mode 100644
index 0000000..c3f5ae7
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
@@ -0,0 +1,341 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.OptionalDataException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.parser.ParseException;
+import org.apache.logging.log4j.core.util.Closer;
+import org.apache.logging.log4j.core.util.Log4jThread;
+import org.apache.logging.log4j.core.tools.picocli.CommandLine;
+import org.apache.logging.log4j.core.tools.picocli.CommandLine.Command;
+import org.apache.logging.log4j.core.tools.picocli.CommandLine.Option;
+import org.apache.logging.log4j.message.EntryMessage;
+
+/**
+ * Listens for Log4j events on a TCP server socket and passes them on to Log4j.
+ *
+ * @param <T>
+ *        The kind of input stream read
+ * @see #main(String[])
+ */
+public class TcpSocketServer<T extends InputStream> extends AbstractSocketServer<T> {
+
+    @Command(name = "TcpSocketServer")
+    protected static class CommandLineArguments extends AbstractSocketServer.CommandLineArguments {
+
+        @Option(names = { "--backlog", "-b" }, description = "Server socket backlog. Must be a positive integer.")
+        // Same default as ServerSocket
+        private int backlog = 50;
+
+        int getBacklog() {
+            return backlog;
+        }
+
+        void setBacklog(final int backlog) {
+            this.backlog = backlog;
+        }
+    }
+
+    /**
+     * Thread that processes the events.
+     */
+    private class SocketHandler extends Log4jThread {
+
+        private final T inputStream;
+        private final Socket socket;
+
+        private volatile boolean shutdown = false;
+
+        public SocketHandler(final Socket socket) throws IOException {
+            this.socket = socket;
+            this.inputStream = logEventInput.wrapStream(socket.getInputStream());
+        }
+
+        @Override
+        public void run() {
+            final EntryMessage entry = logger.traceEntry();
+            boolean closed = false;
+            try {
+                try {
+                    while (!shutdown) {
+                        logEventInput.logEvents(inputStream, TcpSocketServer.this);
+                    }
+                } catch (final EOFException e) {
+                    closed = true;
+                } catch (final OptionalDataException e) {
+                    logger.error("OptionalDataException eof=" + e.eof + " length=" + e.length, e);
+                } catch (final IOException e) {
+                    logger.error("IOException encountered while reading from socket", e);
+                } catch (ParseException e) {
+                    logger.error("ParseException encountered while reading from socket", e);
+                }
+                if (!closed) {
+                    Closer.closeSilently(inputStream);
+                }
+            } finally {
+                handlers.remove(Long.valueOf(getId()));
+            }
+            logger.traceExit(entry);
+        }
+
+        public void shutdown() {
+            this.shutdown = true;
+            if (socket != null) {
+                Closer.closeSilently(socket);
+            }
+            interrupt();
+        }
+    }
+
+    /**
+     * Creates a socket server that reads JSON log events.
+     *
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     */
+    public static TcpSocketServer<InputStream> createJsonSocketServer(final int port) throws IOException {
+        LOGGER.entry("createJsonSocketServer", port);
+        final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, new JsonInputStreamLogEventBridge());
+        return LOGGER.exit(socketServer);
+    }
+
+    /**
+     * Creates a socket server that reads JSON log events.
+     *
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @param backlog
+     *        The server socket backlog.
+     * @param localBindAddress
+     *        The local InetAddress the server will bind to
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     * @since 2.9
+     */
+    public static TcpSocketServer<InputStream> createJsonSocketServer(final int port, final int backlog,
+            final InetAddress localBindAddress) throws IOException {
+        LOGGER.entry("createJsonSocketServer", port, backlog, localBindAddress);
+        final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, backlog, localBindAddress,
+                new JsonInputStreamLogEventBridge());
+        return LOGGER.exit(socketServer);
+    }
+
+    /**
+     * Creates a socket server that reads XML log events.
+     *
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     */
+    public static TcpSocketServer<InputStream> createXmlSocketServer(final int port) throws IOException {
+        LOGGER.entry(port);
+        final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, new XmlInputStreamLogEventBridge());
+        return LOGGER.exit(socketServer);
+    }
+
+    /**
+     * Creates a socket server that reads XML log events.
+     *
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @param backlog
+     *        The server socket backlog.
+     * @param localBindAddress
+     *        The local InetAddress the server will bind to
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     * @since 2.9
+     */
+    public static TcpSocketServer<InputStream> createXmlSocketServer(final int port,
+        final int backlog, final InetAddress localBindAddress
+    ) throws IOException {
+        LOGGER.entry(port);
+        final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, backlog, localBindAddress,
+                new XmlInputStreamLogEventBridge());
+        return LOGGER.exit(socketServer);
+    }
+
+    /**
+     * Main startup for the server. Run with "--help" for to print command line help on the console.
+     *
+     * @param args
+     *        The command line arguments.
+     * @throws Exception
+     *         if an error occurs.
+     */
+    public static void main(final String[] args) throws Exception {
+        CommandLineArguments cla = CommandLine.populateCommand(new CommandLineArguments(), args);
+        if (cla.isHelp() || cla.backlog < 0 || cla.getPort() < 0) {
+            CommandLine.usage(cla, System.err);
+            return;
+        }
+        if (cla.getConfigLocation() != null) {
+            ConfigurationFactory.setConfigurationFactory(new ServerConfigurationFactory(cla.getConfigLocation()));
+        }
+        final TcpSocketServer<InputStream> socketServer = TcpSocketServer.createJsonSocketServer(
+                cla.getPort(), cla.getBacklog(), cla.getLocalBindAddress());
+        final Thread serverThread = socketServer.startNewThread();
+        if (cla.isInteractive()) {
+            socketServer.awaitTermination(serverThread);
+        }
+    }
+
+    private final ConcurrentMap<Long, SocketHandler> handlers = new ConcurrentHashMap<>();
+
+    private final ServerSocket serverSocket;
+
+    /**
+     * Constructor.
+     *
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @param backlog
+     *        The server socket backlog.
+     * @param localBindAddress
+     *        The local InetAddress the server will bind to
+     * @param logEventInput
+     *        the log even input
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     * @since 2.7
+     */
+    @SuppressWarnings("resource")
+    public TcpSocketServer(final int port, final int backlog, final InetAddress localBindAddress, final LogEventBridge<T> logEventInput) throws IOException {
+        this(port, logEventInput, new ServerSocket(port, backlog, localBindAddress));
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param port
+     *         The port number, or 0 to automatically allocate a port number.
+     * @param logEventInput
+     *        the log even input
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     */
+    @SuppressWarnings("resource")
+    public TcpSocketServer(final int port, final LogEventBridge<T> logEventInput) throws IOException {
+        this(port, logEventInput, new ServerSocket(port));
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param port
+     *        to listen.
+     * @param logEventInput
+     *        the log even input
+     * @param serverSocket
+     *        the socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     */
+    public TcpSocketServer(final int port, final LogEventBridge<T> logEventInput, final ServerSocket serverSocket)
+            throws IOException {
+        super(port, logEventInput);
+        this.serverSocket = serverSocket;
+    }
+
+    /**
+     * Accept incoming events and processes them.
+     */
+    @Override
+    public void run() {
+        final EntryMessage entry = logger.traceEntry();
+        while (isActive()) {
+            if (serverSocket.isClosed()) {
+                return;
+            }
+            try {
+                // Accept incoming connections.
+                logger.debug("Listening for a connection {}...", serverSocket);
+                @SuppressWarnings("resource") // clientSocket is closed during SocketHandler shutdown
+                final Socket clientSocket = serverSocket.accept();
+                logger.debug("Accepted connection on {}...", serverSocket);
+                logger.debug("Socket accepted: {}", clientSocket);
+                clientSocket.setSoLinger(true, 0);
+
+                // accept() will block until a client connects to the server.
+                // If execution reaches this point, then it means that a client
+                // socket has been accepted.
+
+                final SocketHandler handler = new SocketHandler(clientSocket);
+                handlers.put(Long.valueOf(handler.getId()), handler);
+                handler.start();
+            } catch (final IOException e) {
+                if (serverSocket.isClosed()) {
+                    // OK we're done.
+                    logger.traceExit(entry);
+                    return;
+                }
+                logger.error("Exception encountered on accept. Ignoring. Stack trace :", e);
+            }
+        }
+        for (final Map.Entry<Long, SocketHandler> handlerEntry : handlers.entrySet()) {
+            final SocketHandler handler = handlerEntry.getValue();
+            handler.shutdown();
+            try {
+                handler.join();
+            } catch (final InterruptedException ignored) {
+                // Ignore the exception
+            }
+        }
+        logger.traceExit(entry);
+    }
+
+    /**
+     * Shutdown the server.
+     *
+     * @throws IOException if the server socket could not be closed
+     */
+    @Override
+    public void shutdown() throws IOException {
+        final EntryMessage entry = logger.traceEntry();
+        setActive(false);
+        //Thread.currentThread().interrupt();
+        serverSocket.close();
+        logger.traceExit(entry);
+    }
+
+    @Override
+    public String toString() {
+        return "TcpSocketServer [serverSocket=" + serverSocket + ", handlers=" + handlers + ", logEventInput="
+                + logEventInput + "]";
+    }
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/UdpSocketServer.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/UdpSocketServer.java
new file mode 100644
index 0000000..6148ad8
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/UdpSocketServer.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.OptionalDataException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.util.List;
+
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.parser.ParseException;
+import org.apache.logging.log4j.core.tools.picocli.CommandLine;
+
+/**
+ * Listens for Log4j events on a datagram socket and passes them on to Log4j.
+ *
+ * @param <T>
+ *            The kind of input stream read
+ * @see #main(String[])
+ */
+public class UdpSocketServer<T extends InputStream> extends AbstractSocketServer<T> {
+
+    /**
+     * Creates a socket server that reads JSON log events.
+     *
+     * @param port
+     *            the port to listen
+     * @return a new a socket server
+     * @throws IOException
+     *             if an I/O error occurs when opening the socket.
+     */
+    public static UdpSocketServer<InputStream> createJsonSocketServer(final int port) throws IOException {
+        return new UdpSocketServer<>(port, new JsonInputStreamLogEventBridge());
+    }
+
+    /**
+     * Creates a socket server that reads XML log events.
+     *
+     * @param port
+     *            the port to listen
+     * @return a new a socket server
+     * @throws IOException
+     *             if an I/O error occurs when opening the socket.
+     */
+    public static UdpSocketServer<InputStream> createXmlSocketServer(final int port) throws IOException {
+        return new UdpSocketServer<>(port, new XmlInputStreamLogEventBridge());
+    }
+
+    /**
+     * Main startup for the server. Run with "--help" for to print command line help on the console.
+     *
+     * @param args
+     *            The command line arguments.
+     * @throws Exception
+     *             if an error occurs.
+     */
+    public static void main(final String[] args) throws Exception {
+        final CommandLineArguments cla = CommandLine.populateCommand(new CommandLineArguments(), args);
+        if (cla.isHelp() || cla.getPort() < 0) {
+            CommandLine.usage(cla, System.err);
+            return;
+        }
+        if (cla.getConfigLocation() != null) {
+            ConfigurationFactory.setConfigurationFactory(new ServerConfigurationFactory(cla.getConfigLocation()));
+        }
+        final UdpSocketServer<InputStream> socketServer = UdpSocketServer
+                .createJsonSocketServer(cla.getPort());
+        final Thread serverThread = socketServer.startNewThread();
+        if (cla.isInteractive()) {
+            socketServer.awaitTermination(serverThread);
+        }
+    }
+
+    private final DatagramSocket datagramSocket;
+
+    // max size so we only have to deal with one packet
+    private final int maxBufferSize = 1024 * 65 + 1024;
+
+    /**
+     * Constructor.
+     *
+     * @param port
+     *            to listen on.
+     * @param logEventInput
+     * @throws IOException
+     *             If an error occurs.
+     */
+    public UdpSocketServer(final int port, final LogEventBridge<T> logEventInput) throws IOException {
+        super(port, logEventInput);
+        this.datagramSocket = new DatagramSocket(port);
+    }
+
+    /**
+     * Accept incoming events and processes them.
+     */
+    @Override
+    public void run() {
+        while (isActive()) {
+            if (datagramSocket.isClosed()) {
+                // OK we're done.
+                return;
+            }
+            try {
+                final byte[] buf = new byte[maxBufferSize];
+                final DatagramPacket packet = new DatagramPacket(buf, buf.length);
+                datagramSocket.receive(packet);
+                final ByteArrayInputStream bais = new ByteArrayInputStream(packet.getData(), packet.getOffset(), packet.getLength());
+                logEventInput.logEvents(logEventInput.wrapStream(bais), this);
+            } catch (final OptionalDataException e) {
+                if (datagramSocket.isClosed()) {
+                    // OK we're done.
+                    return;
+                }
+                logger.error("OptionalDataException eof=" + e.eof + " length=" + e.length, e);
+            } catch (final EOFException e) {
+                if (datagramSocket.isClosed()) {
+                    // OK we're done.
+                    return;
+                }
+                logger.info("EOF encountered");
+            } catch (final IOException e) {
+                if (datagramSocket.isClosed()) {
+                    // OK we're done.
+                    return;
+                }
+                logger.error("Exception encountered on accept. Ignoring. Stack Trace :", e);
+            } catch (ParseException e) {
+                logger.error("Unable to parse log event", e);
+            }
+        }
+    }
+
+    /**
+     * Shutdown the server.
+     */
+    @Override
+    public void shutdown() {
+        this.setActive(false);
+        //Thread.currentThread().interrupt();
+        datagramSocket.close();
+    }
+
+    @Override
+    public String toString() {
+        return "UdpSocketServer [datagramSocket=" + datagramSocket + ", maxBufferSize=" + maxBufferSize
+                + ", logEventInput=" + logEventInput + "]";
+    }
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/XmlInputStreamLogEventBridge.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/XmlInputStreamLogEventBridge.java
new file mode 100644
index 0000000..3c4a1e0
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/XmlInputStreamLogEventBridge.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.jackson.xml.parser.XmlLogEventParser;
+
+/**
+ * Reads and logs {@link LogEvent}s from an {@link InputStream}.
+ */
+public class XmlInputStreamLogEventBridge extends InputStreamLogEventBridge {
+
+    private static final String EVENT_END = "</Event>";
+    private static final String EVENT_START_NS_N = "<Event>";
+    private static final String EVENT_START_NS_Y = "<Event ";
+
+    public XmlInputStreamLogEventBridge() {
+        this(1024, Charset.defaultCharset());
+    }
+
+    public XmlInputStreamLogEventBridge(final int bufferSize, final Charset charset) {
+        super(new XmlLogEventParser(), bufferSize, charset, EVENT_END);
+    }
+
+    @Override
+    protected int[] getEventIndices(final String text, final int beginIndex) {
+        int start = text.indexOf(EVENT_START_NS_Y, beginIndex);
+        int startLen = EVENT_START_NS_Y.length();
+        if (start < 0) {
+            start = text.indexOf(EVENT_START_NS_N, beginIndex);
+            startLen = EVENT_START_NS_N.length();
+        }
+        final int end = start < 0 ? -1 : text.indexOf(EVENT_END, start + startLen);
+        return new int[] { start, end };
+    }
+
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/AbstractJmsReceiver.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/AbstractJmsReceiver.java
new file mode 100644
index 0000000..a85d2f6
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/AbstractJmsReceiver.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server.mom.jms;
+
+import java.util.Properties;
+
+import org.apache.logging.log4j.server.JmsServer;
+
+/**
+ * Common JMS server functionality.
+ *
+ * @since 2.6
+ */
+public abstract class AbstractJmsReceiver {
+
+    class CommandLineArgs {
+
+    }
+
+    /**
+     * Prints out usage information to {@linkplain System#err standard error}.
+     */
+    protected abstract void usage();
+
+    /**
+     * Executes a JmsServer with the given command line arguments.
+     *
+     * @param interactive
+     *            Whether or not this is an interactive application by providing a command line and exit on error.
+     * @param args
+     *            command line arguments
+     *
+     * @throws Exception
+     */
+    protected void doMain(boolean interactive, final String... args) throws Exception {
+        // TODO Too many args, Use picocli
+        if (args.length < 5) {
+            usage();
+            if (interactive) {
+                System.exit(1);
+            }
+        }
+        final Properties properties = new Properties();
+        for (int index = 5; index < args.length; index += 2) {
+            properties.put(args[index], args[index + 1]);
+        }
+        final JmsServer server = new JmsServer(args[0], "ConnectionFactory", args[1], args[2], args[3],
+                args[4].toCharArray(), properties);
+        server.start();
+        if (interactive) {
+            server.commandLineLoop();
+        }
+    }
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsQueueReceiver.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsQueueReceiver.java
new file mode 100644
index 0000000..f7cadc8
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsQueueReceiver.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server.mom.jms;
+
+/**
+ * Receives Log Events over a JMS Queue. This implementation expects that all messages will
+ * contain a serialized LogEvent.
+ */
+public class JmsQueueReceiver extends AbstractJmsReceiver {
+
+    JmsQueueReceiver() {
+        // Usage is to call main()
+    }
+
+    /**
+     * Main startup for the receiver.
+     *
+     * @param args The command line arguments.
+     * @throws Exception if an error occurs.
+     */
+    public static void main(final String[] args) throws Exception {
+        new JmsQueueReceiver().doMain(true, args);
+    }
+
+    @Override
+    protected void usage() {
+        System.err.println("Wrong number of arguments.");
+        System.err.println("Usage: java " + JmsQueueReceiver.class.getName()
+            + " QueueConnectionFactoryBindingName QueueBindingName username password [jndiPropertyKey jndiPropertyValue]*");
+    }
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsTopicReceiver.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsTopicReceiver.java
new file mode 100644
index 0000000..8e50cdf
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsTopicReceiver.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server.mom.jms;
+
+/**
+ * Receives Topic messages that contain LogEvents. This implementation expects that all messages
+ * are serialized log events.
+ */
+public class JmsTopicReceiver extends AbstractJmsReceiver {
+
+    private JmsTopicReceiver() {
+        // Usage is to call main()
+    }
+
+    /**
+     * Main startup for the receiver.
+     *
+     * @param args The command line arguments.
+     * @throws Exception if an error occurs.
+     */
+    public static void main(final String[] args) throws Exception {
+        new JmsTopicReceiver().doMain(true, args);
+    }
+
+    @Override
+    protected void usage() {
+        System.err.println("Wrong number of arguments.");
+        System.err.println("Usage: java " + JmsTopicReceiver.class.getName()
+            + " TopicConnectionFactoryBindingName TopicBindingName username password [jndiPropertyKey jndiPropertyValue]*");
+    }
+}
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/package-info.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/package-info.java
new file mode 100644
index 0000000..dd9c90e
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+ * Supporting network code for JMS appenders.
+ *
+ * <p>Note that you can use JmsQueueReceiver or JmsTopicReceiver as executable main classes to receive log events over
+ * JMS (sent via the appropriate JMS appender) that can be subsequently logged according to the configuration given to
+ * the running process. Of course, use of these classes as standalone executables are entirely optional and can
+ * be used directly in your application (e.g., through your Spring {@code beans.xml} configuration).</p>
+ */
+package org.apache.logging.log4j.server.mom.jms;
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/package-info.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/package-info.java
new file mode 100644
index 0000000..c446a9d
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+ * Standalone server classes for consuming log events over a network. Each of the various servers should be used with
+ * another Log4j configuration to handle incoming {@link org.apache.logging.log4j.core.LogEvent}s. It is recommended
+ * to consider using the <a href="../../../../../../../../../manual/appenders.html#FlumeAppender">Flume Appender</a>
+ * for highly reliable networked logging.
+ */
+package org.apache.logging.log4j.server;
diff --git a/log4j-server/src/site/markdown/index.md b/log4j-server/src/site/markdown/index.md
new file mode 100644
index 0000000..b3d96ba
--- /dev/null
+++ b/log4j-server/src/site/markdown/index.md
@@ -0,0 +1,30 @@
+<!-- vim: set syn=markdown : -->
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+-->
+
+# Log4j Server components
+
+## Log4j Server components
+
+Standalone server classes for consuming log events over a network. Each of the various servers should be used with
+another Log4j configuration to handle incoming log events. It is recommended to consider using the 
+[Flume Appender](../manual/appenders.html#FlumeAppender) for highly reliable networked logging.
+
+## Requirements
+
+The Log4j Server components requires the Log4j 2 API and core. This component was introduced in Log4j 2.8.2, 
+before it was part of log4j-core. For more information, see [Runtime Dependencies](../manual/runtime-dependencies.html).
diff --git a/log4j-server/src/site/site.xml b/log4j-server/src/site/site.xml
new file mode 100644
index 0000000..f863dbf
--- /dev/null
+++ b/log4j-server/src/site/site.xml
@@ -0,0 +1,52 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+
+-->
+<project name="Log4j IOStreams"
+         xmlns="http://maven.apache.org/DECORATION/1.4.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 http://maven.apache.org/xsd/decoration-1.4.0.xsd">
+  <body>
+    <links>
+      <item name="Apache" href="http://www.apache.org/" />
+      <item name="Logging Services" href="http://logging.apache.org/"/>
+      <item name="Log4j" href="../index.html"/>
+    </links>
+
+    <!-- Component-specific reports -->
+    <menu ref="reports"/>
+
+	<!-- Overall Project Info -->
+    <menu name="Log4j Project Information" img="icon-info-sign">
+      <item name="Dependencies" href="../dependencies.html" />
+      <item name="Dependency Convergence" href="../dependency-convergence.html" />
+      <item name="Dependency Management" href="../dependency-management.html" />
+      <item name="Project Team" href="../team-list.html" />
+      <item name="Mailing Lists" href="../mail-lists.html" />
+      <item name="Issue Tracking" href="../issue-tracking.html" />
+      <item name="Project License" href="../license.html" />
+      <item name="Source Repository" href="../source-repository.html" />
+      <item name="Project Summary" href="../project-summary.html" />
+    </menu>
+
+    <menu name="Log4j Project Reports" img="icon-cog">
+      <item name="Changes Report" href="../changes-report.html" />
+      <item name="JIRA Report" href="../jira-report.html" />
+      <item name="Surefire Report" href="../surefire-report.html" />
+      <item name="RAT Report" href="../rat-report.html" />
+    </menu>
+  </body>
+</project>
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/AbstractSocketServerTest.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/AbstractSocketServerTest.java
new file mode 100644
index 0000000..758716b
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/AbstractSocketServerTest.java
@@ -0,0 +1,240 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.AppenderLoggingException;
+import org.apache.logging.log4j.core.appender.ConsoleAppender;
+import org.apache.logging.log4j.core.appender.SocketAppender;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.apache.logging.log4j.core.net.Protocol;
+import org.apache.logging.log4j.jackson.json.layout.JsonLayout;
+import org.apache.logging.log4j.jackson.xml.layout.XmlLayout;
+import org.apache.logging.log4j.test.AvailablePortFinder;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.junit.After;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ *
+ */
+public abstract class AbstractSocketServerTest {
+
+    protected static Thread thread;
+
+    private static final String MESSAGE = "This is test message";
+
+    private static final String MESSAGE_2 = "This is test message 2";
+
+    private static final String MESSAGE_WITH_SPECIAL_CHARS = "{This}\n[is]\"n\"a\"\r\ntrue:\n\ttest,\nmessage";
+
+    static final int PORT_NUM = AvailablePortFinder.getNextAvailable();
+
+    static final int PORT = PORT_NUM;
+
+    private final LoggerContext ctx = LoggerContext.getContext(false);
+
+    private final boolean expectLengthException;
+
+    protected final int port;
+
+    protected final Protocol protocol;
+
+    private final Logger rootLogger = ctx.getLogger(AbstractSocketServerTest.class.getSimpleName());
+
+    protected AbstractSocketServerTest(final Protocol protocol, final int port, final boolean expectLengthException) {
+        this.protocol = protocol;
+        this.port = port;
+        this.expectLengthException = expectLengthException;
+    }
+
+    protected Layout<String> createJsonLayout() {
+        // @formatter: off
+        return JsonLayout.newBuilder()
+            .setLocationInfo(true)
+            .setProperties(true)
+            .setPropertiesAsList(false)
+            .setComplete(false)
+            .setCompact(false)
+            .setEventEol(false)
+            .setIncludeStacktrace(true)
+            .build();
+        // @formatter: on
+
+        //return JsonLayout.createLayout(null, true, true, false, false, false, false, null, null, null, true);
+    }
+
+    protected abstract Layout<? extends Serializable> createLayout();
+
+    protected Layout<String> createXmlLayout() {
+        return XmlLayout.newBuilder()
+                .setLocationInfo(true)
+                .setProperties(true)
+                .setComplete(false)
+                .setCompact(false)
+                .setIncludeStacktrace(true)
+                .build();
+    }
+
+    @After
+    public void tearDown() {
+        final Map<String, Appender> map = rootLogger.getAppenders();
+        for (final Map.Entry<String, Appender> entry : map.entrySet()) {
+            final Appender appender = entry.getValue();
+            rootLogger.removeAppender(appender);
+            appender.stop();
+        }
+    }
+
+    @Test
+    @Ignore("Broken test?")
+    public void test1000ShortMessages() throws Exception {
+        testServer(1000);
+    }
+
+    @Test
+    @Ignore("Broken test?")
+    public void test100ShortMessages() throws Exception {
+        testServer(100);
+    }
+
+    @Test
+    public void test10ShortMessages() throws Exception {
+        testServer(10);
+    }
+
+    @Test
+    public void test1ShortMessages() throws Exception {
+        testServer(1);
+    }
+
+    @Test
+    public void test2ShortMessages() throws Exception {
+        testServer(2);
+    }
+
+    @Test
+    public void test64KBMessages() throws Exception {
+        final char[] a64K = new char[1024 * 64];
+        Arrays.fill(a64K, 'a');
+        final String m1 = new String(a64K);
+        final String m2 = MESSAGE_2 + m1;
+        if (expectLengthException) {
+            try {
+                testServer(m1, m2);
+            } catch (final AppenderLoggingException are) {
+                assertTrue("", are.getCause() != null && are.getCause() instanceof IOException);
+                // Failure expected.
+            }
+        } else {
+            testServer(m1, m2);
+        }
+    }
+
+
+    @Test
+    public void testMessagesWithSpecialChars() throws Exception {
+        testServer(MESSAGE_WITH_SPECIAL_CHARS);
+    }
+
+
+    private void testServer(final int size) throws Exception {
+        final String[] messages = new String[size];
+        for (int i = 0; i < messages.length; i++) {
+            messages[i] = MESSAGE + " " + i;
+        }
+        testServer(messages);
+    }
+
+    protected void testServer(final String... messages) throws Exception {
+        final Filter socketFilter = new ThreadNameFilter(Filter.Result.NEUTRAL, Filter.Result.DENY);
+        final Filter serverFilter = new ThreadNameFilter(Filter.Result.DENY, Filter.Result.NEUTRAL);
+        final Layout<? extends Serializable> socketLayout = createLayout();
+        final SocketAppender socketAppender = createSocketAppender(socketFilter, socketLayout);
+        socketAppender.start();
+        final ListAppender listAppender = new ListAppender("Events", serverFilter, null, false, false);
+        listAppender.start();
+        final PatternLayout layout = PatternLayout.newBuilder().setPattern("%m %ex%n").build();
+        final ConsoleAppender console = ConsoleAppender.createDefaultAppenderForLayout(layout);
+        final Logger serverLogger = ctx.getLogger(this.getClass().getName());
+        serverLogger.addAppender(console);
+        serverLogger.setAdditive(false);
+
+        // set appender on root and set level to debug
+        rootLogger.addAppender(socketAppender);
+        rootLogger.addAppender(listAppender);
+        rootLogger.setAdditive(false);
+        rootLogger.setLevel(Level.DEBUG);
+        for (final String message : messages) {
+            rootLogger.debug(message);
+        }
+        final int MAX_TRIES = 400;
+        for (int i = 0; i < MAX_TRIES; i++) {
+            if (listAppender.getEvents().size() < messages.length) {
+                try {
+                    // Let the server-side read the messages.
+                    Thread.sleep(50);
+                } catch (final Exception e) {
+                    e.printStackTrace();
+                }
+            } else {
+                break;
+            }
+        }
+        final List<LogEvent> events = listAppender.getEvents();
+        assertNotNull("No event retrieved", events);
+        assertEquals("Incorrect number of events received", messages.length, events.size());
+        for (int i = 0; i < messages.length; i++) {
+            assertTrue("Incorrect event", events.get(i).getMessage().getFormattedMessage().equals(messages[i]));
+        }
+    }
+
+    protected SocketAppender createSocketAppender(final Filter socketFilter,
+            final Layout<? extends Serializable> socketLayout) {
+        // @formatter:off
+        return SocketAppender.newBuilder()
+        .setProtocol(this.protocol)
+        .setHost("localhost")
+        .setPort(this.port)
+        .setReconnectDelayMillis(-1)
+        .setName("test")
+        .setImmediateFlush(true)
+        .setImmediateFail(false)
+        .setIgnoreExceptions(false)
+        .setLayout(socketLayout).setFilter(socketFilter)
+                .build();
+        // @formatter:on        
+    }
+
+}
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/SslXmlSocketServerTest.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/SslXmlSocketServerTest.java
new file mode 100644
index 0000000..6d08723
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/SslXmlSocketServerTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.nio.charset.Charset;
+
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.SocketAppender;
+import org.apache.logging.log4j.core.net.Protocol;
+import org.apache.logging.log4j.core.net.ssl.KeyStoreConfiguration;
+import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
+import org.apache.logging.log4j.core.net.ssl.StoreConfigurationException;
+import org.apache.logging.log4j.core.net.ssl.TestConstants;
+import org.apache.logging.log4j.core.net.ssl.TrustStoreConfiguration;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class SslXmlSocketServerTest extends AbstractSocketServerTest {
+
+    private static TcpSocketServer<InputStream> server;
+
+    private static SslConfiguration sslConfiguration;
+
+    private static void initServerSocketFactory() throws StoreConfigurationException {
+        final KeyStoreConfiguration ksc = new KeyStoreConfiguration(TestConstants.KEYSTORE_FILE,
+                TestConstants.KEYSTORE_PWD(), TestConstants.KEYSTORE_TYPE, null);
+        final TrustStoreConfiguration tsc = new TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE,
+                TestConstants.TRUSTSTORE_PWD(), null, null);
+        sslConfiguration = SslConfiguration.createSSLConfiguration(null, ksc, tsc);
+    }
+
+    @Override
+    protected SocketAppender createSocketAppender(final Filter socketFilter,
+            final Layout<? extends Serializable> socketLayout) {
+        // @formatter:off
+        return SocketAppender.newBuilder()
+        .setProtocol(this.protocol)
+        .setHost("localhost")
+        .setPort(this.port)
+        .setReconnectDelayMillis(-1)
+        .setName("test")
+        .setImmediateFlush(true)
+        .setImmediateFail(false)
+        .setIgnoreExceptions(false)
+        .setLayout(socketLayout).setFilter(socketFilter)
+                .setSslConfiguration(sslConfiguration)
+                .build();
+        // @formatter:on        
+    }
+
+    @BeforeClass
+    public static void setupClass() throws Exception {
+        LoggerContext.getContext(false).reconfigure();
+        initServerSocketFactory();
+        // Use a large buffer just to test the code, the UDP test uses a tiny buffer
+        server = new SecureTcpSocketServer<>(PORT_NUM, new XmlInputStreamLogEventBridge(1024 * 100,
+                Charset.defaultCharset()), sslConfiguration);
+        thread = server.startNewThread();
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        try {
+            server.shutdown();
+        } catch (final IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            thread.join();
+        } catch (final InterruptedException e) {
+            // ignore
+        }
+    }
+
+    public SslXmlSocketServerTest() {
+        super(Protocol.SSL, PORT, false);
+    }
+
+    @Override
+    protected Layout<String> createLayout() {
+        return super.createXmlLayout();
+    }
+
+}
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/TcpJsonSocketServerTest.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/TcpJsonSocketServerTest.java
new file mode 100644
index 0000000..63470dd
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/TcpJsonSocketServerTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.net.Protocol;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class TcpJsonSocketServerTest extends AbstractSocketServerTest {
+    
+    private static TcpSocketServer<InputStream> server;
+
+    @BeforeClass
+    public static void setupClass() throws Exception {
+        LoggerContext.getContext(false).reconfigure();
+        server = TcpSocketServer.createJsonSocketServer(PORT_NUM);
+        thread = server.startNewThread();
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        try {
+            server.shutdown();
+        } catch (final IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            thread.join();
+        } catch (final InterruptedException e) {
+            // ignore
+        }
+    }
+
+    public TcpJsonSocketServerTest() {
+        super(Protocol.TCP, PORT, false);
+    }
+
+    @Override
+    protected Layout<String> createLayout() {
+        return super.createJsonLayout();
+    }
+
+}
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/TcpXmlSocketServerTest.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/TcpXmlSocketServerTest.java
new file mode 100644
index 0000000..6a0ad13
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/TcpXmlSocketServerTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.net.Protocol;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class TcpXmlSocketServerTest extends AbstractSocketServerTest {
+    
+    private static TcpSocketServer<InputStream> server;
+
+    @BeforeClass
+    public static void setupClass() throws Exception {
+        LoggerContext.getContext(false).reconfigure();
+        // Use a large buffer just to test the code, the UDP test uses a tiny buffer
+        server = new TcpSocketServer<>(PORT_NUM, new XmlInputStreamLogEventBridge(1024 * 100,
+                Charset.defaultCharset()));
+        thread = server.startNewThread();
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        try {
+            server.shutdown();
+        } catch (final IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            thread.join();
+        } catch (final InterruptedException e) {
+            // ignore
+        }
+    }
+
+    public TcpXmlSocketServerTest() {
+        super(Protocol.TCP, PORT, false);
+    }
+
+    @Override
+    protected Layout<String> createLayout() {
+        return super.createXmlLayout();
+    }
+
+}
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/ThreadIdFilter.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/ThreadIdFilter.java
new file mode 100644
index 0000000..d98e3f4
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/ThreadIdFilter.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.filter.AbstractFilter;
+
+/**
+ * TODO Should use thread ID cache?
+ * @since 2.6
+ */
+public class ThreadIdFilter extends AbstractFilter {
+
+    private static final long serialVersionUID = 1L;
+
+    public ThreadIdFilter(final Result onMatch, final Result onMismatch) {
+        super(onMatch, onMismatch);
+    }
+
+    @Override
+    public Filter.Result filter(final LogEvent event) {
+        return event.getThreadId() == Thread.currentThread().getId() ? onMatch : onMismatch;
+    }
+}
\ No newline at end of file
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/ThreadNameFilter.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/ThreadNameFilter.java
new file mode 100644
index 0000000..4204ac1
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/ThreadNameFilter.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.filter.AbstractFilter;
+
+/**
+ * TODO Should use thread name cache?
+ */
+public class ThreadNameFilter extends AbstractFilter {
+
+    private static final long serialVersionUID = 1L;
+
+    public ThreadNameFilter(final Result onMatch, final Result onMismatch) {
+        super(onMatch, onMismatch);
+    }
+
+    @Override
+    public Filter.Result filter(final LogEvent event) {
+        return event.getThreadName().equals(Thread.currentThread().getName()) ? onMatch : onMismatch;
+    }
+}
\ No newline at end of file
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/ThreadPriorityFilter.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/ThreadPriorityFilter.java
new file mode 100644
index 0000000..6074f86
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/ThreadPriorityFilter.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.filter.AbstractFilter;
+
+/**
+ * TODO Should use thread priority cache?
+ * @since 2.6
+ */
+public class ThreadPriorityFilter extends AbstractFilter {
+
+    private static final long serialVersionUID = 1L;
+
+    public ThreadPriorityFilter(final Result onMatch, final Result onMismatch) {
+        super(onMatch, onMismatch);
+    }
+
+    @Override
+    public Filter.Result filter(final LogEvent event) {
+        return event.getThreadPriority() == Thread.currentThread().getPriority() ? onMatch : onMismatch;
+    }
+}
\ No newline at end of file
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/UdpJsonSocketServerTest.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/UdpJsonSocketServerTest.java
new file mode 100644
index 0000000..e6b6d93
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/UdpJsonSocketServerTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.InputStream;
+import java.io.Serializable;
+
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.net.Protocol;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class UdpJsonSocketServerTest extends AbstractSocketServerTest {
+
+    private static UdpSocketServer<InputStream> server;
+
+    @BeforeClass
+    public static void setupClass() throws Exception {
+        LoggerContext.getContext(false).reconfigure();
+        server = UdpSocketServer.createJsonSocketServer(PORT_NUM);
+        thread = server.startNewThread();
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        server.shutdown();
+        try {
+            thread.join();
+        } catch (final InterruptedException e) {
+            // ignore
+        }
+    }
+
+    public UdpJsonSocketServerTest() {
+        super(Protocol.UDP, PORT, true);
+    }
+
+    @Override
+    protected Layout<? extends Serializable> createLayout() {
+        return super.createJsonLayout();
+    }
+
+}
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/UdpXmlSocketServerTest.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/UdpXmlSocketServerTest.java
new file mode 100644
index 0000000..9cbb07f
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/UdpXmlSocketServerTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server;
+
+import java.io.InputStream;
+import java.io.Serializable;
+import java.nio.charset.Charset;
+
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.net.Protocol;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class UdpXmlSocketServerTest extends AbstractSocketServerTest {
+
+    private static UdpSocketServer<InputStream> server;
+
+    @BeforeClass
+    public static void setupClass() throws Exception {
+        LoggerContext.getContext(false).reconfigure();
+        // Use a tiny buffer just to test the code, the TCP test uses a large buffer
+        server = new UdpSocketServer<>(PORT_NUM, new XmlInputStreamLogEventBridge(100,
+                Charset.defaultCharset()));
+        thread = server.startNewThread();
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        server.shutdown();
+        try {
+            thread.join();
+        } catch (final InterruptedException e) {
+            // ignore
+        }
+    }
+
+    public UdpXmlSocketServerTest() {
+        super(Protocol.UDP, PORT, true);
+    }
+
+    @Override
+    protected Layout<? extends Serializable> createLayout() {
+        return super.createXmlLayout();
+    }
+
+}
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/mom/activemq/ActiveMqBrokerServiceHelper.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/mom/activemq/ActiveMqBrokerServiceHelper.java
new file mode 100644
index 0000000..e1fb522
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/mom/activemq/ActiveMqBrokerServiceHelper.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server.mom.activemq;
+
+import java.io.IOException;
+
+import org.apache.activemq.broker.BrokerService;
+
+/**
+ * Helps starts an embedded Apache ActiveMQ service broker.
+ */
+public class ActiveMqBrokerServiceHelper {
+
+    public static BrokerService startBrokerService(final String brokerName, String brokerUrlString, final int port)
+            throws Exception {
+        // TODO Abstract out scheme
+        brokerUrlString = "tcp://localhost:" + port;
+        final BrokerService broker = new BrokerService();
+        // configure the Broker
+        broker.setBrokerName(brokerName);
+        broker.addConnector(brokerUrlString);
+        broker.setPersistent(false);
+        broker.start();
+        broker.waitUntilStarted();
+        return broker;
+    }
+
+    public static void stopBrokerService(final BrokerService brokerService) throws IOException, Exception {
+        if (brokerService != null) {
+            brokerService.deleteAllMessages();
+            brokerService.stop();
+            brokerService.waitUntilStopped();
+        }
+    }
+
+}
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/mom/activemq/ActiveMqBrokerServiceRule.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/mom/activemq/ActiveMqBrokerServiceRule.java
new file mode 100644
index 0000000..a3116ac
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/mom/activemq/ActiveMqBrokerServiceRule.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server.mom.activemq;
+
+import org.apache.activemq.broker.BrokerService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.TestMarkers;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * JUnit {@link TestRule} to manage an in-JVM Apache ActiveMQ broker with socket
+ * communications between clients and broker.
+ */
+public class ActiveMqBrokerServiceRule implements TestRule {
+
+	static final Logger logger = LogManager.getLogger(ActiveMqBrokerServiceRule.class);
+
+	/**
+	 * Apache Active MQ uses this property name to lookup which port to use to
+	 * connect to a broker.
+	 */
+	public static final String PORT_PROPERTY_NAME = "org.apache.activemq.AMQ_PORT";
+
+	private final String brokerName;
+
+	private String brokerUrlString;
+
+	private final String portPropertyName;
+
+	public ActiveMqBrokerServiceRule(final String brokerName, final String portPropertyName) {
+		this.brokerName = brokerName;
+		this.portPropertyName = portPropertyName;
+	}
+
+	@Override
+	public Statement apply(final Statement base, final Description description) {
+		return new Statement() {
+
+			@Override
+			public void evaluate() throws Throwable {
+				final BrokerService broker = ActiveMqBrokerServiceHelper.startBrokerService(brokerName, brokerUrlString,
+						Integer.parseInt(System.getProperty(portPropertyName)));
+				logger.debug(TestMarkers.TEST_RULE_LIFE_CYCLE, "{} started Apache Active MQ {}",
+						this.getClass().getSimpleName(), this);
+				try {
+					base.evaluate();
+				} finally {
+					ActiveMqBrokerServiceHelper.stopBrokerService(broker);
+					logger.debug(TestMarkers.TEST_RULE_LIFE_CYCLE, "{} stopped Apache Active MQ {}",
+							this.getClass().getSimpleName(), this);
+				}
+			}
+
+		};
+	}
+
+	public String getBrokerName() {
+		return brokerName;
+	}
+
+	public String getBrokerUrlString() {
+		return brokerUrlString;
+	}
+
+	@Override
+	public String toString() {
+		final StringBuilder builder = new StringBuilder();
+		builder.append("ActiveMqBrokerServiceRule [brokerName=");
+		builder.append(brokerName);
+		builder.append(", bindAddress=");
+		builder.append(brokerUrlString);
+		builder.append("]");
+		return builder.toString();
+	}
+
+}
diff --git a/log4j-server/src/test/java/org/apache/logging/log4j/server/mom/jms/JmsQueueReceiverTest.java b/log4j-server/src/test/java/org/apache/logging/log4j/server/mom/jms/JmsQueueReceiverTest.java
new file mode 100644
index 0000000..ba6ea87
--- /dev/null
+++ b/log4j-server/src/test/java/org/apache/logging/log4j/server/mom/jms/JmsQueueReceiverTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.server.mom.jms;
+
+import org.apache.logging.log4j.server.mom.activemq.ActiveMqBrokerServiceRule;
+import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
+import org.apache.logging.log4j.test.RuleChainFactory;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+
+public class JmsQueueReceiverTest {
+
+    private static final AvailablePortSystemPropertyTestRule portRule = AvailablePortSystemPropertyTestRule
+            .create(ActiveMqBrokerServiceRule.PORT_PROPERTY_NAME);
+
+    private static final ActiveMqBrokerServiceRule activeMqBrokerServiceRule = new ActiveMqBrokerServiceRule(
+            JmsQueueReceiverTest.class.getName(), portRule.getName());
+
+    @ClassRule
+    public static RuleChain ruleChain = RuleChainFactory.create(portRule, activeMqBrokerServiceRule);
+
+    @Test
+    public void testMain() throws Exception {
+        new JmsQueueReceiver().doMain(false, new String[] { "org.apache.activemq.jndi.ActiveMQInitialContextFactory",
+                "tcp://localhost:" + portRule.getPort(), "testq", "admin", "admin", "queue.testq", "testq" });
+    }
+}
diff --git a/log4j-server/src/test/resources/org/apache/logging/log4j/core/net/ssl/client.log4j2-keystore.jks b/log4j-server/src/test/resources/org/apache/logging/log4j/core/net/ssl/client.log4j2-keystore.jks
new file mode 100644
index 0000000..36f11b6
--- /dev/null
+++ b/log4j-server/src/test/resources/org/apache/logging/log4j/core/net/ssl/client.log4j2-keystore.jks
Binary files differ
diff --git a/log4j-server/src/test/resources/org/apache/logging/log4j/core/net/ssl/truststore.jks b/log4j-server/src/test/resources/org/apache/logging/log4j/core/net/ssl/truststore.jks
new file mode 100644
index 0000000..0e6aaf2
--- /dev/null
+++ b/log4j-server/src/test/resources/org/apache/logging/log4j/core/net/ssl/truststore.jks
Binary files differ
diff --git a/pom.xml b/pom.xml
index 98dbfa0..0f20b3d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,7 @@
   <parent>
     <groupId>org.apache.logging</groupId>
     <artifactId>logging-parent</artifactId>
-    <version>7</version>
+    <version>1</version>
   </parent>
   <description>Apache Log4j 2 Tools</description>
   <url>https://logging.apache.org/log4j/2.x/</url>
@@ -41,7 +41,7 @@
       <email>rgoers@apache.org</email>
       <organization>Nextiva</organization>
       <roles>
-        <role>PMC Member</role>
+        <role>PMC Chair</role>
       </roles>
       <timezone>America/Phoenix</timezone>
     </developer>
@@ -56,6 +56,15 @@
       <timezone>America/Los_Angeles</timezone>
     </developer>
     <developer>
+      <id>sdeboy</id>
+      <name>Scott Deboy</name>
+      <email>sdeboy@apache.org</email>
+      <roles>
+        <role>PMC Member</role>
+      </roles>
+      <timezone>America/Los_Angeles</timezone>
+    </developer>
+    <developer>
       <id>rpopma</id>
       <name>Remko Popma</name>
       <email>rpopma@apache.org</email>
@@ -68,6 +77,15 @@
       </properties>
     </developer>
     <developer>
+      <id>nickwilliams</id>
+      <name>Nick Williams</name>
+      <email>nickwilliams@apache.org</email>
+      <roles>
+        <role>PMC Member</role>
+      </roles>
+      <timezone>America/Chicago</timezone>
+    </developer>
+    <developer>
       <id>mattsicker</id>
       <name>Matt Sicker</name>
       <email>mattsicker@apache.org</email>
@@ -77,7 +95,42 @@
       </roles>
       <timezone>America/Chicago</timezone>
     </developer>
+    <developer>
+      <id>bbrouwer</id>
+      <name>Bruce Brouwer</name>
+      <email>bruce.brouwer@gmail.com</email>
+      <roles>
+        <role>Committer</role>
+      </roles>
+      <timezone>America/Detroit</timezone>
+    </developer>
+    <developer>
+      <id>mikes</id>
+      <name>Mikael Ståldal</name>
+      <email>mikes@apache.org</email>
+      <organization>Magine TV</organization>
+      <roles>
+        <role>PMC Member</role>
+      </roles>
+      <timezone>Europe/Stockholm</timezone>
+    </developer>
   </developers>
+  <!-- Contributors -->
+  <contributors>
+      <contributor>
+        <name>Murad Ersoy</name>
+        <email>muradersoy@gmail.com</email>
+        <url>https://www.behance.net/muradersoy</url>
+        <roles>
+          <role>Illustrator and Designer</role>
+          <role>created the new Log4j 2 logo.</role>
+        </roles>
+        <timezone>Europe/Istanbul</timezone>
+        <properties>
+          <picUrl>https://mir-s3-cdn-cf.behance.net/user/138/403dcf1521581.54d67f8fb01f7.jpg</picUrl>
+        </properties>
+      </contributor>
+   </contributors>
   <mailingLists>
     <mailingList>
       <name>log4j-user</name>
@@ -93,12 +146,14 @@
     </mailingList>
     <mailingList>
       <name>log4j-dev</name>
-      <subscribe>dev-subscribe@logging.apache.org</subscribe>
-      <unsubscribe>dev-unsubscribe@logging.apache.org</unsubscribe>
-      <post>dev@logging.apache.org</post>
-      <archive>https://lists.apache.org/list.html?dev@logging.apache.org</archive>
+      <subscribe>log4j-dev-subscribe@logging.apache.org</subscribe>
+      <unsubscribe>log4j-dev-unsubscribe@logging.apache.org</unsubscribe>
+      <post>log4j-dev@logging.apache.org</post>
+      <archive>https://lists.apache.org/list.html?log4j-dev@logging.apache.org</archive>
       <otherArchives>
-        <otherArchive>http://mail-archives.apache.org/mod_mbox/logging-dev/</otherArchive>
+        <otherArchive>http://mail-archives.apache.org/mod_mbox/logging-log4j-dev/</otherArchive>
+        <otherArchive>http://marc.info/?l=log4j-dev</otherArchive>
+        <otherArchive>http://dir.gmane.org/gmane.comp.jakarta.log4j.devel</otherArchive>
       </otherArchives>
     </mailingList>
   </mailingLists>
@@ -109,6 +164,49 @@
     <tag>log4j-${Log4jReleaseVersion}</tag>
   </scm>
   <properties>
+    <!-- make sure to update these for each release! -->
+    <log4jParentDir>${basedir}</log4jParentDir>
+    <Log4jReleaseVersion>2.10.0</Log4jReleaseVersion>
+    <!--<Log4jReleaseManager>Ralph Goers</Log4jReleaseManager>-->
+    <!--<Log4jReleaseKey>B3D8E1BA</Log4jReleaseKey>-->
+    <Log4jReleaseManager>Matt Sicker</Log4jReleaseManager>
+    <Log4jReleaseKey>FA1C814D</Log4jReleaseKey>
+    <!-- note that any properties you want available in velocity templates must not use periods! -->
+    <jackson2Version>2.8.7</jackson2Version>
+    <compiler.plugin.version>3.6.0</compiler.plugin.version>
+    <pmd.plugin.version>3.7</pmd.plugin.version>
+    <findbugs.plugin.version>3.0.4</findbugs.plugin.version>
+    <changes.plugin.version>2.12.1</changes.plugin.version>
+    <javadoc.plugin.version>2.10.4</javadoc.plugin.version>
+    <!-- surefire.plugin.version 2.18 yields http://jira.codehaus.org/browse/SUREFIRE-1121, which is fixed in 2.18.1 -->
+    <!-- surefire.plugin.version 2.19 yields https://issues.apache.org/jira/browse/SUREFIRE-1193. -->
+    <surefire.plugin.version>2.19.1</surefire.plugin.version>
+    <failsafe.plugin.version>2.19.1</failsafe.plugin.version>
+    <checkstyle.plugin.version>2.17</checkstyle.plugin.version>
+    <rat.plugin.version>0.12</rat.plugin.version>
+    <pdf.plugin.version>1.2</pdf.plugin.version>
+    <cobertura.plugin.version>2.7</cobertura.plugin.version>
+    <jacoco.plugin.version>0.7.7.201606060606</jacoco.plugin.version>
+    <release.plugin.version>2.5.3</release.plugin.version>
+    <scm.plugin.version>1.9.5</scm.plugin.version>
+    <jxr.plugin.version>2.5</jxr.plugin.version>
+    <clirr.plugin.version>2.8</clirr.plugin.version>
+    <site.plugin.version>3.4</site.plugin.version>
+    <remote.resources.plugin.version>1.5</remote.resources.plugin.version>
+    <manifestfile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestfile>
+    <maven.compiler.source>1.7</maven.compiler.source>
+    <maven.compiler.target>1.7</maven.compiler.target>
+    <docLabel>Site Documentation</docLabel>
+    <projectDir />
+    <commonsLoggingVersion>1.2</commonsLoggingVersion>
+    <osgi.api.version>4.3.1</osgi.api.version>
+    <!-- Version 5.15.0 requires Java 8 -->
+    <activemq.version>5.14.5</activemq.version>
+    <!-- Allow Clirr severity to be overriden by the command-line option -DminSeverity=level -->
+    <minSeverity>info</minSeverity>
+    <jctoolsVersion>1.2.1</jctoolsVersion>
+    <mockitoVersion>2.2.7</mockitoVersion>
+    <argLine>-Xms256m -Xmx1024m</argLine>
   </properties>
   <pluginRepositories>
     <pluginRepository>
@@ -117,8 +215,548 @@
     </pluginRepository>
   </pluginRepositories>
   <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-api</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-api</artifactId>
+        <version>${project.version}</version>
+        <type>test-jar</type>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-core</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-core</artifactId>
+        <version>${project.version}</version>
+        <type>test-jar</type>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-databind</artifactId>
+        <version>${jackson2Version}</version>
+        <optional>true</optional>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-xml</artifactId>
+        <version>${jackson2Version}</version>
+        <optional>true</optional>
+      </dependency>
+      <dependency>
+        <groupId>org.jboss.spec.javax.jms</groupId>
+        <artifactId>jboss-jms-api_1.1_spec</artifactId>
+        <version>1.0.1.Final</version>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-broker</artifactId>
+        <version>${activemq.version}</version>
+        <scope>test</scope>
+        <exclusions>
+          <exclusion>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jms_1.1_spec</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.12</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-all</artifactId>
+        <version>1.3</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-core</artifactId>
+        <version>${mockitoVersion}</version>
+        <scope>test</scope>
+      </dependency>
+    </dependencies>
   </dependencyManagement>
-   <distributionManagement>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.felix</groupId>
+          <artifactId>maven-bundle-plugin</artifactId>
+          <!--  Using version 2.5.4 causes Jenkins to get compiler errors in log4j-perf. -->
+          <version>3.2.0</version>
+          <inherited>true</inherited>
+          <extensions>true</extensions>
+          <executions>
+            <execution>
+              <goals>
+                <goal>manifest</goal>
+              </goals>
+              <phase>process-classes</phase>
+            </execution>
+          </executions>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-changes-plugin</artifactId>
+          <version>${changes.plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-release-plugin</artifactId>
+          <version>${release.plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-scm-plugin</artifactId>
+          <version>${scm.plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <version>${checkstyle.plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-javadoc-plugin</artifactId>
+          <version>${javadoc.plugin.version}</version>
+          <configuration>
+            <bottom><![CDATA[<p align="center">Copyright &#169; {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
+            Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
+            and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
+            <additionalparam>${javadoc.opts}</additionalparam>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-pmd-plugin</artifactId>
+          <version>${pmd.plugin.version}</version>
+        </plugin>
+        <!-- some nice default compiler options -->
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>${compiler.plugin.version}</version>
+          <configuration>
+            <source>${maven.compiler.source}</source>
+            <target>${maven.compiler.target}</target>
+            <showDeprecation>true</showDeprecation>
+            <showWarnings>true</showWarnings>
+            <encoding>UTF-8</encoding>
+            <fork>true</fork>
+            <meminitial>256</meminitial>
+            <maxmem>1024</maxmem>
+            <compilerArguments>
+              <Xmaxwarns>10000</Xmaxwarns>
+              <Xlint />
+            </compilerArguments>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <version>${surefire.plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-failsafe-plugin</artifactId>
+          <version>${failsafe.plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-source-plugin</artifactId>
+          <version>3.0.1</version>
+          <executions>
+            <execution>
+              <id>attach-sources</id>
+              <phase>verify</phase>
+              <goals>
+                <goal>jar-no-fork</goal>
+              </goals>
+            </execution>
+          </executions>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jxr-plugin</artifactId>
+          <version>${jxr.plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>clirr-maven-plugin</artifactId>
+          <version>${clirr.plugin.version}</version>
+          <configuration>
+            <minSeverity>${minSeverity}</minSeverity>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.eluder.coveralls</groupId>
+          <artifactId>coveralls-maven-plugin</artifactId>
+          <version>4.3.0</version>
+        </plugin>
+        <plugin>
+          <groupId>org.jacoco</groupId>
+          <artifactId>jacoco-maven-plugin</artifactId>
+          <version>${jacoco.plugin.version}</version>
+          <executions>
+            <execution>
+                <id>prepare-agent</id>
+                <goals>
+                  <goal>prepare-agent</goal>
+                </goals>
+            </execution>
+            <execution>
+              <id>default-report</id>
+              <phase>prepare-package</phase>
+              <goals>
+                <goal>report</goal>
+              </goals>
+            </execution>
+          </executions>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestFile>${manifestfile}</manifestFile>
+            <manifestEntries>
+              <Specification-Title>${project.name}</Specification-Title>
+              <Specification-Version>${project.version}</Specification-Version>
+              <Specification-Vendor>${project.organization.name}</Specification-Vendor>
+              <Implementation-Title>${project.name}</Implementation-Title>
+              <Implementation-Version>${project.version}</Implementation-Version>
+              <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
+              <Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
+              <X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
+              <X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <version>3.0.1</version>
+        <executions>
+          <execution>
+            <id>copy-sitecss</id>
+            <!-- fetch site.xml before creating site documentation -->
+            <phase>pre-site</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.build.directory}/site</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>${log4jParentDir}/src/site/resources</directory>
+                  <includes>
+                    <include>**/*</include>
+                  </includes>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>${surefire.plugin.version}</version>
+        <configuration>
+          <systemPropertyVariables>
+            <java.awt.headless>true</java.awt.headless>
+          </systemPropertyVariables>
+          <forkCount>2C</forkCount>
+          <reuseForks>true</reuseForks>
+          <excludes>
+            <exclude>${log4j.skip.test1}</exclude>
+            <exclude>${log4j.skip.test2}</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-failsafe-plugin</artifactId>
+        <version>${failsafe.plugin.version}</version>
+        <executions>
+          <execution>
+            <id>integration-tests</id>
+            <goals>
+              <goal>integration-test</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>verify</id>
+            <goals>
+              <goal>verify</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <systemPropertyVariables>
+            <java.awt.headless>true</java.awt.headless>
+          </systemPropertyVariables>
+          <argLine>-Xms256m -Xmx1024m</argLine>
+          <forkCount>1</forkCount>
+          <reuseForks>false</reuseForks>
+          <encoding>UTF-8</encoding>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-site-plugin</artifactId>
+        <version>${site.plugin.version}</version>
+        <dependencies>
+          <dependency>
+            <groupId>org.apache.maven.wagon</groupId>
+            <artifactId>wagon-ssh</artifactId>
+            <version>2.10</version>
+          </dependency>
+        </dependencies>
+        <configuration>
+          <!-- only build English site even on other language OS -->
+          <locales>en</locales>
+          <!-- Exclude the navigation file for Maven 1 sites
+               and the changes file used by the changes-plugin,
+               as they interfere with the site generation. -->
+          <moduleExcludes>
+            <xdoc>navigation.xml,changes.xml</xdoc>
+          </moduleExcludes>
+          <templateDirectory>${log4jParentDir}/src/site</templateDirectory>
+          <template>site.vm</template>
+        </configuration>
+      </plugin>
+      <!-- <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>cobertura-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>clean</id>
+            <goals>
+              <goal>clean</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin> -->
+      <!-- We need to disable the standard ASF configuration to be able to publish our own notice and license files -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>process</goal>
+            </goals>
+            <configuration>
+              <skip>true</skip>
+              <resourceBundles />
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-pdf-plugin</artifactId>
+        <version>${pdf.plugin.version}</version>
+        <executions>
+          <execution>
+            <id>pdf</id>
+            <phase>site</phase>
+            <goals>
+              <goal>pdf</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+      </plugin>
+      <!-- RAT report -->
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <version>${rat.plugin.version}</version>
+        <configuration>
+          <excludes>
+            <!-- Matches other RAT configurations in this POM -->
+            <exclude>src/main/resources/META-INF/services/**/*</exclude>
+            <!-- IntelliJ files -->
+            <exclude>.idea/**/*</exclude>
+            <exclude>src/test/resources/**/*</exclude>
+            <!-- IDE settings imports -->
+            <exclude>src/ide/**</exclude>
+            <!-- does it even make sense to apply a license to a GPG signature? -->
+            <exclude>**/*.asc</exclude>
+            <!-- jQuery is MIT-licensed, but RAT can't figure it out -->
+            <exclude>src/site/resources/js/jquery.js</exclude>
+            <exclude>src/site/resources/js/jquery.min.js</exclude>
+            <!-- Generated files -->
+            <exclude>log4j-distribution/target/**/*</exclude>
+            <exclude>log4j-distribution/.project</exclude>
+            <exclude>log4j-distribution/.settings/**</exclude>
+            <exclude>velocity.log</exclude>
+            <!-- Other -->
+            <exclude>felix-cache/**</exclude>
+            <exclude>RELEASE-NOTES.md</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+      <!-- DOAP (RDF) metadata generation -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-doap-plugin</artifactId>
+        <version>1.2</version>
+        <configuration>
+          <doapOptions>
+            <programmingLanguage>Java</programmingLanguage>
+            <category>library</category>
+          </doapOptions>
+          <asfExtOptions>
+            <charter>
+              The Apache Logging Services Project creates and maintains open-source software related to the logging of
+              application behavior and released at no charge to the public.
+            </charter>
+          </asfExtOptions>
+        </configuration>
+        <executions>
+          <execution>
+            <id>site</id>
+            <phase>site</phase>
+            <goals>
+              <goal>generate</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <reporting>
+    <plugins>
+      <!-- Changes report -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-changes-plugin</artifactId>
+        <version>${changes.plugin.version}</version>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>changes-report</report>
+              <report>jira-report</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+        <configuration>
+          <statusIds>Resolved, Closed</statusIds>
+          <columnNames>Type,Key,Summary,Assignee,Status,Resolution,Fix Version</columnNames>
+          <useJql>true</useJql>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+        <version>2.8.1</version>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>index</report>
+              <report>dependencies</report>
+              <report>dependency-info</report>
+              <report>dependency-convergence</report>
+              <report>dependency-management</report>
+              <report>project-team</report>
+              <report>mailing-list</report>
+              <report>issue-tracking</report>
+              <report>license</report>
+              <report>scm</report>
+              <report>summary</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+        <configuration>
+          <!-- you'd think these would be the defaults, right? -->
+          <customBundle>${project.basedir}/src/site/custom/project-info-report.properties</customBundle>
+          <webAccessUrl>${project.scm.url}</webAccessUrl>
+          <anonymousConnection>${project.scm.connection}</anonymousConnection>
+          <developerConnection>${project.scm.developerConnection}</developerConnection>
+          <scmTag>log4j-${Log4jReleaseVersion}</scmTag>
+        </configuration>
+      </plugin>
+      <!-- Surefire report -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+        <version>${surefire.plugin.version}</version>
+        <reportSets>
+          <reportSet>
+            <id>integration-tests</id>
+            <reports>
+              <report>failsafe-report-only</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <!-- RAT report -->
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <version>${rat.plugin.version}</version>
+        <configuration>
+          <excludes>
+            <!-- Matches other RAT configurations in this POM -->
+            <exclude>src/main/resources/META-INF/services/**/*</exclude>
+            <!-- IntelliJ files -->
+            <exclude>.idea/**/*</exclude>
+            <exclude>src/test/resources/**/*</exclude>
+            <!-- IDE settings imports -->
+            <exclude>src/ide/**</exclude>
+            <!-- does it even make sense to apply a license to a GPG signature? -->
+            <exclude>**/*.asc</exclude>
+            <!-- jQuery is MIT-licensed, but RAT can't figure it out -->
+            <exclude>src/site/resources/js/jquery.js</exclude>
+            <exclude>src/site/resources/js/jquery.min.js</exclude>
+            <!-- Generated files -->
+            <exclude>log4j-distribution/target/**/*</exclude>
+            <exclude>log4j-distribution/.project</exclude>
+            <exclude>log4j-distribution/.settings/**</exclude>
+            <exclude>velocity.log</exclude>
+            <!-- Other -->
+            <exclude>felix-cache/**</exclude>
+            <exclude>RELEASE-NOTES.txt</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+  <distributionManagement>
     <downloadUrl>https://logging.apache.org/log4j/2.x/download.html</downloadUrl>
     <!-- site is only included to make maven-site-plugin stop complaining -->
     <site>
@@ -127,6 +765,235 @@
     </site>
   </distributionManagement>
   <modules>
-    <module>log4j-internal-tools</module>
+    <module>log4j-server</module>
   </modules>
- </project>
+  <profiles>
+    <profile>
+        <id>Windows</id>
+        <activation>
+            <os>
+                <family>Windows</family>
+            </os>
+        </activation>
+        <build>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <configuration>
+                        <argLine>-server</argLine>
+                    </configuration>
+                </plugin>
+              <plugin>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <configuration>
+                  <argLine>-server</argLine>
+                </configuration>
+              </plugin>
+            </plugins>
+        </build>
+    </profile>
+    <profile>
+      <id>pdf</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-pdf-plugin</artifactId>
+            <version>${pdf.plugin.version}</version>
+            <executions>
+              <execution>
+                <id>pdf</id>
+                <phase>generate-resources</phase>
+                <goals>
+                  <goal>pdf</goal>
+                </goals>
+                <configuration>
+                  <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>release-notes</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-changes-plugin</artifactId>
+            <version>${changes.plugin.version}</version>
+            <configuration>
+              <template>announcement.vm</template>
+              <templateDirectory>src/changes</templateDirectory>
+              <runOnlyAtExecutionRoot>true</runOnlyAtExecutionRoot>
+              <announcementDirectory>.</announcementDirectory>
+              <announcementFile>RELEASE-NOTES.txt</announcementFile>
+              <issueManagementSystems>
+                <issueManagementSystem>changes.xml</issueManagementSystem>
+                <!--<issueManagementSystem>JIRA</issueManagementSystem> -->
+              </issueManagementSystems>
+              <version>${Log4jReleaseVersion}</version>
+              <announceParameters>
+                <releaseVersion>${Log4jReleaseVersion}</releaseVersion>
+                <releaseCount>${Log4jReleaseCount}</releaseCount>
+              </announceParameters>
+              <useJql>true</useJql>
+            </configuration>
+            <executions>
+              <execution>
+                <id>create-release-notes</id>
+                <phase>generate-resources</phase>
+                <goals>
+                  <goal>announcement-generate</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>apache-release</id>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>source-release-assembly</id>
+                <configuration>
+                  <skipAssembly>true</skipAssembly>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+      <modules>
+        <module>log4j-distribution</module>
+      </modules>
+    </profile>
+    <profile>
+      <id>rat</id>
+      <build>
+        <plugins>
+          <!-- RAT report -->
+          <plugin>
+            <groupId>org.apache.rat</groupId>
+            <artifactId>apache-rat-plugin</artifactId>
+            <version>${rat.plugin.version}</version>
+            <configuration>
+              <excludes>
+                <!-- Matches other RAT configurations in this POM -->
+                <exclude>src/main/resources/META-INF/services/**/*</exclude>
+                <!-- IntelliJ files -->
+                <exclude>.idea/**/*</exclude>
+                <exclude>src/test/resources/**/*</exclude>
+                <!-- IDE settings imports -->
+                <exclude>src/ide/**</exclude>
+                <!-- does it even make sense to apply a license to a GPG signature? -->
+                <exclude>**/*.asc</exclude>
+                <!-- jQuery is MIT-licensed, but RAT can't figure it out -->
+                <exclude>src/site/resources/js/jquery.js</exclude>
+                <exclude>src/site/resources/js/jquery.min.js</exclude>
+                <!-- Generated files -->
+                <exclude>log4j-distribution/target/**/*</exclude>
+                <exclude>log4j-distribution/.project</exclude>
+                <exclude>log4j-distribution/.settings/**</exclude>
+                <exclude>velocity.log</exclude>
+                <!-- Other -->
+                <exclude>felix-cache/**</exclude>
+                <exclude>RELEASE-NOTES.md</exclude>
+              </excludes>
+            </configuration>
+            <executions>
+              <execution>
+                <phase>verify</phase>
+                <goals>
+                  <goal>check</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <!-- http://www.yourkit.com/docs/80/help/agent.jsp -->
+      <id>yourkit-mac</id>
+      <!--
+      <activation>
+        <os>
+          <family>Mac</family>
+        </os>
+        <file>
+          <exists>${yourkit.home}/bin/mac/libyjpagent.jnilib</exists>
+        </file>
+      </activation>
+      -->
+      <properties>
+        <yourkit.home>/Applications/YJP.app</yourkit.home>
+      </properties>
+      <dependencies>
+        <dependency>
+          <groupId>com.yourkit</groupId>
+          <artifactId>yjp-controller-api-redist</artifactId>
+          <version>2013</version>
+          <scope>system</scope>
+          <systemPath>${yourkit.home}/lib/yjp-controller-api-redist.jar</systemPath>
+        </dependency>
+      </dependencies>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <argLine>-agentpath:"${yourkit.home}/bin/mac/libyjpagent.jnilib"</argLine>
+            </configuration>
+          </plugin>
+          <plugin>
+            <artifactId>maven-failsafe-plugin</artifactId>
+            <configuration>
+              <argLine>-agentpath:"${yourkit.home}/bin/mac/libyjpagent.jnilib"</argLine>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>jdk7</id>
+      <activation>
+        <jdk>1.7</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <argLine>-XX:MaxPermSize=512m</argLine>
+            </configuration>
+          </plugin>
+          <plugin>
+            <artifactId>maven-failsafe-plugin</artifactId>
+            <configuration>
+              <argLine>-XX:MaxPermSize=512m</argLine>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>java8-doclint-disabled</id>
+      <activation>
+        <jdk>[1.8,)</jdk>
+      </activation>
+      <properties>
+        <javadoc.opts>-Xdoclint:none</javadoc.opts>
+      </properties>
+    </profile>
+  </profiles>
+</project>