// Path: api/src/main/java/io/opencensus/trace/unsafe/ContextHandleUtils.java
// public class ContextHandleUtils {
// 
//   // No instance of this class.
//   private ContextHandleUtils() {}
// 
//   private static final Logger LOGGER = Logger.getLogger(ContextHandleUtils.class.getName());
//   private static final ContextManager CONTEXT_MANAGER =
//       loadContextManager(ContextManager.class.getClassLoader());
// 
//   private static ContextManager loadContextManager(@Nullable ClassLoader classLoader) {
//     try {
//       return Provider.createInstance(
//           Class.forName(
//               "io.opentelemetry.opencensusshim.OpenTelemetryContextManager",
//               /*initialize=*/ true,
//               classLoader),
//           ContextManager.class);
//     } catch (ClassNotFoundException e) {
//       LOGGER.log(
//           Level.FINE,
//           "Couldn't load full implementation for OpenTelemetry context manager, now loading "
//               + "original implementation.",
//           e);
//     }
//     return new ContextManagerImpl();
//   }
// 
//   public static ContextHandle currentContext() {
//     return CONTEXT_MANAGER.currentContext();
//   }
// 
//   /**
//    * Creates a new {@code ContextHandle} with the given value set.
//    *
//    * @param context the parent {@code ContextHandle}.
//    * @param span the value to be set.
//    * @return a new context with the given value set.
//    */
//   public static ContextHandle withValue(
//       ContextHandle context, @javax.annotation.Nullable Span span) {
//     return CONTEXT_MANAGER.withValue(context, span);
//   }
// 
//   /**
//    * Returns the value from the specified {@code ContextHandle}.
//    *
//    * @param context the specified {@code ContextHandle}.
//    * @return the value from the specified {@code ContextHandle}.
//    */
//   public static Span getValue(ContextHandle context) {
//     return CONTEXT_MANAGER.getValue(context);
//   }
// 
//   /**
//    * Attempts to pull the {@link io.grpc.Context} out of an OpenCensus {@code ContextHandle}.
//    *
//    * @return The context, or null if not a GRPC backed context handle.
//    */
//   @Nullable
//   public static Context tryExtractGrpcContext(ContextHandle handle) {
//     if (handle instanceof ContextHandleImpl) {
//       return ((ContextHandleImpl) handle).getContext();
//     }
//     // TODO: see if we can do something for the OpenTelemetry shim.
//     return null;
//   }
// }


import com.google.cloud.ServiceOptions;
import com.google.cloud.logging.LogEntry;
import com.google.cloud.logging.LoggingEnhancer;
import io.opencensus.trace.Span;
import io.opencensus.trace.SpanContext;
import io.opencensus.trace.TraceId;
import io.opencensus.trace.unsafe.ContextHandleUtils;
import java.util.logging.LogManager;
import javax.annotation.Nullable;

  @Nullable
  private static String lookUpProjectId() {
    String projectIdProperty = lookUpProperty(PROJECT_ID_PROPERTY_NAME);
    return projectIdProperty == null || projectIdProperty.isEmpty()
        ? ServiceOptions.getDefaultProjectId()
        : projectIdProperty;
  }

  // An OpenCensusTraceLoggingEnhancer property can be set with a logging property or a system
  // property.
  @Nullable
  private static String lookUpProperty(String name) {
    String property = LogManager.getLogManager().getProperty(name);
    return property == null || property.isEmpty() ? System.getProperty(name) : property;
  }

  // visible for testing
  @Nullable
  String getProjectId() {
    return projectId;
  }

  // This method avoids getting the current span when the feature is disabled, for efficiency.
  @Override
  public void enhanceLogEntry(LogEntry.Builder builder) {
    addTracingData(tracePrefix, getCurrentSpanContext(), builder);
  }

  private static SpanContext getCurrentSpanContext() {
// Path: api/src/main/java/io/opencensus/trace/unsafe/ContextHandleUtils.java
// public class ContextHandleUtils {
// 
//   // No instance of this class.
//   private ContextHandleUtils() {}
// 
//   private static final Logger LOGGER = Logger.getLogger(ContextHandleUtils.class.getName());
//   private static final ContextManager CONTEXT_MANAGER =
//       loadContextManager(ContextManager.class.getClassLoader());
// 
//   private static ContextManager loadContextManager(@Nullable ClassLoader classLoader) {
//     try {
//       return Provider.createInstance(
//           Class.forName(
//               "io.opentelemetry.opencensusshim.OpenTelemetryContextManager",
//               /*initialize=*/ true,
//               classLoader),
//           ContextManager.class);
//     } catch (ClassNotFoundException e) {
//       LOGGER.log(
//           Level.FINE,
//           "Couldn't load full implementation for OpenTelemetry context manager, now loading "
//               + "original implementation.",
//           e);
//     }
//     return new ContextManagerImpl();
//   }
// 
//   public static ContextHandle currentContext() {
//     return CONTEXT_MANAGER.currentContext();
//   }
// 
//   /**
//    * Creates a new {@code ContextHandle} with the given value set.
//    *
//    * @param context the parent {@code ContextHandle}.
//    * @param span the value to be set.
//    * @return a new context with the given value set.
//    */
//   public static ContextHandle withValue(
//       ContextHandle context, @javax.annotation.Nullable Span span) {
//     return CONTEXT_MANAGER.withValue(context, span);
//   }
// 
//   /**
//    * Returns the value from the specified {@code ContextHandle}.
//    *
//    * @param context the specified {@code ContextHandle}.
//    * @return the value from the specified {@code ContextHandle}.
//    */
//   public static Span getValue(ContextHandle context) {
//     return CONTEXT_MANAGER.getValue(context);
//   }
// 
//   /**
//    * Attempts to pull the {@link io.grpc.Context} out of an OpenCensus {@code ContextHandle}.
//    *
//    * @return The context, or null if not a GRPC backed context handle.
//    */
//   @Nullable
//   public static Context tryExtractGrpcContext(ContextHandle handle) {
//     if (handle instanceof ContextHandleImpl) {
//       return ((ContextHandleImpl) handle).getContext();
//     }
//     // TODO: see if we can do something for the OpenTelemetry shim.
//     return null;
//   }
// }


// Path: contrib/log_correlation/stackdriver/src/main/java/io/opencensus/contrib/logcorrelation/stackdriver/OpenCensusTraceLoggingEnhancer.java
import com.google.cloud.ServiceOptions;
import com.google.cloud.logging.LogEntry;
import com.google.cloud.logging.LoggingEnhancer;
import io.opencensus.trace.Span;
import io.opencensus.trace.SpanContext;
import io.opencensus.trace.TraceId;
import io.opencensus.trace.unsafe.ContextHandleUtils;
import java.util.logging.LogManager;
import javax.annotation.Nullable;


  @Nullable
  private static String lookUpProjectId() {
    String projectIdProperty = lookUpProperty(PROJECT_ID_PROPERTY_NAME);
    return projectIdProperty == null || projectIdProperty.isEmpty()
        ? ServiceOptions.getDefaultProjectId()
        : projectIdProperty;
  }

  // An OpenCensusTraceLoggingEnhancer property can be set with a logging property or a system
  // property.
  @Nullable
  private static String lookUpProperty(String name) {
    String property = LogManager.getLogManager().getProperty(name);
    return property == null || property.isEmpty() ? System.getProperty(name) : property;
  }

  // visible for testing
  @Nullable
  String getProjectId() {
    return projectId;
  }

  // This method avoids getting the current span when the feature is disabled, for efficiency.
  @Override
  public void enhanceLogEntry(LogEntry.Builder builder) {
    addTracingData(tracePrefix, getCurrentSpanContext(), builder);
  }

  private static SpanContext getCurrentSpanContext() {
    Span span = ContextHandleUtils.getValue(ContextHandleUtils.currentContext());