Merge remote-tracking branch 'aosp/upstream-pull-525' into master

* aosp/upstream-pull-525:
  Increase checked size for build result
  Fix description.
  Remove unnecessary .gitignore
  New option -quiet for all commands
  Tests for XML documentation generator.
  Test and documentation for multiple values.
  Adjust test case names to new conventions.
  Command to print version.
  Update documentation for command line interface
  Close ServerSocket in tests.
  Wrap long usage lines in documentation.
  Make sure the build runs with Java 5.
  Flush output automatically
  Use -dest for option name as output can be folder or file.
  Correct test method naming.
  Remove obsolete, commented configuration.
  Github #525: Simple Command Line Interface

Change-Id: Ia4c47f78760fc756ecc029ff4bc21d265e22d82a
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..b55fb27
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+# Build jacoco from sources for the platform
+#
+# Note: this is only intended to be used for the platform development. This is *not* intended
+# to be used in the SDK where apps can use the official jacoco release.
+include $(CLEAR_VARS)
+
+jacoco_src_files := $(call all-java-files-under,org.jacoco.core/src)
+jacoco_src_files += $(call all-java-files-under,org.jacoco.agent/src)
+jacoco_src_files += $(call all-java-files-under,org.jacoco.agent.rt/src)
+
+# Some Jacoco source files depend on classes that do not exist in Android. While these classes are
+# not executed at runtime (because we use offline instrumentation), they will cause issues when
+# compiling them with ART during dex pre-opting. Therefore, it would prevent from applying code
+# coverage on classes in the bootclasspath (frameworks, services, ...) or system apps.
+# Note: we still may need to update the source code to cut dependencies in mandatory jacoco classes.
+jacoco_android_exclude_list := \
+  %org.jacoco.core/src/org/jacoco/core/runtime/ModifiedSystemClassRuntime.java \
+  %org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/PreMain.java \
+  %org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/CoverageTransformer.java \
+  %org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/JmxRegistration.java
+
+LOCAL_SRC_FILES := $(filter-out $(jacoco_android_exclude_list),$(jacoco_src_files))
+
+# In order to include Jacoco in core libraries, we cannot depend on anything in the
+# bootclasspath (or we would create dependency cycle). Therefore we compile against
+# the SDK android.jar which gives the same APIs Jacoco depends on.
+LOCAL_SDK_VERSION := 9
+
+LOCAL_MODULE := jacocoagent
+LOCAL_MODULE_TAGS := optional
+LOCAL_STATIC_JAVA_LIBRARIES := jacoco-asm
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+#
+# Build asm-5.0.1 as a static library.
+#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := jacoco-asm
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_SRC_FILES := asm-debug-all-5.0.1$(COMMON_JAVA_PACKAGE_SUFFIX)
+# Workaround for b/27319022
+LOCAL_JACK_FLAGS := -D jack.import.jar.debug-info=false
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_PREBUILT)
diff --git a/MODULE_LICENSE_EPL b/MODULE_LICENSE_EPL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_EPL
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..54fc346
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,14 @@
+License
+=======
+
+Copyright (c) 2009, 2015 Mountainminds GmbH & Co. KG and Contributors
+
+The JaCoCo Java Code Coverage Library and all included documentation is made
+available by Mountainminds GmbH & Co. KG, Munich. Except indicated below, the
+Content is provided to you under the terms and conditions of the Eclipse Public
+License Version 1.0 ("EPL"). A copy of the EPL is available at
+[http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html).
+
+Please visit
+[http://www.eclemma.org/jacoco/trunk/doc/license.html](http://www.eclemma.org/jacoco/trunk/doc/license.html)
+for the complete license information including third party licenses and trademarks.
diff --git a/PREBUILT b/PREBUILT
new file mode 100644
index 0000000..c8d9fd8
--- /dev/null
+++ b/PREBUILT
@@ -0,0 +1,7 @@
+The ASM jar required by jacoco is updated in the following way:
+
+mvn -f org.jacoco.agent.rt/pom.xml dependency:copy-dependencies
+cp org.jacoco.agent.rt/target/dependency/asm-debug-all-5.0.1.jar ./
+mvn clean
+
+The Android.mk must be updated to reference the right prebuilt.
diff --git a/README.android b/README.android
new file mode 100644
index 0000000..1e6118a
--- /dev/null
+++ b/README.android
@@ -0,0 +1,17 @@
+We build an equivalent of the jacoco-agent.jar which contains classes from org.jacoco.core,
+org.jacoco.agent and org.jacoco.agent.rt packages but also classes from asm 5.0.1.
+
+However, Jacoco depends on classes that do not exist in Android (java.lang.instrument.* or
+javax.management.*) for runtime instrumentation only. The ART compiler would reject those classes
+when they are either in the bootclasspath (core, frameworks, ...) or system apps.
+
+Since we only use offline instrumentation for code coverage (using Jack) and do not execute these
+classes at runtime, we simply not compile them here.
+
+We also need to modify the source code to cut dependencies to the classes that we exclude from the
+compilation. The changes are surrounded by "BEGIN android-change" and "END android-change". Here
+is the list of the changes:
+
+1) Remove the creation of JmxRegistration in org.jacoco.agent.rt.internal.Agent.
+2) Change default OutputMode to none in org.jacoco.core.runtime.AgentOptions
+3) Merge https://github.com/jacoco/jacoco/pull/525
diff --git a/README.version b/README.version
new file mode 100644
index 0000000..0ef82ce
--- /dev/null
+++ b/README.version
@@ -0,0 +1,4 @@
+URL: https://github.com/jacoco/jacoco/tree/v0.7.5
+Version: v0.7.5
+BugComponent: 108682
+Owners: shertz
diff --git a/asm-debug-all-5.0.1.jar b/asm-debug-all-5.0.1.jar
new file mode 100644
index 0000000..76d4b6a
--- /dev/null
+++ b/asm-debug-all-5.0.1.jar
Binary files differ
diff --git a/config.mk b/config.mk
new file mode 100644
index 0000000..d645621
--- /dev/null
+++ b/config.mk
@@ -0,0 +1,16 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+JACOCO_PACKAGE_NAME := org.jacoco.agent.rt.internal
+
diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnection.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnection.java
index 8e20e24..d82ef8f 100644
--- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnection.java
+++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnection.java
@@ -41,15 +41,15 @@
 		socketA.connect(socketB);
 	}
 
-	public Socket getSocketA() {
+	public MockSocket getSocketA() {
 		return socketA;
 	}
 
-	public Socket getSocketB() {
+	public MockSocket getSocketB() {
 		return socketB;
 	}
 
-	private class MockSocket extends Socket {
+	class MockSocket extends Socket {
 
 		private MockSocket other;
 
@@ -85,6 +85,7 @@
 								return -1;
 							}
 							final Byte b = buffer.poll();
+							buffer.notifyAll();
 							if (b != null) {
 								return 0xff & b.intValue();
 							}
@@ -98,26 +99,36 @@
 
 			@Override
 			public int available() throws IOException {
-				return buffer.size();
+				synchronized (buffer) {
+					return buffer.size();
+				}
 			}
 
 		};
 
-		public MockSocket() throws SocketException {
+		private MockSocket() throws SocketException {
 			super((SocketImpl) null);
 			closed = false;
 		}
 
-		void connect(MockSocket other) {
+		private void connect(MockSocket other) {
 			this.other = other;
 			other.other = this;
 		}
 
+		public void waitUntilInputBufferIsEmpty() throws InterruptedException {
+			synchronized (buffer) {
+				while (!closed && !buffer.isEmpty()) {
+					buffer.wait();
+				}
+			}
+		}
+
 		// socket methods with mocking behavior:
 
 		@Override
 		public OutputStream getOutputStream() throws IOException {
-			if (closed) {
+			if (isClosed()) {
 				throw new SocketException("Socket is closed");
 			}
 			return out;
@@ -125,7 +136,7 @@
 
 		@Override
 		public InputStream getInputStream() throws IOException {
-			if (closed) {
+			if (isClosed()) {
 				throw new SocketException("Socket is closed");
 			}
 			return in;
@@ -133,8 +144,8 @@
 
 		@Override
 		public void close() throws IOException {
-			closed = true;
 			synchronized (buffer) {
+				closed = true;
 				buffer.notifyAll();
 			}
 			synchronized (other.buffer) {
@@ -144,7 +155,9 @@
 
 		@Override
 		public boolean isClosed() {
-			return closed;
+			synchronized (buffer) {
+				return closed;
+			}
 		}
 
 		// unsupported socket methods:
diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpClientOutputTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpClientOutputTest.java
index 9ac8fa8..e7f1866 100644
--- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpClientOutputTest.java
+++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpClientOutputTest.java
@@ -21,6 +21,7 @@
 import java.util.List;
 
 import org.jacoco.agent.rt.internal.ExceptionRecorder;
+import org.jacoco.agent.rt.internal.output.MockSocketConnection.MockSocket;
 import org.jacoco.core.data.ExecutionDataStore;
 import org.jacoco.core.data.SessionInfo;
 import org.jacoco.core.data.SessionInfoStore;
@@ -40,7 +41,8 @@
 
 	private IAgentOutput controller;
 
-	private Socket remoteSocket;
+	private MockSocket localSocket;
+	private MockSocket remoteSocket;
 
 	private RemoteControlWriter remoteWriter;
 
@@ -52,13 +54,14 @@
 	public void setup() throws Exception {
 		logger = new ExceptionRecorder();
 		final MockSocketConnection con = new MockSocketConnection();
+		localSocket = con.getSocketA();
 		remoteSocket = con.getSocketB();
 		remoteWriter = new RemoteControlWriter(remoteSocket.getOutputStream());
 		controller = new TcpClientOutput(logger) {
 			@Override
 			protected Socket createSocket(AgentOptions options)
 					throws IOException {
-				return con.getSocketA();
+				return localSocket;
 			}
 		};
 		data = new RuntimeData();
@@ -75,6 +78,8 @@
 
 	@Test
 	public void testRemoteClose() throws Exception {
+		localSocket.waitUntilInputBufferIsEmpty();
+
 		remoteSocket.close();
 		controller.shutdown();
 		logger.assertNoException();
@@ -82,16 +87,18 @@
 
 	@Test
 	public void testInvalidCommand() throws Exception {
+		// send invalid command to agent
 		remoteWriter.visitSessionInfo(new SessionInfo("info", 1, 2));
-		while (remoteReader.read()) {
-		}
+
+		localSocket.waitUntilInputBufferIsEmpty();
 		controller.shutdown();
 		logger.assertException(IOException.class, "No session info visitor.");
 	}
 
 	@Test
 	public void testWriteExecutionData() throws Exception {
-		data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42).getProbes()[0] = true;
+		data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42)
+				.getProbes()[0] = true;
 		data.setSessionId("stubid");
 
 		controller.writeExecutionData(false);
diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpConnectionTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpConnectionTest.java
index d713203..34b5388 100644
--- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpConnectionTest.java
+++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpConnectionTest.java
@@ -66,8 +66,8 @@
 		final OutputStream remoteOut = mockConnection.getSocketB()
 				.getOutputStream();
 		new ExecutionDataWriter(remoteOut);
-		final TcpConnection con = new TcpConnection(
-				mockConnection.getSocketA(), data);
+		final TcpConnection con = new TcpConnection(mockConnection.getSocketA(),
+				data);
 		con.init();
 		remoteOut.write(123);
 		con.run();
@@ -82,8 +82,8 @@
 				.getOutputStream();
 		new ExecutionDataWriter(remoteOut);
 
-		final TcpConnection con = new TcpConnection(
-				mockConnection.getSocketA(), data);
+		final TcpConnection con = new TcpConnection(mockConnection.getSocketA(),
+				data);
 		con.init();
 
 		final Future<Void> f = executor.submit(new Callable<Void>() {
@@ -95,26 +95,7 @@
 
 		assertBlocks(f);
 
-		mockConnection.getSocketB().close();
-		f.get();
-	}
-
-	/**
-	 * Remote endpoint is closed before even a valid header was send.
-	 */
-	public void testRemoteCloseWithoutHeader() throws Throwable {
-		final TcpConnection con = new TcpConnection(
-				mockConnection.getSocketA(), data);
-
-		final Future<Void> f = executor.submit(new Callable<Void>() {
-			public Void call() throws Exception {
-				con.init();
-				return null;
-			}
-		});
-
-		assertBlocks(f);
-
+		mockConnection.getSocketA().waitUntilInputBufferIsEmpty();
 		mockConnection.getSocketB().close();
 		f.get();
 	}
@@ -130,8 +111,8 @@
 				.getOutputStream();
 		new ExecutionDataWriter(remoteOut);
 
-		final TcpConnection con = new TcpConnection(
-				mockConnection.getSocketA(), data);
+		final TcpConnection con = new TcpConnection(mockConnection.getSocketA(),
+				data);
 		con.init();
 
 		final Future<Void> f = executor.submit(new Callable<Void>() {
@@ -149,14 +130,15 @@
 
 	@Test
 	public void testRemoteDump() throws Exception {
-		data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42).getProbes()[0] = true;
+		data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42)
+				.getProbes()[0] = true;
 		data.setSessionId("stubid");
 
 		final RemoteControlWriter remoteWriter = new RemoteControlWriter(
 				mockConnection.getSocketB().getOutputStream());
 
-		final TcpConnection con = new TcpConnection(
-				mockConnection.getSocketA(), data);
+		final TcpConnection con = new TcpConnection(mockConnection.getSocketA(),
+				data);
 		con.init();
 
 		final Future<Void> f = executor.submit(new Callable<Void>() {
@@ -177,13 +159,14 @@
 
 	@Test
 	public void testLocalDump() throws Exception {
-		data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42).getProbes()[0] = true;
+		data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42)
+				.getProbes()[0] = true;
 		data.setSessionId("stubid");
 
 		new RemoteControlWriter(mockConnection.getSocketB().getOutputStream());
 
-		final TcpConnection con = new TcpConnection(
-				mockConnection.getSocketA(), data);
+		final TcpConnection con = new TcpConnection(mockConnection.getSocketA(),
+				data);
 		con.init();
 
 		final Future<Void> f = executor.submit(new Callable<Void>() {
@@ -204,13 +187,13 @@
 
 	@Test
 	public void testLocalDumpWithoutInit() throws Exception {
-		final TcpConnection con = new TcpConnection(
-				mockConnection.getSocketA(), data);
+		final TcpConnection con = new TcpConnection(mockConnection.getSocketA(),
+				data);
 		// Must not write any data as we're not initialized:
 		con.writeExecutionData(false);
 
-		assertEquals(0, mockConnection.getSocketB().getInputStream()
-				.available());
+		assertEquals(0,
+				mockConnection.getSocketB().getInputStream().available());
 	}
 
 	private void readAndAssertData() throws IOException {
@@ -233,13 +216,14 @@
 
 	@Test
 	public void testRemoteReset() throws Exception {
-		data.getExecutionData(Long.valueOf(123), "Foo", 1).getProbes()[0] = true;
+		data.getExecutionData(Long.valueOf(123), "Foo", 1)
+				.getProbes()[0] = true;
 
 		final RemoteControlWriter remoteWriter = new RemoteControlWriter(
 				mockConnection.getSocketB().getOutputStream());
 
-		final TcpConnection con = new TcpConnection(
-				mockConnection.getSocketA(), data);
+		final TcpConnection con = new TcpConnection(mockConnection.getSocketA(),
+				data);
 		con.init();
 
 		final Future<Void> f = executor.submit(new Callable<Void>() {
diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java
index dd45e14..e21371b 100644
--- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java
+++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java
@@ -121,7 +121,9 @@
 			output = createAgentOutput();
 			output.startup(options, data);
 			if (options.getJmx()) {
-				jmxRegistration = new JmxRegistration(this);
+// BEGIN android-change
+//				jmxRegistration = new JmxRegistration(this);
+// END android-change
 			}
 		} catch (final Exception e) {
 			logger.logExeption(e);
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilterTest.java
new file mode 100644
index 0000000..9026208
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilterTest.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import org.jacoco.core.internal.instr.InstrSupport;
+import org.junit.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+
+import static org.junit.Assert.assertEquals;
+
+public class PrivateEmptyNoArgConstructorFilterTest implements IFilterOutput {
+
+	private final IFilter filter = new PrivateEmptyNoArgConstructorFilter();
+
+	private AbstractInsnNode fromInclusive;
+	private AbstractInsnNode toInclusive;
+
+	@Test
+	public void test() {
+		final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION,
+				Opcodes.ACC_PRIVATE, "<init>", "()V", null, null);
+
+		m.visitVarInsn(Opcodes.ALOAD, 0);
+		m.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
+				"()V", false);
+		m.visitInsn(Opcodes.RETURN);
+
+		filter.filter("Foo", "java/lang/Object", m, this);
+
+		assertEquals(m.instructions.getFirst(), fromInclusive);
+		assertEquals(m.instructions.getLast(), toInclusive);
+	}
+
+	public void ignore(final AbstractInsnNode fromInclusive,
+			final AbstractInsnNode toInclusive) {
+		this.fromInclusive = fromInclusive;
+		this.toInclusive = toInclusive;
+	}
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/filter/ConstructorTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/filter/ConstructorTest.java
new file mode 100644
index 0000000..a74d467
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/filter/ConstructorTest.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.test.filter;
+
+import org.jacoco.core.analysis.ICounter;
+import org.jacoco.core.test.filter.targets.Constructor;
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.junit.Test;
+
+/**
+ * Test of filtering of a bytecode that is generated for a private empty
+ * constructors that do not have no arguments.
+ */
+public class ConstructorTest extends ValidationTestBase {
+
+	public ConstructorTest() {
+		super(Constructor.class);
+	}
+
+	@Test
+	public void testCoverageResult() {
+		// not filtered because not private:
+		assertLine("packageLocal", ICounter.FULLY_COVERED);
+
+		// not filtered because has argument:
+		assertLine("arg", ICounter.FULLY_COVERED);
+
+		// not filtered because not empty - prepares arguments for super
+		// constructor:
+		assertLine("super", ICounter.FULLY_COVERED);
+
+		// not filtered because contains initialization of a field to hold
+		// reference to an instance of outer class that is passed as an
+		// argument:
+		assertLine("inner", ICounter.FULLY_COVERED);
+
+		// not filtered because not empty - contains initialization of
+		// a field:
+		assertLine("innerStatic", ICounter.FULLY_COVERED);
+
+		// not filtered because default constructor for not private inner
+		// classes is not private:
+		assertLine("publicDefault", ICounter.FULLY_COVERED);
+		assertLine("packageLocalDefault", ICounter.FULLY_COVERED);
+
+		assertLine("privateDefault", ICounter.EMPTY);
+
+		assertLine("privateNonEmptyNoArg", ICounter.FULLY_COVERED);
+
+		assertLine("privateEmptyNoArg", ICounter.EMPTY);
+		assertLine("return", ICounter.EMPTY);
+	}
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/filter/SyntheticTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/filter/SyntheticTest.java
index a0b54e0..8f8d253 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/test/filter/SyntheticTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/filter/SyntheticTest.java
@@ -27,7 +27,7 @@
 
 	@Test
 	public void testCoverageResult() {
-		assertMethodCount(6);
+		assertMethodCount(5);
 
 		assertLine("classdef", ICounter.EMPTY);
 		assertLine("field", ICounter.EMPTY);
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/filter/targets/Constructor.java b/org.jacoco.core.test/src/org/jacoco/core/test/filter/targets/Constructor.java
new file mode 100644
index 0000000..8623d2d
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/filter/targets/Constructor.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.test.filter.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+
+/**
+ * This test target is a constructors.
+ */
+public class Constructor {
+
+	Constructor() { // $line-packageLocal$
+	}
+
+	private Constructor(Object arg) { // $line-arg$
+	}
+
+	private static class Super extends Constructor {
+		private Super() {
+			super(null); // $line-super$
+		}
+	}
+
+	private class Inner {
+		private Inner() { // $line-inner$
+		}
+	}
+
+	private static class InnerStatic {
+		private Object field = this;
+
+		private InnerStatic() { // $line-innerStatic$
+		}
+	}
+
+	public static class PublicDefault { // $line-publicDefault$
+	}
+
+	static class PackageLocalDefault { // $line-packageLocalDefault$
+	}
+
+	private static class PrivateDefault { // $line-privateDefault$
+	}
+
+	private static class PrivateNonEmptyNoArg {
+		private PrivateNonEmptyNoArg() {
+			nop(); // $line-privateNonEmptyNoArg$
+		}
+	}
+
+	private static class PrivateEmptyNoArg {
+		private PrivateEmptyNoArg() { // $line-privateEmptyNoArg$
+		} // $line-return$
+	}
+
+	public static void main(String[] args) {
+		new Super();
+		new Constructor().new Inner();
+		new InnerStatic();
+		new PublicDefault();
+		new PackageLocalDefault();
+		new PrivateDefault();
+		new PrivateNonEmptyNoArg();
+		new PrivateEmptyNoArg();
+	}
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/filter/targets/Synthetic.java b/org.jacoco.core.test/src/org/jacoco/core/test/filter/targets/Synthetic.java
index 783495d..43826a8 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/test/filter/targets/Synthetic.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/filter/targets/Synthetic.java
@@ -18,6 +18,12 @@
 
 	private static int counter; // $line-field$
 
+	/**
+	 * {@link org.jacoco.core.test.validation.targets.Target06 Default
+	 * constructor will refer to a line of class definition}, so that we define
+	 * constructor explicitly in order to verify that we filter all other
+	 * constructions here that might refer to line of class definition.
+	 */
 	private Synthetic() {
 	}
 
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/PrivateEmptyDefaultConstructorTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/PrivateEmptyDefaultConstructorTest.java
index 410f1df..ac9b927 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/PrivateEmptyDefaultConstructorTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/PrivateEmptyDefaultConstructorTest.java
@@ -30,8 +30,8 @@
 	public void testCoverageResult() {
 
 		assertLine("classdef", ICounter.EMPTY);
-		assertLine("super", ICounter.NOT_COVERED);
-		assertLine("constructor", ICounter.NOT_COVERED);
+		assertLine("super", ICounter.EMPTY);
+		assertLine("constructor", ICounter.EMPTY);
 
 	}
 
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java
index ee05143..8e07e56 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java
@@ -23,6 +23,7 @@
 import org.jacoco.core.internal.analysis.filter.IFilter;
 import org.jacoco.core.internal.analysis.filter.IFilterOutput;
 import org.jacoco.core.internal.analysis.filter.LombokGeneratedFilter;
+import org.jacoco.core.internal.analysis.filter.PrivateEmptyNoArgConstructorFilter;
 import org.jacoco.core.internal.analysis.filter.SynchronizedFilter;
 import org.jacoco.core.internal.analysis.filter.SyntheticFilter;
 import org.jacoco.core.internal.analysis.filter.TryWithResourcesEcjFilter;
@@ -48,7 +49,7 @@
 	private static final IFilter[] FILTERS = new IFilter[] { new EnumFilter(),
 			new SyntheticFilter(), new SynchronizedFilter(),
 			new TryWithResourcesJavacFilter(), new TryWithResourcesEcjFilter(),
-			new LombokGeneratedFilter() };
+			new PrivateEmptyNoArgConstructorFilter(), new LombokGeneratedFilter() };
 
 	private final String className;
 
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java
index e4958bd..50a295d 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java
@@ -73,11 +73,16 @@
 		if (cursor == null) {
 			return;
 		}
-		do {
-			cursor = cursor.getNext();
-		} while (cursor != null && (cursor.getType() == AbstractInsnNode.FRAME
+		cursor = cursor.getNext();
+		skipNonOpcodes();
+	}
+
+	final void skipNonOpcodes() {
+		while (cursor != null && (cursor.getType() == AbstractInsnNode.FRAME
 				|| cursor.getType() == AbstractInsnNode.LABEL
-				|| cursor.getType() == AbstractInsnNode.LINE));
+				|| cursor.getType() == AbstractInsnNode.LINE)) {
+			cursor = cursor.getNext();
+		}
 	}
 
 }
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java
new file mode 100644
index 0000000..9e1bd43
--- /dev/null
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.VarInsnNode;
+
+/**
+ * Filters private empty constructors that do not have arguments.
+ */
+public final class PrivateEmptyNoArgConstructorFilter implements IFilter {
+
+	public void filter(final String className, final String superClassName,
+			final MethodNode methodNode, final IFilterOutput output) {
+		if ((methodNode.access & Opcodes.ACC_PRIVATE) != 0
+				&& "<init>".equals(methodNode.name)
+				&& "()V".equals(methodNode.desc)
+				&& new Matcher().match(methodNode, superClassName)) {
+			output.ignore(methodNode.instructions.getFirst(),
+					methodNode.instructions.getLast());
+		}
+	}
+
+	private static class Matcher extends AbstractMatcher {
+		private boolean match(final MethodNode methodNode,
+				final String superClassName) {
+			cursor = methodNode.instructions.getFirst();
+			skipNonOpcodes();
+			if (cursor.getOpcode() != Opcodes.ALOAD
+					|| ((VarInsnNode) cursor).var != 0) {
+				return false;
+			}
+			nextIs(Opcodes.INVOKESPECIAL);
+			MethodInsnNode m = (MethodInsnNode) cursor;
+			if (m != null && superClassName.equals(m.owner)
+					&& "<init>".equals(m.name) && ("()V").equals(m.desc)) {
+				nextIs(Opcodes.RETURN);
+				return cursor != null;
+			}
+			return false;
+		}
+	}
+
+}
diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java b/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java
index 6422832..cf57512 100644
--- a/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java
+++ b/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java
@@ -494,7 +494,10 @@
 	 */
 	public OutputMode getOutput() {
 		final String value = options.get(OUTPUT);
-		return value == null ? OutputMode.file : OutputMode.valueOf(value);
+// BEGIN android-change
+//		return value == null ? OutputMode.file : OutputMode.valueOf(value);
+		return value == null ? OutputMode.none : OutputMode.valueOf(value);
+// END android-change
 	}
 
 	/**
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index cb7b855..6561c81 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -34,6 +34,8 @@
   <li>Exclude from a report methods which are annotated with <code>@lombok.Generated</code>.
       Initial analysis and contribution by Rüdiger zu Dohna.
       (GitHub <a href="https://github.com/jacoco/jacoco/issues/513">#513</a>).</li>
+  <li>Exclude from a report private empty constructors that do not have arguments
+      (GitHub <a href="https://github.com/jacoco/jacoco/issues/529">#529</a>).</li>
   <li>Maven aggregated reports will now also include modules of runtime dependencies
       (GitHub <a href="https://github.com/jacoco/jacoco/issues/498">#498</a>).</li>
   <li>JaCoCo now comes with a simple command line interface