startig to fill opentracing repo - not yet functional at all
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..49ca981
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.idea
+*.iml
+target
+
diff --git a/geronimo-microprofile-opentracing-spec/pom.xml b/geronimo-microprofile-opentracing-spec/pom.xml
new file mode 100644
index 0000000..d73cc96
--- /dev/null
+++ b/geronimo-microprofile-opentracing-spec/pom.xml
@@ -0,0 +1,34 @@
+<?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">
+  <parent>
+    <artifactId>geronimo-opentracing</artifactId>
+    <groupId>org.apache.geronimo</groupId>
+    <version>1.0.1-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>geronimo-microprofile-opentracing-spec</artifactId>
+  <name>Geronimo OpenTracing :: Spec</name>
+
+  <properties>
+    <geronimo.jpms.name>org.eclipse.microprofile.opentracing</geronimo.jpms.name>
+  </properties>
+</project>
diff --git a/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrar.java b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrar.java
new file mode 100644
index 0000000..5526e08
--- /dev/null
+++ b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrar.java
@@ -0,0 +1,47 @@
+/*
+ * 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.eclipse.microprofile.opentracing;
+
+import java.util.ServiceLoader;
+import java.util.concurrent.ExecutorService;
+import javax.ws.rs.client.ClientBuilder;
+
+/**
+ * Allows a user to activate tracing on a client builder.
+ */
+public final class ClientTracingRegistrar {
+    /**
+     * @param cb the client builder to active tracing on.
+     * @return the same client builder with tracing activated.
+     */
+    public static ClientBuilder configure(final ClientBuilder cb) {
+        return ServiceLoader.load(ClientTracingRegistrarProvider.class).iterator().next().configure(cb);
+    }
+
+    /**
+     * @param cb the client builder to active tracing on.
+     * @param executorService the executor service the client will use.
+     * @return the same client builder with tracing activated.
+     */
+    public static ClientBuilder configure(final ClientBuilder cb, final ExecutorService executorService) {
+        return ServiceLoader.load(ClientTracingRegistrarProvider.class).iterator().next().configure(cb, executorService);
+    }
+
+    private ClientTracingRegistrar() {
+        // no-op
+    }
+}
diff --git a/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrarProvider.java b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrarProvider.java
new file mode 100644
index 0000000..1909364
--- /dev/null
+++ b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/ClientTracingRegistrarProvider.java
@@ -0,0 +1,31 @@
+/*
+ * 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.eclipse.microprofile.opentracing;
+
+import java.util.concurrent.ExecutorService;
+
+import javax.ws.rs.client.ClientBuilder;
+
+/**
+ * Standard java SPI which is used by {@link ClientTracingRegistrar}.
+ */
+public interface ClientTracingRegistrarProvider {
+
+    ClientBuilder configure(ClientBuilder builder);
+
+    ClientBuilder configure(ClientBuilder builder, ExecutorService executorService);
+}
diff --git a/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/Traced.java b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/Traced.java
new file mode 100644
index 0000000..0ddc5fa
--- /dev/null
+++ b/geronimo-microprofile-opentracing-spec/src/main/java/org/eclipse/microprofile/opentracing/Traced.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.eclipse.microprofile.opentracing;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.enterprise.util.Nonbinding;
+import javax.interceptor.InterceptorBinding;
+
+@InterceptorBinding
+@Retention(RUNTIME)
+@Target({ TYPE, METHOD })
+public @interface Traced {
+
+    /**
+     * This method only modifies the default behavior when set to false.
+     * Depending if Traced has been set on the class it behaves differently:
+     *
+     * <ul>
+     * <li>If <code>@Traced</code> exists on the class then setting this flag to false
+     * on a method will disable the span creation for the endpoint</li>
+     * <li>If the class doesn't have the <code>@Traced</code> marker then the parent is ignored.</li>
+     * </ul>
+     *
+     * @return should the method be traced or not.
+     */
+    @Nonbinding
+    boolean value() default true;
+
+    /**
+     * Allows to customize the span name.
+     *
+     * @return the span name for the "current" endpoint.
+     */
+    @Nonbinding
+    String operationName() default "";
+}
diff --git a/geronimo-opentracing-impl/pom.xml b/geronimo-opentracing-impl/pom.xml
new file mode 100644
index 0000000..cfdba21
--- /dev/null
+++ b/geronimo-opentracing-impl/pom.xml
@@ -0,0 +1,125 @@
+<?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">
+  <parent>
+    <artifactId>geronimo-opentracing</artifactId>
+    <groupId>org.apache.geronimo</groupId>
+    <version>1.0.1-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>geronimo-opentracing-impl</artifactId>
+  <name>Geronimo OpenTracing :: Impl</name>
+
+  <properties>
+    <geronimo.jpms.name>org.apache.geronimo.opentracing</geronimo.jpms.name>
+
+    <tck.version>1.1-SNAPSHOT</tck.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.geronimo</groupId>
+      <artifactId>geronimo-microprofile-opentracing-spec</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo</groupId>
+      <artifactId>geronimo-opentracing-spec</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.openwebbeans</groupId>
+      <artifactId>openwebbeans-impl</artifactId>
+      <version>2.0.5</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.arquillian.testng</groupId>
+      <artifactId>arquillian-testng-container</artifactId>
+      <version>1.1.13.Final</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.testng</groupId>
+      <artifactId>testng</artifactId>
+      <version>6.8.21</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.meecrowave</groupId>
+      <artifactId>meecrowave-arquillian</artifactId>
+      <version>1.2.1</version>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>javax.inject</groupId>
+          <artifactId>javax.inject</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.microprofile.opentracing</groupId>
+      <artifactId>microprofile-opentracing-tck</artifactId>
+      <version>${tck.version}</version>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>org.eclipse.microprofile.opentracing</groupId>
+          <artifactId>microprofile-opentracing-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>javax.ws.rs</groupId>
+          <artifactId>javax.ws.rs-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>io.opentracing</groupId>
+          <artifactId>opentracing-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.jboss.resteasy</groupId>
+          <artifactId>resteasy-client</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.jboss.resteasy</groupId>
+          <artifactId>resteasy-jackson-provider</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.21.0</version>
+        <configuration>
+          <suiteXmlFiles>
+            <suiteXmlFile>${project.basedir}/src/test/resources/tck.xml</suiteXmlFile>
+          </suiteXmlFiles>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/FinishedSpan.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/FinishedSpan.java
new file mode 100644
index 0000000..6349ee7
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/FinishedSpan.java
@@ -0,0 +1,31 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import io.opentracing.Span;
+
+public class FinishedSpan {
+    private final Span span;
+
+    FinishedSpan(final Span span) {
+        this.span = span;
+    }
+
+    public Span getSpan() {
+        return span;
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/GeronimoTracer.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/GeronimoTracer.java
new file mode 100644
index 0000000..19f0090
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/GeronimoTracer.java
@@ -0,0 +1,113 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import static java.util.Optional.ofNullable;
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toMap;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Event;
+import javax.inject.Inject;
+import javax.ws.rs.core.MultivaluedMap;
+
+import io.opentracing.Scope;
+import io.opentracing.ScopeManager;
+import io.opentracing.Span;
+import io.opentracing.SpanContext;
+import io.opentracing.Tracer;
+import io.opentracing.propagation.Format;
+import io.opentracing.propagation.TextMap;
+
+@ApplicationScoped
+public class GeronimoTracer implements Tracer {
+
+    @Inject
+    private ScopeManager scopeManager;
+
+    @Inject
+    private IdGenerator idGenerator;
+
+    @Inject
+    private Event<FinishedSpan> finishedSpanEvent;
+
+    @Override
+    public ScopeManager scopeManager() {
+        return scopeManager;
+    }
+
+    @Override
+    public Span activeSpan() {
+        return ofNullable(scopeManager.active()).map(Scope::span).orElse(null);
+    }
+
+    @Override
+    public SpanBuilder buildSpan(final String operationName) {
+        return new SpanBuilderImpl(this, span -> finishedSpanEvent.fire(new FinishedSpan(span)), operationName, idGenerator);
+    }
+
+    @Override
+    public <C> void inject(final SpanContext spanContext, final Format<C> format, final C carrier) {
+        if (!TextMap.class.isInstance(carrier)) {
+            throw new IllegalArgumentException("Only TextMap are supported");
+        }
+        final TextMap textMap = TextMap.class.cast(carrier);
+        final SpanContextImpl context = SpanContextImpl.class.cast(spanContext);
+        textMap.put("traceid", String.valueOf(context.getTraceId()));
+        textMap.put("spanid", String.valueOf(context.getSpanId()));
+        context.getBaggageItems().forEach((k, v) -> textMap.put("baggage-" + k, v));
+    }
+
+    @Override
+    public <C> SpanContext extract(final Format<C> format, final C carrier) {
+        if (HeaderTextMap.class.isInstance(carrier)) {
+            final MultivaluedMap<String, ?> map = HeaderTextMap.class.cast(carrier).getMap();
+            final String traceid = (String) map.getFirst("traceid");
+            final String spanid = (String) map.getFirst("spanid");
+            if (traceid != null && spanid != null) {
+                return new SpanContextImpl(traceid, spanid, map.keySet().stream().filter(it -> it.startsWith("baggage-"))
+                        .collect(toMap(identity(), k -> String.valueOf(map.getFirst(k)))));
+            }
+            return null;
+        }
+        if (!TextMap.class.isInstance(carrier)) {
+            throw new IllegalArgumentException("Only TextMap are supported");
+        }
+        final Iterator<Map.Entry<String, String>> textMap = TextMap.class.cast(carrier).iterator();
+        String traceId = null;
+        String spanId = null;
+        final Map<String, String> baggages = new HashMap<>();
+        while (textMap.hasNext()) {
+            final Map.Entry<String, String> next = textMap.next();
+            if (next.getKey().startsWith("baggage-")) {
+                baggages.put(next.getKey(), next.getValue());
+            } else if ("spanid".equals(next.getKey())) {
+                spanId = next.getValue();
+            } else if ("traceid".equals(next.getKey())) {
+                traceId = next.getValue();
+            }
+        }
+        if (traceId != null && spanId != null) {
+            return new SpanContextImpl(traceId, spanId, baggages);
+        }
+        return null;
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/HeaderTextMap.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/HeaderTextMap.java
new file mode 100644
index 0000000..82b1706
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/HeaderTextMap.java
@@ -0,0 +1,76 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import io.opentracing.propagation.TextMap;
+
+public class HeaderTextMap<T> implements TextMap {
+
+    private final MultivaluedMap<String, T> headers;
+
+    public HeaderTextMap(final MultivaluedMap<String, T> headers) {
+        this.headers = headers;
+    }
+
+    public MultivaluedMap<String, ?> getMap() {
+        return headers;
+    }
+
+    @Override
+    public Iterator<Map.Entry<String, String>> iterator() {
+        final Iterator<String> iterator = headers.keySet().iterator();
+        return new Iterator<Map.Entry<String, String>>() {
+
+            @Override
+            public boolean hasNext() {
+                return iterator.hasNext();
+            }
+
+            @Override
+            public Map.Entry<String, String> next() {
+                final String next = iterator.next();
+                return new Map.Entry<String, String>() {
+
+                    @Override
+                    public String getKey() {
+                        return next;
+                    }
+
+                    @Override
+                    public String getValue() {
+                        return String.valueOf(headers.getFirst(next));
+                    }
+
+                    @Override
+                    public String setValue(final String value) {
+                        throw new UnsupportedOperationException();
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public void put(final String key, final String value) {
+        this.headers.putSingle(key, (T) value);
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/IdGenerator.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/IdGenerator.java
new file mode 100644
index 0000000..9a048c0
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/IdGenerator.java
@@ -0,0 +1,29 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import java.util.UUID;
+
+import javax.enterprise.context.ApplicationScoped;
+
+@ApplicationScoped
+public class IdGenerator {
+
+    public Object next() {
+        return UUID.randomUUID().toString();
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ReferenceImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ReferenceImpl.java
new file mode 100644
index 0000000..b97ee0f
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ReferenceImpl.java
@@ -0,0 +1,37 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+public class ReferenceImpl {
+
+    private final String type;
+
+    private final SpanContextImpl value;
+
+    public ReferenceImpl(final String type, final SpanContextImpl value) {
+        this.type = type;
+        this.value = value;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public SpanContextImpl getValue() {
+        return value;
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeImpl.java
new file mode 100644
index 0000000..8d5851e
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeImpl.java
@@ -0,0 +1,53 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import io.opentracing.Scope;
+import io.opentracing.Span;
+
+public class ScopeImpl implements Scope {
+
+    private final Span span;
+
+    private final boolean finishOnClose;
+
+    private final Runnable onClose;
+
+    public ScopeImpl(final Runnable onClose, final Span span, final boolean finishSpanOnClose) {
+        this.onClose = onClose;
+        this.span = span;
+        this.finishOnClose = finishSpanOnClose;
+    }
+
+    @Override
+    public void close() {
+        try {
+            if (finishOnClose) {
+                span.finish();
+            }
+        } finally {
+            if (onClose != null) {
+                onClose.run();
+            }
+        }
+    }
+
+    @Override
+    public Span span() {
+        return span;
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeManagerImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeManagerImpl.java
new file mode 100644
index 0000000..5f5c36f
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/ScopeManagerImpl.java
@@ -0,0 +1,49 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import javax.enterprise.context.ApplicationScoped;
+
+import io.opentracing.Scope;
+import io.opentracing.ScopeManager;
+import io.opentracing.Span;
+
+@ApplicationScoped
+public class ScopeManagerImpl implements ScopeManager {
+
+    private final ThreadLocal<Scope> current = new ThreadLocal<>();
+
+    @Override
+    public Scope activate(final Span span, final boolean finishSpanOnClose) {
+        final Thread thread = Thread.currentThread();
+        final Scope oldScope = current.get();
+        return new ScopeImpl(() -> {
+            if (Thread.currentThread() == thread) {
+                current.set(oldScope);
+            } // else error?
+        }, span, finishSpanOnClose);
+    }
+
+    @Override
+    public Scope active() {
+        final Scope scope = current.get();
+        if (scope == null) {
+            current.remove();
+        }
+        return scope;
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanBuilderImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanBuilderImpl.java
new file mode 100644
index 0000000..f943540
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanBuilderImpl.java
@@ -0,0 +1,145 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import static java.util.stream.Collectors.toMap;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.stream.StreamSupport;
+
+import io.opentracing.References;
+import io.opentracing.Scope;
+import io.opentracing.Span;
+import io.opentracing.SpanContext;
+import io.opentracing.Tracer;
+
+public class SpanBuilderImpl implements Tracer.SpanBuilder {
+
+    private final Tracer tracer;
+
+    private final Consumer<Span> onFinish;
+
+    private final String operationName;
+
+    private final Collection<ReferenceImpl> references = new ArrayList<>();
+
+    private final Map<String, Object> tags = new HashMap<>();
+
+    private final IdGenerator idGenerator;
+
+    private boolean ignoreActiveSpan;
+
+    private long timestamp = -1;
+
+    public SpanBuilderImpl(final Tracer tracer, final Consumer<Span> onFinish, final String operationName,
+            final IdGenerator idGenerator) {
+        this.tracer = tracer;
+        this.onFinish = onFinish;
+        this.operationName = operationName;
+        this.idGenerator = idGenerator;
+    }
+
+    @Override
+    public Tracer.SpanBuilder asChildOf(final SpanContext parent) {
+        return addReference(References.CHILD_OF, parent);
+    }
+
+    @Override
+    public Tracer.SpanBuilder asChildOf(final Span parent) {
+        if (parent == null) {
+            return this;
+        }
+        return asChildOf(parent.context());
+    }
+
+    @Override
+    public Tracer.SpanBuilder addReference(final String referenceType, final SpanContext referencedContext) {
+        references.add(new ReferenceImpl(referenceType, SpanContextImpl.class.cast(referencedContext)));
+        return this;
+    }
+
+    @Override
+    public Tracer.SpanBuilder ignoreActiveSpan() {
+        this.ignoreActiveSpan = ignoreActiveSpan;
+        return this;
+    }
+
+    @Override
+    public Tracer.SpanBuilder withTag(final String key, final String value) {
+        tags.put(key, value);
+        return this;
+    }
+
+    @Override
+    public Tracer.SpanBuilder withTag(final String key, final boolean value) {
+        tags.put(key, value);
+        return this;
+    }
+
+    @Override
+    public Tracer.SpanBuilder withTag(final String key, final Number value) {
+        tags.put(key, value);
+        return this;
+    }
+
+    @Override
+    public Tracer.SpanBuilder withStartTimestamp(final long microseconds) {
+        this.timestamp = microseconds;
+        return this;
+    }
+
+    @Override
+    public Scope startActive(boolean finishSpanOnClose) {
+        return new ScopeImpl(null, startManual(), finishSpanOnClose);
+    }
+
+    @Override
+    public Span startManual() {
+        if (timestamp < 0) {
+            timestamp = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
+        }
+        if (!ignoreActiveSpan && references.stream().noneMatch(it -> it.getType().equalsIgnoreCase(References.CHILD_OF))) {
+            final Span span = tracer.activeSpan();
+            if (span != null) {
+                addReference(References.CHILD_OF, span.context());
+            }
+        }
+        final ReferenceImpl parent = references.stream().filter(it -> References.CHILD_OF.equals(it.getType())).findFirst()
+                .orElseGet(() -> references.isEmpty() ? null : references.iterator().next());
+        final Map<String, String> baggages = references.stream()
+                .flatMap(r -> StreamSupport.stream(
+                        Spliterators.spliteratorUnknownSize(r.getValue().baggageItems().iterator(), Spliterator.IMMUTABLE),
+                        false))
+                .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
+        return new SpanImpl(operationName, timestamp, references, tags, onFinish,
+                parent == null ? new SpanContextImpl(idGenerator.next(), idGenerator.next(), baggages)
+                        : new SpanContextImpl(parent.getValue().getTraceId(), idGenerator.next(), baggages),
+                parent == null ? null : parent.getValue().getSpanId());
+    }
+
+    @Override
+    public Span start() {
+        return startManual();
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanContextImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanContextImpl.java
new file mode 100644
index 0000000..bc71855
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanContextImpl.java
@@ -0,0 +1,63 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import java.util.Map;
+
+import io.opentracing.SpanContext;
+
+public class SpanContextImpl implements SpanContext {
+
+    private final Object traceId;
+
+    private final Object spanId;
+
+    private final Map<String, String> baggageItems;
+
+    public SpanContextImpl(final Object traceId, final Object spanId, final Map<String, String> baggageItems) {
+        this.traceId = traceId;
+        this.spanId = spanId;
+        this.baggageItems = baggageItems;
+    }
+
+    public Map<String, String> getBaggageItems() {
+        return baggageItems;
+    }
+
+    public Object getTraceId() {
+        return traceId;
+    }
+
+    public Object getSpanId() {
+        return spanId;
+    }
+
+    @Override
+    public Iterable<Map.Entry<String, String>> baggageItems() {
+        return baggageItems.entrySet();
+    }
+
+    @Deprecated // TCK
+    public Object traceId() {
+        return getTraceId();
+    }
+
+    @Deprecated // TCK
+    public Object spanId() {
+        return getSpanId();
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanImpl.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanImpl.java
new file mode 100644
index 0000000..968486b
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/impl/SpanImpl.java
@@ -0,0 +1,189 @@
+/*
+ * 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.geronimo.microprofile.opentracing.impl;
+
+import static java.util.Collections.singletonMap;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+import io.opentracing.Span;
+import io.opentracing.SpanContext;
+
+public class SpanImpl implements Span {
+
+    private final Collection<ReferenceImpl> references;
+
+    private final Map<String, Object> tags;
+
+    private final Consumer<Span> onFinish;
+
+    private final SpanContextImpl context;
+
+    private final long startTimestamp;
+
+    private final Object parentId;
+
+    private String operationName;
+
+    private long finishTimestamp;
+
+    private final Collection<Log> logs = new ArrayList<>();
+
+    public SpanImpl(final String operationName, final long startTimestamp, final Collection<ReferenceImpl> references,
+            final Map<String, Object> tags, final Consumer<Span> onFinish, final SpanContextImpl context, final Object parentId) {
+        this.operationName = operationName;
+        this.startTimestamp = startTimestamp;
+        this.references = references;
+        this.tags = tags;
+        this.context = context;
+        this.parentId = parentId;
+        this.onFinish = onFinish;
+    }
+
+    @Override
+    public Span log(final long timestampMicroseconds, final Map<String, ?> fields) {
+        synchronized (logs) {
+            logs.add(new Log(timestampMicroseconds, fields));
+        }
+        return this;
+    }
+
+    @Override
+    public SpanContext context() {
+        return context;
+    }
+
+    @Override
+    public Span log(final long timestampMicroseconds, final String event) {
+        return log(singletonMap("event", event));
+    }
+
+    @Override
+    public void finish() {
+        finish(TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()));
+    }
+
+    @Override
+    public void finish(final long finishMicros) {
+        finishTimestamp = finishMicros;
+        onFinish.accept(this);
+    }
+
+    @Override
+    public Span setTag(final String key, final String value) {
+        tags.put(key, value);
+        return this;
+    }
+
+    @Override
+    public Span setTag(final String key, final boolean value) {
+        tags.put(key, value);
+        return this;
+    }
+
+    @Override
+    public Span setTag(final String key, final Number value) {
+        tags.put(key, value);
+        return this;
+    }
+
+    @Override
+    public Span log(final Map<String, ?> fields) {
+        return log(startTimestamp, fields);
+    }
+
+    @Override
+    public Span log(final String event) {
+        return log(startTimestamp, event);
+    }
+
+    @Override
+    public Span setBaggageItem(final String key, final String value) {
+        context.getBaggageItems().put(key, value);
+        return this;
+    }
+
+    @Override
+    public String getBaggageItem(final String key) {
+        return context.getBaggageItems().get(key);
+    }
+
+    @Override
+    public Span setOperationName(final String operationName) {
+        this.operationName = operationName;
+        return this;
+    }
+
+    @Deprecated // TCK compat
+    public long startMicros() {
+        return startTimestamp;
+    }
+
+    @Deprecated // TCK compat
+    public long finishMicros() {
+        return finishTimestamp;
+    }
+
+    @Deprecated // TCK compat
+    public String operationName() {
+        return operationName;
+    }
+
+    @Deprecated // TCK compat
+    public Object parentId() {
+        return parentId;
+    }
+
+    @Deprecated // TCK compat
+    public Map<String, Object> tags() {
+        return tags;
+    }
+
+    @Deprecated // TCK compat
+    public Collection<Log> logEntries() {
+        return logs;
+    }
+
+    public static class Log {
+
+        private final long timestampMicros;
+
+        private final Map<String, ?> fields;
+
+        private Log(long timestampMicros, Map<String, ?> fields) {
+            this.timestampMicros = timestampMicros;
+            this.fields = fields;
+        }
+
+        public long getTimestampMicros() {
+            return timestampMicros;
+        }
+
+        public Map<String, ?> getFields() {
+            return fields;
+        }
+
+        @Deprecated // TCK compat
+        public Map<String, ?> fields() {
+            return getFields();
+        }
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/GeronimoClientTracingRegistrarProvider.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/GeronimoClientTracingRegistrarProvider.java
new file mode 100644
index 0000000..309a3dd
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/GeronimoClientTracingRegistrarProvider.java
@@ -0,0 +1,57 @@
+/*
+ * 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.geronimo.microprofile.opentracing.microprofile.client;
+
+import java.util.concurrent.ExecutorService;
+
+import javax.enterprise.inject.spi.CDI;
+import javax.ws.rs.client.ClientBuilder;
+
+import org.eclipse.microprofile.opentracing.ClientTracingRegistrarProvider;
+
+import io.opentracing.Tracer;
+
+public class GeronimoClientTracingRegistrarProvider implements ClientTracingRegistrarProvider {
+
+    private final OpenTracingClientRequestFilter requestFilter;
+
+    private final OpenTracingClientResponseFilter responseFilter;
+
+    private final Tracer tracer;
+
+    public GeronimoClientTracingRegistrarProvider() {
+        final CDI<Object> cdi = CDI.current();
+        requestFilter = cdi.select(OpenTracingClientRequestFilter.class).get();
+        responseFilter = cdi.select(OpenTracingClientResponseFilter.class).get();
+        tracer = cdi.select(Tracer.class).get();
+    }
+
+    @Override
+    public ClientBuilder configure(final ClientBuilder builder) {
+        return builder.register(requestFilter).register(responseFilter);
+    }
+
+    @Override
+    public ClientBuilder configure(final ClientBuilder builder, final ExecutorService executorService) {
+        final ExecutorService executor = wrapExecutor(executorService);
+        return configure(builder).property("executorService" /* cxf */, executor);
+    }
+
+    private ExecutorService wrapExecutor(final ExecutorService executorService) {
+        return new OpenTracingExecutorService(executorService, tracer);
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientRequestFilter.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientRequestFilter.java
new file mode 100644
index 0000000..fb98146
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientRequestFilter.java
@@ -0,0 +1,77 @@
+/*
+ * 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.geronimo.microprofile.opentracing.microprofile.client;
+
+import static io.opentracing.References.CHILD_OF;
+import static java.util.Optional.ofNullable;
+
+import java.util.function.Consumer;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+
+import org.apache.geronimo.microprofile.opentracing.impl.HeaderTextMap;
+
+import io.opentracing.Span;
+import io.opentracing.SpanContext;
+import io.opentracing.Tracer;
+import io.opentracing.propagation.Format;
+import io.opentracing.tag.Tags;
+
+@ApplicationScoped
+public class OpenTracingClientRequestFilter implements ClientRequestFilter {
+
+    @Inject
+    private Tracer tracer;
+
+    @Override
+    public void filter(final ClientRequestContext context) {
+        if (context.getProperty(OpenTracingClientRequestFilter.class.getName()) != null || "true"
+                .equalsIgnoreCase(String.valueOf(context.getProperty("org.apache.geronimo.microprofile.opentracing.skip")))) {
+            return;
+        }
+
+        final Tracer.SpanBuilder builder = tracer.buildSpan(context.getMethod());
+        builder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT);
+
+        ofNullable(SpanContext.class.cast(context.getProperty(CHILD_OF)))
+                .ifPresent(parent -> builder.ignoreActiveSpan().asChildOf(parent));
+
+        final Span span = builder.start();
+        if (span == null) {
+            return;
+        }
+
+        span.setOperationName(context.getUri().getPath());
+        if (!"true".equalsIgnoreCase(
+                String.valueOf(context.getProperty("org.apache.geronimo.microprofile.opentracing.client.skipDefaultSpanTags")))) {
+            Tags.HTTP_METHOD.set(span, context.getMethod());
+            Tags.HTTP_URL.set(span, context.getUri().toASCIIString());
+            Tags.PEER_HOSTNAME.set(span, context.getUri().getHost());
+            Tags.PEER_PORT.set(span, context.getUri().getPort());
+        }
+        // customization point
+        ofNullable(context.getProperty("org.apache.geronimo.microprofile.opentracing.spanConsumer"))
+                .ifPresent(consumer -> Consumer.class.cast(consumer).accept(span));
+
+        tracer.inject(span.context(), Format.Builtin.HTTP_HEADERS, new HeaderTextMap<>(context.getHeaders()));
+        context.setProperty(OpenTracingClientRequestFilter.class.getName(), span);
+
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientResponseFilter.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientResponseFilter.java
new file mode 100644
index 0000000..4f9a528
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingClientResponseFilter.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.geronimo.microprofile.opentracing.microprofile.client;
+
+import static java.util.Optional.ofNullable;
+
+import javax.annotation.Priority;
+import javax.enterprise.context.ApplicationScoped;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+
+import io.opentracing.Span;
+import io.opentracing.tag.Tags;
+
+@ApplicationScoped
+@Priority(Priorities.HEADER_DECORATOR)
+public class OpenTracingClientResponseFilter implements ClientResponseFilter {
+
+    @Override
+    public void filter(final ClientRequestContext req, final ClientResponseContext resp) {
+        ofNullable(req.getProperty(OpenTracingClientRequestFilter.class.getName())).map(Span.class::cast).map(span -> {
+            Tags.HTTP_STATUS.set(span, resp.getStatus());
+            return span;
+        }).ifPresent(Span::finish);
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingExecutorService.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingExecutorService.java
new file mode 100644
index 0000000..37e1059
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/client/OpenTracingExecutorService.java
@@ -0,0 +1,155 @@
+/*
+ * 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.geronimo.microprofile.opentracing.microprofile.client;
+
+import static java.util.stream.Collectors.toList;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import io.opentracing.Span;
+import io.opentracing.Tracer;
+import io.opentracing.tag.Tags;
+
+public class OpenTracingExecutorService implements ExecutorService {
+
+    private final ExecutorService delegate;
+
+    private final Tracer tracer;
+
+    public OpenTracingExecutorService(final ExecutorService executorService, final Tracer tracer) {
+        this.delegate = executorService;
+        this.tracer = tracer;
+    }
+
+    private Span before() {
+        return tracer.activeSpan();
+    }
+
+    private void after(final Span span, final RuntimeException error) {
+        if (span != null && error != null) {
+            Tags.ERROR.set(span, true);
+            if (error.getMessage() != null) {
+                span.setTag("errorMessage", error.getMessage());
+                span.setTag("errorType", error.getClass().getName());
+            }
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        delegate.shutdown();
+    }
+
+    @Override
+    public List<Runnable> shutdownNow() {
+        return delegate.shutdownNow();
+    }
+
+    @Override
+    public boolean isShutdown() {
+        return delegate.isShutdown();
+    }
+
+    @Override
+    public boolean isTerminated() {
+        return delegate.isTerminated();
+    }
+
+    @Override
+    public boolean awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException {
+        return delegate.awaitTermination(timeout, unit);
+    }
+
+    @Override
+    public <T> Future<T> submit(final Callable<T> task) {
+        return delegate.submit(wrap(task));
+    }
+
+    @Override
+    public <T> Future<T> submit(final Runnable task, final T result) {
+        return delegate.submit(wrap(task), result);
+    }
+
+    @Override
+    public Future<?> submit(final Runnable task) {
+        return delegate.submit(wrap(task));
+    }
+
+    @Override
+    public <T> List<Future<T>> invokeAll(final Collection<? extends Callable<T>> tasks) throws InterruptedException {
+        return delegate.invokeAll(tasks.stream().map(this::wrap).collect(toList()));
+    }
+
+    @Override
+    public <T> List<Future<T>> invokeAll(final Collection<? extends Callable<T>> tasks, final long timeout, final TimeUnit unit)
+            throws InterruptedException {
+        return delegate.invokeAll(tasks.stream().map(this::wrap).collect(toList()), timeout, unit);
+    }
+
+    @Override
+    public <T> T invokeAny(final Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
+        return delegate.invokeAny(tasks.stream().map(this::wrap).collect(toList()));
+    }
+
+    @Override
+    public <T> T invokeAny(final Collection<? extends Callable<T>> tasks, final long timeout, final TimeUnit unit)
+            throws InterruptedException, ExecutionException, TimeoutException {
+        return delegate.invokeAny(tasks.stream().map(this::wrap).collect(toList()), timeout, unit);
+    }
+
+    @Override
+    public void execute(final Runnable command) {
+        delegate.execute(wrap(command));
+    }
+
+    private Runnable wrap(final Runnable task) {
+        return () -> {
+            RuntimeException error = null;
+            final Span span = before();
+            try {
+                task.run();
+            } catch (final RuntimeException re) {
+                error = re;
+                throw re;
+            } finally {
+                after(span, error);
+            }
+        };
+    }
+
+    private <T> Callable<T> wrap(final Callable<T> task) {
+        return () -> {
+            RuntimeException error = null;
+            final Span span = before();
+            try {
+                return task.call();
+            } catch (final RuntimeException re) {
+                error = re;
+                throw re;
+            } finally {
+                after(span, error);
+            }
+        };
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/GeronimoOpenTracingFeature.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/GeronimoOpenTracingFeature.java
new file mode 100644
index 0000000..8032163
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/GeronimoOpenTracingFeature.java
@@ -0,0 +1,64 @@
+/*
+ * 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.geronimo.microprofile.opentracing.microprofile.server;
+
+import static java.util.Optional.ofNullable;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.spi.CDI;
+import javax.inject.Inject;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.container.DynamicFeature;
+import javax.ws.rs.container.ResourceInfo;
+import javax.ws.rs.core.FeatureContext;
+import javax.ws.rs.ext.Provider;
+
+import org.eclipse.microprofile.opentracing.Traced;
+
+import io.opentracing.Tracer;
+
+@Provider
+@Dependent
+public class GeronimoOpenTracingFeature implements DynamicFeature {
+
+    @Inject
+    private Tracer tracer;
+
+    @Override
+    public void configure(final ResourceInfo resourceInfo, final FeatureContext context) {
+        if (tracer == null) { // configured instead of scanned
+            tracer = CDI.current().select(Tracer.class).get();
+        }
+
+        final Optional<Traced> traced = ofNullable(ofNullable(resourceInfo.getResourceMethod().getAnnotation(Traced.class))
+                .orElseGet(() -> resourceInfo.getResourceClass().getAnnotation(Traced.class)));
+        if (!traced.map(Traced::value).orElse(true)) {
+            return;
+        }
+
+        final String operationName = traced.map(Traced::operationName).filter(v -> !v.trim().isEmpty())
+                .orElseGet(() -> Stream.of(resourceInfo.getResourceMethod().getAnnotations())
+                        .filter(a -> a.annotationType().isAnnotationPresent(HttpMethod.class)).findFirst()
+                        .map(a -> a.annotationType().getAnnotation(HttpMethod.class).value()).orElse("") + ':'
+                        + resourceInfo.getResourceClass().getName() + "." + resourceInfo.getResourceMethod().getName());
+        context.register(new OpenTracingServerResponseFilter())
+                .register(new OpenTracingServerRequestFilter(operationName, tracer));
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingFilter.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingFilter.java
new file mode 100644
index 0000000..7dc43f2
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingFilter.java
@@ -0,0 +1,87 @@
+package org.apache.geronimo.microprofile.opentracing.microprofile.server;
+
+import static java.util.Optional.ofNullable;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.enterprise.context.Dependent;
+import javax.inject.Inject;
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import io.opentracing.Scope;
+import io.opentracing.Span;
+import io.opentracing.Tracer;
+import io.opentracing.tag.Tags;
+
+@Dependent
+@WebFilter(asyncSupported = true, urlPatterns = "/*")
+public class OpenTracingFilter implements Filter {
+
+    @Inject
+    private Tracer tracer;
+
+    @Override
+    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
+            throws IOException, ServletException {
+        if (!HttpServletRequest.class.isInstance(request)) {
+            chain.doFilter(request, response);
+            return;
+        }
+        try {
+            chain.doFilter(request, response);
+        } catch (final Exception ex) {
+            ofNullable(request.getAttribute(OpenTracingFilter.class.getName())).map(Span.class::cast).ifPresent(span -> {
+                Tags.HTTP_STATUS.set(span, HttpServletResponse.class.cast(response).getStatus());
+                Tags.ERROR.set(span, true);
+                span.log(new HashMap<String, Object>() {
+
+                    {
+                        put("event", Tags.ERROR.getKey());
+                        put("event.object", ex);
+                    }
+                });
+            });
+            throw ex;
+        } finally {
+            ofNullable(tracer.scopeManager().active()).ifPresent(Scope::close);
+            ofNullable(request.getAttribute(OpenTracingFilter.class.getName())).map(Span.class::cast).ifPresent(span -> {
+                if (request.isAsyncStarted()) {
+                    request.getAsyncContext().addListener(new AsyncListener() {
+
+                        @Override
+                        public void onComplete(final AsyncEvent event) {
+                            span.finish();
+                        }
+
+                        @Override
+                        public void onTimeout(final AsyncEvent event) {
+                            // no-op
+                        }
+
+                        @Override
+                        public void onError(final AsyncEvent event) {
+                            // no-op
+                        }
+
+                        @Override
+                        public void onStartAsync(final AsyncEvent event) {
+                            // no-op
+                        }
+                    });
+                } else {
+                    span.finish();
+                }
+            });
+        }
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerRequestFilter.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerRequestFilter.java
new file mode 100644
index 0000000..021ebf0
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerRequestFilter.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.geronimo.microprofile.opentracing.microprofile.server;
+
+import static java.util.Optional.ofNullable;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+
+import org.apache.geronimo.microprofile.opentracing.impl.HeaderTextMap;
+import org.apache.geronimo.microprofile.opentracing.microprofile.client.OpenTracingClientRequestFilter;
+
+import io.opentracing.Span;
+import io.opentracing.Tracer;
+import io.opentracing.propagation.Format;
+import io.opentracing.tag.Tags;
+
+public class OpenTracingServerRequestFilter implements ContainerRequestFilter {
+
+    private final String operationName;
+
+    private final Tracer tracer;
+
+    public OpenTracingServerRequestFilter(final String operationName, final Tracer tracer) {
+        this.operationName = operationName;
+        this.tracer = tracer;
+    }
+
+    @Override
+    public void filter(final ContainerRequestContext context) {
+        if (context.getProperty(OpenTracingClientRequestFilter.class.getName()) != null || "true"
+                .equalsIgnoreCase(String.valueOf(context.getProperty("org.apache.geronimo.microprofile.opentracing.skip")))) {
+            return;
+        }
+
+        final Tracer.SpanBuilder builder = tracer.buildSpan(operationName);
+        builder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER);
+
+        ofNullable(ofNullable(tracer.activeSpan()).map(Span::context)
+                .orElseGet(() -> tracer.extract(Format.Builtin.HTTP_HEADERS, new HeaderTextMap<>(context.getHeaders()))))
+                        .ifPresent(builder::asChildOf);
+
+        final Span span = builder.startActive(false/* filter does */).span();
+        if (span == null) {
+            return;
+        }
+        if (!"true".equalsIgnoreCase(
+                String.valueOf(context.getProperty("org.apache.geronimo.microprofile.opentracing.server.skipDefaultSpanTags")))) {
+            Tags.HTTP_METHOD.set(span, context.getMethod());
+            Tags.HTTP_URL.set(span, context.getUriInfo().getRequestUri().toASCIIString());
+        }
+
+        context.setProperty(OpenTracingFilter.class.getName(), span);
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerResponseFilter.java b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerResponseFilter.java
new file mode 100644
index 0000000..4191497
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/java/org/apache/geronimo/microprofile/opentracing/microprofile/server/OpenTracingServerResponseFilter.java
@@ -0,0 +1,38 @@
+/*
+ * 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.geronimo.microprofile.opentracing.microprofile.server;
+
+import static java.util.Optional.ofNullable;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+
+import io.opentracing.Span;
+import io.opentracing.tag.Tags;
+
+@Priority(Priorities.HEADER_DECORATOR)
+public class OpenTracingServerResponseFilter implements ContainerResponseFilter {
+
+    @Override
+    public void filter(final ContainerRequestContext req, final ContainerResponseContext resp) {
+        ofNullable(req.getProperty(OpenTracingFilter.class.getName())).map(Span.class::cast)
+                .ifPresent(span -> Tags.HTTP_STATUS.set(span, resp.getStatus()));
+    }
+}
diff --git a/geronimo-opentracing-impl/src/main/resources/META-INF/beans.xml b/geronimo-opentracing-impl/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..70dd4a9
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+    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.
+-->
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+        http://xmlns.jcp.org/xml/ns/javaee
+        http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="all"
+       version="2.0">
+  <trim/>
+</beans>
diff --git a/geronimo-opentracing-impl/src/main/resources/META-INF/services/org.eclipse.microprofile.opentracing.ClientTracingRegistrarProvider b/geronimo-opentracing-impl/src/main/resources/META-INF/services/org.eclipse.microprofile.opentracing.ClientTracingRegistrarProvider
new file mode 100644
index 0000000..f0f09c0
--- /dev/null
+++ b/geronimo-opentracing-impl/src/main/resources/META-INF/services/org.eclipse.microprofile.opentracing.ClientTracingRegistrarProvider
@@ -0,0 +1 @@
+org.apache.geronimo.microprofile.opentracing.microprofile.client.GeronimoClientTracingRegistrarProvider
diff --git a/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/LongIdGenerator.java b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/LongIdGenerator.java
new file mode 100644
index 0000000..d4e56c8
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/LongIdGenerator.java
@@ -0,0 +1,35 @@
+/*
+ * 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.geronimo.microprofile.opentracing.tck.setup;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Specializes;
+
+import org.apache.geronimo.microprofile.opentracing.impl.IdGenerator;
+
+@Specializes
+@ApplicationScoped
+public class LongIdGenerator extends IdGenerator {
+
+    private final AtomicLong id = new AtomicLong();
+
+    public Object next() {
+        return id.incrementAndGet();
+    }
+}
diff --git a/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SkipOpentracingApiSetup.java b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SkipOpentracingApiSetup.java
new file mode 100644
index 0000000..788d6a4
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/SkipOpentracingApiSetup.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.geronimo.microprofile.opentracing.tck.setup;
+
+import org.jboss.arquillian.container.spi.event.container.BeforeDeploy;
+import org.jboss.arquillian.core.api.annotation.Observes;
+import org.jboss.arquillian.core.spi.LoadableExtension;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.Filters;
+
+// the tck put the opentracing-api in the war but not our impl, let's fix it by using the apploader api jar!
+public class SkipOpentracingApiSetup implements LoadableExtension {
+
+    @Override
+    public void register(final ExtensionBuilder builder) {
+        builder.observer(Impl.class);
+    }
+
+    public static class Impl {
+
+        public void clean(@Observes final BeforeDeploy beforeDeploy) {
+            final Archive<?> archive = beforeDeploy.getDeployment().getArchive();
+            archive.delete(archive.getContent(Filters.include("\\/WEB-INF\\/lib\\/opentracing\\-api\\-.*\\.jar")).values()
+                    .iterator().next().getPath());
+        }
+    }
+}
diff --git a/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/TckTracer.java b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/TckTracer.java
new file mode 100644
index 0000000..43ffc79
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/java/org/apache/geronimo/microprofile/opentracing/tck/setup/TckTracer.java
@@ -0,0 +1,48 @@
+/*
+ * 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.geronimo.microprofile.opentracing.tck.setup;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Specializes;
+
+import org.apache.geronimo.microprofile.opentracing.impl.FinishedSpan;
+import org.apache.geronimo.microprofile.opentracing.impl.GeronimoTracer;
+
+import io.opentracing.Span;
+
+// compat for TCK, to drop once tcks are fixed - used by reflection!!!!
+@Specializes
+@ApplicationScoped
+public class TckTracer extends GeronimoTracer {
+    private final Collection<Span> spans = new ArrayList<>();
+
+    synchronized void onSpan(@Observes final FinishedSpan span) {
+        spans.add(span.getSpan());
+    }
+
+    public synchronized Iterable<Span> finishedSpans() {
+        return new ArrayList<>(spans);
+    }
+
+    public synchronized void reset() {
+        spans.clear();
+    }
+}
diff --git a/geronimo-opentracing-impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/geronimo-opentracing-impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
new file mode 100644
index 0000000..c34b326
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -0,0 +1 @@
+org.apache.geronimo.microprofile.opentracing.tck.setup.SkipOpentracingApiSetup
diff --git a/geronimo-opentracing-impl/src/test/resources/arquillian.xml b/geronimo-opentracing-impl/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..9d21c97
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/resources/arquillian.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+    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.
+-->
+<arquillian xmlns="http://jboss.org/schema/arquillian"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="
+              http://jboss.org/schema/arquillian
+              http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+  <container qualifier="default" default="true">
+    <configuration>
+      <property name="tempDir">target/meecrowave/temp</property>
+      <property name="jaxrsDefaultProviders">
+        com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider,
+        org.apache.geronimo.microprofile.opentracing.microprofile.server.GeronimoOpenTracingFeature
+      </property>
+      <property name="scanningExcludes">
+        arquillian,
+        bsh,
+        debugger,
+        jackson-,
+        jcommander,
+        microprofile-,
+        opentracing,
+        resteasy
+      </property>
+    </configuration>
+  </container>
+</arquillian>
diff --git a/geronimo-opentracing-impl/src/test/resources/tck-dev.xml b/geronimo-opentracing-impl/src/test/resources/tck-dev.xml
new file mode 100644
index 0000000..cfc75d1
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/resources/tck-dev.xml
@@ -0,0 +1,28 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
+<!--
+    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.
+-->
+<suite name="microprofile-opentracing-TCK" verbose="2" configfailurepolicy="continue">
+  <test name="microprofile-opentracing 1.0 TCK">
+    <classes>
+      <class name="org.eclipse.microprofile.opentracing.tck.OpentracingClientTests">
+        <methods>
+          <include name="testAnnotations" />
+        </methods>
+      </class>
+    </classes>
+  </test>
+</suite>
diff --git a/geronimo-opentracing-impl/src/test/resources/tck.xml b/geronimo-opentracing-impl/src/test/resources/tck.xml
new file mode 100644
index 0000000..bb8dfbd
--- /dev/null
+++ b/geronimo-opentracing-impl/src/test/resources/tck.xml
@@ -0,0 +1,24 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
+<!--
+    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.
+-->
+<suite name="microprofile-opentracing-TCK" verbose="2" configfailurepolicy="continue">
+  <test name="microprofile-opentracing 1.0 TCK">
+    <packages>
+      <package name="org.eclipse.microprofile.opentracing.tck.*"/>
+    </packages>
+  </test>
+</suite>
diff --git a/geronimo-opentracing-spec/pom.xml b/geronimo-opentracing-spec/pom.xml
new file mode 100644
index 0000000..acd05fe
--- /dev/null
+++ b/geronimo-opentracing-spec/pom.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+  <parent>
+    <artifactId>geronimo-opentracing</artifactId>
+    <groupId>org.apache.geronimo</groupId>
+    <version>1.0.1-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>geronimo-opentracing-spec</artifactId>
+  <name>Geronimo OpenTracing :: OpenTracing Spec</name>
+
+  <properties>
+    <geronimo.jpms.name>io.opentracing.api</geronimo.jpms.name>
+  </properties>
+</project>
\ No newline at end of file
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/References.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/References.java
new file mode 100644
index 0000000..1091e19
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/References.java
@@ -0,0 +1,27 @@
+/*
+ * 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 io.opentracing;
+
+public final class References {
+
+    public static final String CHILD_OF = "child_of";
+    public static final String FOLLOWS_FROM = "follows_from";
+
+    private References() {
+        // no-op
+    }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/Scope.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/Scope.java
new file mode 100644
index 0000000..e46a5ed
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/Scope.java
@@ -0,0 +1,36 @@
+/*
+ * 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 io.opentracing;
+
+import java.io.Closeable;
+
+/**
+ * Abstract a span life.
+ */
+public interface Scope extends Closeable {
+
+    /**
+     * remove the span from the manager (active() will not return it anymore).
+     */
+    @Override
+    void close();
+
+    /**
+     * @return the related span.
+     */
+    Span span();
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/ScopeManager.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/ScopeManager.java
new file mode 100644
index 0000000..7aa512a
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/ScopeManager.java
@@ -0,0 +1,33 @@
+/*
+ * 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 io.opentracing;
+
+/**
+ * Abstracts span contextuality.
+ */
+public interface ScopeManager {
+
+    /**
+     * Set the active span.
+     */
+    Scope activate(Span span, boolean finishSpanOnClose);
+
+    /**
+     * @return current active span.
+     */
+    Scope active();
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/Span.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/Span.java
new file mode 100644
index 0000000..14778c6
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/Span.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 io.opentracing;
+
+import java.util.Map;
+
+public interface Span {
+
+    /**
+     * @return the context related to this span.
+     */
+    SpanContext context();
+
+    Span setTag(String key, String value);
+
+    Span setTag(String key, boolean value);
+
+    Span setTag(String key, Number value);
+
+    Span log(Map<String, ?> fields);
+
+    Span log(long timestampMicroseconds, Map<String, ?> fields);
+
+    Span log(String event);
+
+    Span log(long timestampMicroseconds, String event);
+
+    Span setBaggageItem(String key, String value);
+
+    String getBaggageItem(String key);
+
+    Span setOperationName(String operationName);
+
+    void finish();
+
+    void finish(long finishMicros);
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/SpanContext.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/SpanContext.java
new file mode 100644
index 0000000..2210079
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/SpanContext.java
@@ -0,0 +1,27 @@
+/*
+ * 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 io.opentracing;
+
+import java.util.Map;
+
+public interface SpanContext {
+
+    /**
+     * @return baggage items related to current span.
+     */
+    Iterable<Map.Entry<String, String>> baggageItems();
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/Tracer.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/Tracer.java
new file mode 100644
index 0000000..4477984
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/Tracer.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 io.opentracing;
+
+import io.opentracing.propagation.Format;
+
+public interface Tracer {
+
+    /**
+     * @return current {@link ScopeManager}.
+     */
+    ScopeManager scopeManager();
+
+    /**
+     * @return current {@link Span}.
+     */
+    Span activeSpan();
+
+    /**
+     * @return a new span builder.
+     */
+    SpanBuilder buildSpan(String operationName);
+
+    /**
+     * Inject a span context into a carrier.
+     */
+    <C> void inject(SpanContext spanContext, Format<C> format, C carrier);
+
+    /**
+     * @return the span context from the carrier.
+     */
+    <C> SpanContext extract(Format<C> format, C carrier);
+
+    interface SpanBuilder {
+
+        /**
+         * @return this span builder after having added CHILD_OFF reference.
+         */
+        SpanBuilder asChildOf(SpanContext parent);
+
+        /**
+         * @return this span builder after having added CHILD_OFF reference from the parent.
+         */
+        SpanBuilder asChildOf(Span parent);
+
+        /**
+         * @return this span builder after having added a reference.
+         */
+        SpanBuilder addReference(String referenceType, SpanContext referencedContext);
+
+        /**
+         * @return this span builder flag to ignore implicit CHILD_OFF reference.
+         */
+        SpanBuilder ignoreActiveSpan();
+
+        SpanBuilder withTag(String key, String value);
+
+        SpanBuilder withTag(String key, boolean value);
+
+        SpanBuilder withTag(String key, Number value);
+
+        SpanBuilder withStartTimestamp(long microseconds);
+
+        /**
+         * @return a new scope registered in the scope manager.
+         */
+        Scope startActive(boolean finishSpanOnClose);
+
+        /**
+         * @deprecated replaced by {@link #start} and {@link #startActive}.
+         */
+        @Deprecated
+        Span startManual();
+
+        /**
+         * @return a new scope not registered in the manager.
+         */
+        Span start();
+    }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/log/Fields.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/log/Fields.java
new file mode 100644
index 0000000..8be899f
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/log/Fields.java
@@ -0,0 +1,34 @@
+/*
+ * 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 io.opentracing.log;
+
+public final class Fields {
+
+    private Fields() {
+        // no-op
+    }
+
+    public static final String ERROR_KIND = "error.kind";
+
+    public static final String ERROR_OBJECT = "error.object";
+
+    public static final String EVENT = "event";
+
+    public static final String MESSAGE = "message";
+
+    public static final String STACK = "stack";
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/Format.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/Format.java
new file mode 100644
index 0000000..a461c77
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/Format.java
@@ -0,0 +1,45 @@
+/*
+ * 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 io.opentracing.propagation;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Tracer interaction abstraction.
+ */
+public interface Format<C> {
+
+    final class Builtin<C> implements Format<C> {
+
+        public final static Format<TextMap> TEXT_MAP = new Builtin<TextMap>("TEXT_MAP");
+
+        public final static Format<TextMap> HTTP_HEADERS = new Builtin<TextMap>("HTTP_HEADERS");
+
+        public final static Format<ByteBuffer> BINARY = new Builtin<ByteBuffer>("BINARY");
+
+        private final String name;
+
+        private Builtin(final String name) {
+            this.name = name;
+        }
+
+        @Override
+        public String toString() {
+            return Builtin.class.getSimpleName() + "." + name;
+        }
+    }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMap.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMap.java
new file mode 100644
index 0000000..0b26473
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMap.java
@@ -0,0 +1,30 @@
+/*
+ * 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 io.opentracing.propagation;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Default carrier (kind of limited map).
+ */
+public interface TextMap extends Iterable<Map.Entry<String, String>> {
+
+    Iterator<Map.Entry<String, String>> iterator();
+
+    void put(String key, String value);
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapExtractAdapter.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapExtractAdapter.java
new file mode 100644
index 0000000..05a07c7
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapExtractAdapter.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 io.opentracing.propagation;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Read only TextMap adapter from a map.
+ */
+public final class TextMapExtractAdapter implements TextMap {
+
+    private final Map<String, String> map;
+
+    public TextMapExtractAdapter(final Map<String, String> map) {
+        this.map = map;
+    }
+
+    @Override
+    public Iterator<Map.Entry<String, String>> iterator() {
+        return map.entrySet().iterator();
+    }
+
+    @Override
+    public void put(final String key, final String value) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapInjectAdapter.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapInjectAdapter.java
new file mode 100644
index 0000000..e8b611b
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/propagation/TextMapInjectAdapter.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 io.opentracing.propagation;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Write only TextMap adapter from a map.
+ */
+public class TextMapInjectAdapter implements TextMap {
+
+    private final Map<String, String> map;
+
+    public TextMapInjectAdapter(final Map<String, String> map) {
+        this.map = map;
+    }
+
+    @Override
+    public Iterator<Map.Entry<String, String>> iterator() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void put(final String key, final String value) {
+        this.map.put(key, value);
+    }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/AbstractTag.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/AbstractTag.java
new file mode 100644
index 0000000..dcac609
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/AbstractTag.java
@@ -0,0 +1,34 @@
+/*
+ * 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 io.opentracing.tag;
+
+import io.opentracing.Span;
+
+public abstract class AbstractTag<T> {
+
+    protected final String key;
+
+    public AbstractTag(final String tagKey) {
+        this.key = tagKey;
+    }
+
+    protected abstract void set(Span span, T tagValue);
+
+    public String getKey() {
+        return key;
+    }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/BooleanTag.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/BooleanTag.java
new file mode 100644
index 0000000..ac5f788
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/BooleanTag.java
@@ -0,0 +1,31 @@
+/*
+ * 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 io.opentracing.tag;
+
+import io.opentracing.Span;
+
+public class BooleanTag extends AbstractTag<Boolean> {
+
+    public BooleanTag(final String key) {
+        super(key);
+    }
+
+    @Override
+    public void set(final Span span, final Boolean tagValue) {
+        span.setTag(key, tagValue);
+    }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntOrStringTag.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntOrStringTag.java
new file mode 100644
index 0000000..37f712c
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntOrStringTag.java
@@ -0,0 +1,30 @@
+/*
+ * 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 io.opentracing.tag;
+
+import io.opentracing.Span;
+
+public class IntOrStringTag extends IntTag {
+
+    public IntOrStringTag(final String key) {
+        super(key);
+    }
+
+    public void set(final Span span, final String tagValue) {
+        span.setTag(key, tagValue);
+    }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntTag.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntTag.java
new file mode 100644
index 0000000..53c1ede
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/IntTag.java
@@ -0,0 +1,31 @@
+/*
+ * 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 io.opentracing.tag;
+
+import io.opentracing.Span;
+
+public class IntTag extends AbstractTag<Integer> {
+
+    public IntTag(final String key) {
+        super(key);
+    }
+
+    @Override
+    public void set(final Span span, final Integer tagValue) {
+        span.setTag(key, tagValue);
+    }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/StringTag.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/StringTag.java
new file mode 100644
index 0000000..ce2a703
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/StringTag.java
@@ -0,0 +1,31 @@
+/*
+ * 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 io.opentracing.tag;
+
+import io.opentracing.Span;
+
+public class StringTag extends AbstractTag<String> {
+
+    public StringTag(final String key) {
+        super(key);
+    }
+
+    @Override
+    public void set(final Span span, final String tagValue) {
+        span.setTag(key, tagValue);
+    }
+}
diff --git a/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/Tags.java b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/Tags.java
new file mode 100644
index 0000000..f482a38
--- /dev/null
+++ b/geronimo-opentracing-spec/src/main/java/io/opentracing/tag/Tags.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 io.opentracing.tag;
+
+public final class Tags {
+
+    public static final String SPAN_KIND_SERVER = "server";
+    public static final String SPAN_KIND_CLIENT = "client";
+    public static final String SPAN_KIND_PRODUCER = "producer";
+    public static final String SPAN_KIND_CONSUMER = "consumer";
+    public static final StringTag HTTP_URL = new StringTag("http.url");
+    public static final IntTag HTTP_STATUS = new IntTag("http.status_code");
+    public static final StringTag HTTP_METHOD = new StringTag("http.method");
+    public static final IntOrStringTag PEER_HOST_IPV4 = new IntOrStringTag("peer.ipv4");
+    public static final StringTag PEER_HOST_IPV6 = new StringTag("peer.ipv6");
+    public static final StringTag PEER_SERVICE = new StringTag("peer.service");
+    public static final StringTag PEER_HOSTNAME = new StringTag("peer.hostname");
+    public static final IntTag PEER_PORT = new IntTag("peer.port");
+    public static final IntTag SAMPLING_PRIORITY = new IntTag("sampling.priority");
+    public static final StringTag SPAN_KIND = new StringTag("span.kind");
+    public static final StringTag COMPONENT = new StringTag("component");
+    public static final BooleanTag ERROR = new BooleanTag("error");
+    public static final StringTag DB_TYPE = new StringTag("db.type");
+    public static final StringTag DB_INSTANCE = new StringTag("db.instance");
+    public static final StringTag DB_USER = new StringTag("db.user");
+    public static final StringTag DB_STATEMENT = new StringTag("db.statement");
+    public static final StringTag MESSAGE_BUS_DESTINATION = new StringTag("message_bus.destination");
+
+    private Tags() {
+        // no-op
+    }
+}
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..4ff6c7d
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,150 @@
+<?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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache</groupId>
+    <artifactId>apache</artifactId>
+    <version>18</version>
+  </parent>
+
+  <groupId>org.apache.geronimo</groupId>
+  <artifactId>geronimo-opentracing</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <name>Geronimo OpenTracing</name>
+
+  <description>
+    Apache Geronimo implementation of the Microprofile OpenTracing Specification
+  </description>
+
+  <scm>
+    <connection>scm:git:https://gitbox.apache.org/repos/asf/geronimo-opentracing.git</connection>
+    <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/geronimo-opentracing.git</developerConnection>
+    <url>https://gitbox.apache.org/repos/asf/geronimo-opentracing.git</url>
+    <tag>HEAD</tag>
+  </scm>
+
+  <modules>
+    <module>geronimo-microprofile-opentracing-spec</module>
+    <module>geronimo-opentracing-impl</module>
+    <module>geronimo-opentracing-impl</module>
+    <module>geronimo-opentracing-spec</module>
+  </modules>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>tomcat-servlet-api</artifactId>
+      <version>9.0.7</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-jaxrs_2.0_spec</artifactId>
+      <version>1.0-alpha-1</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-json_1.1_spec</artifactId>
+      <version>1.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-interceptor_1.2_spec</artifactId>
+      <version>1.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-atinject_1.0_spec</artifactId>
+      <version>1.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-jcdi_2.0_spec</artifactId>
+      <version>1.0.1</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-annotation_1.3_spec</artifactId>
+      <version>1.0</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.7.0</version>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>3.0.2</version>
+        <configuration>
+          <archive combine.children="append">
+            <manifestEntries>
+              <Automatic-Module-Name>${geronimo.jpms.name}</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+
+  <organization>
+    <name>The Apache Software Foundation</name>
+    <url>http://www.apache.org/</url>
+  </organization>
+
+  <inceptionYear>2017</inceptionYear>
+
+  <licenses>
+    <license>
+      <name>Apache License, Version 2.0</name>
+      <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+
+  <developers>
+    <developer>
+      <name>Apache Geronimo Community</name>
+      <url>https://geronimo.apache.org</url>
+      <organization>Apache</organization>
+    </developer>
+  </developers>
+
+  <issueManagement>
+    <system>ASF JIRA</system>
+    <url>https://issues.apache.org/jira/browse/GERONIMO</url>
+  </issueManagement>
+</project>