// 
// Decompiled by Procyon v0.6.0
// 

package io.sentry;

import io.sentry.clientreport.DiscardReason;
import io.sentry.protocol.SentryTransaction;
import io.sentry.logger.DefaultLoggerBatchProcessorFactory;
import io.sentry.logger.ILoggerBatchProcessorFactory;
import java.net.Proxy;
import io.sentry.protocol.SentryId;
import java.util.HashSet;
import java.util.HashMap;
import io.sentry.util.Platform;
import io.sentry.util.LoadClass;
import io.sentry.util.runtime.NeutralRuntimeManager;
import io.sentry.backpressure.NoOpBackpressureMonitor;
import io.sentry.util.thread.NoOpThreadChecker;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Collection;
import io.sentry.internal.debugmeta.NoOpDebugMetaLoader;
import io.sentry.internal.modules.NoOpModulesLoader;
import io.sentry.clientreport.NoOpClientReportRecorder;
import io.sentry.clientreport.ClientReportRecorder;
import java.util.ArrayList;
import java.util.Iterator;
import io.sentry.cache.PersistingScopeObserver;
import io.sentry.transport.NoOpEnvelopeCache;
import org.jetbrains.annotations.TestOnly;
import io.sentry.transport.NoOpTransportGate;
import io.sentry.util.SampleRateUtils;
import java.io.File;
import io.sentry.util.StringUtils;
import io.sentry.util.runtime.IRuntimeManager;
import io.sentry.util.AutoClosableReentrantLock;
import io.sentry.backpressure.IBackpressureMonitor;
import io.sentry.util.thread.IThreadChecker;
import io.sentry.internal.viewhierarchy.ViewHierarchyExporter;
import io.sentry.internal.gestures.GestureTargetLocator;
import io.sentry.internal.debugmeta.IDebugMetaLoader;
import io.sentry.internal.modules.IModulesLoader;
import io.sentry.clientreport.IClientReportRecorder;
import java.util.Map;
import javax.net.ssl.SSLSocketFactory;
import io.sentry.protocol.SdkVersion;
import io.sentry.cache.IEnvelopeCache;
import io.sentry.transport.ITransportGate;
import io.sentry.util.LazyEvaluator;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.ApiStatus;

public class SentryOptions
{
    @ApiStatus.Internal
    @NotNull
    public static final String DEFAULT_PROPAGATION_TARGETS = ".*";
    static final SentryLevel DEFAULT_DIAGNOSTIC_LEVEL;
    private static final String DEFAULT_ENVIRONMENT = "production";
    @NotNull
    private final List<EventProcessor> eventProcessors;
    @NotNull
    private final Set<Class<? extends Throwable>> ignoredExceptionsForType;
    @Nullable
    private List<FilterString> ignoredErrors;
    @NotNull
    private final List<Integration> integrations;
    @NotNull
    private final Set<String> bundleIds;
    @Nullable
    private String dsn;
    @NotNull
    private final LazyEvaluator<Dsn> parsedDsn;
    @Nullable
    private String dsnHash;
    private long shutdownTimeoutMillis;
    private long flushTimeoutMillis;
    private long sessionFlushTimeoutMillis;
    private boolean debug;
    @NotNull
    private ILogger logger;
    @ApiStatus.Experimental
    @NotNull
    private ILogger fatalLogger;
    @NotNull
    private SentryLevel diagnosticLevel;
    @NotNull
    private final LazyEvaluator<ISerializer> serializer;
    @NotNull
    private final LazyEvaluator<IEnvelopeReader> envelopeReader;
    private int maxDepth;
    @Nullable
    private String sentryClientName;
    @Nullable
    private BeforeSendCallback beforeSend;
    @Nullable
    private BeforeSendCallback beforeSendFeedback;
    @Nullable
    private BeforeSendTransactionCallback beforeSendTransaction;
    @Nullable
    private BeforeSendReplayCallback beforeSendReplay;
    @Nullable
    private BeforeBreadcrumbCallback beforeBreadcrumb;
    @Nullable
    private OnDiscardCallback onDiscard;
    @Nullable
    private String cacheDirPath;
    private int maxCacheItems;
    private int maxQueueSize;
    private int maxBreadcrumbs;
    private int maxFeatureFlags;
    @Nullable
    private String release;
    @Nullable
    private String environment;
    @Nullable
    private Proxy proxy;
    @Nullable
    private Double sampleRate;
    @Nullable
    private Double tracesSampleRate;
    @Nullable
    private TracesSamplerCallback tracesSampler;
    @Nullable
    private volatile TracesSampler internalTracesSampler;
    @NotNull
    private final List<String> inAppExcludes;
    @NotNull
    private final List<String> inAppIncludes;
    @NotNull
    private ITransportFactory transportFactory;
    @NotNull
    private ITransportGate transportGate;
    @Nullable
    private String dist;
    private boolean attachThreads;
    private boolean attachStacktrace;
    private boolean enableAutoSessionTracking;
    private long sessionTrackingIntervalMillis;
    @Nullable
    private String distinctId;
    @Nullable
    private String serverName;
    private boolean attachServerName;
    private boolean enableUncaughtExceptionHandler;
    private boolean printUncaughtStackTrace;
    @NotNull
    private ISentryExecutorService executorService;
    private int connectionTimeoutMillis;
    private int readTimeoutMillis;
    @NotNull
    private IEnvelopeCache envelopeDiskCache;
    @Nullable
    private SdkVersion sdkVersion;
    private boolean sendDefaultPii;
    @Nullable
    private SSLSocketFactory sslSocketFactory;
    @NotNull
    private final List<IScopeObserver> observers;
    @NotNull
    private final List<IOptionsObserver> optionsObservers;
    private boolean enableExternalConfiguration;
    @NotNull
    private final Map<String, String> tags;
    private long maxAttachmentSize;
    private boolean enableDeduplication;
    private boolean enableEventSizeLimiting;
    @Nullable
    private OnOversizedEventCallback onOversizedEvent;
    private int maxSpans;
    private boolean enableShutdownHook;
    @NotNull
    private RequestSize maxRequestBodySize;
    private boolean traceSampling;
    @Nullable
    private Double profilesSampleRate;
    @Nullable
    private ProfilesSamplerCallback profilesSampler;
    private long maxTraceFileSize;
    @NotNull
    private ITransactionProfiler transactionProfiler;
    @NotNull
    private IContinuousProfiler continuousProfiler;
    @NotNull
    private IProfileConverter profilerConverter;
    @Nullable
    private List<String> tracePropagationTargets;
    @NotNull
    private final List<String> defaultTracePropagationTargets;
    private boolean propagateTraceparent;
    @Nullable
    private String proguardUuid;
    @Nullable
    private Long idleTimeout;
    @NotNull
    private final List<String> contextTags;
    private boolean sendClientReports;
    @NotNull
    IClientReportRecorder clientReportRecorder;
    @NotNull
    private IModulesLoader modulesLoader;
    @NotNull
    private IDebugMetaLoader debugMetaLoader;
    private boolean enableUserInteractionTracing;
    private boolean enableUserInteractionBreadcrumbs;
    @NotNull
    private Instrumenter instrumenter;
    @NotNull
    private final List<GestureTargetLocator> gestureTargetLocators;
    @NotNull
    private final List<ViewHierarchyExporter> viewHierarchyExporters;
    @NotNull
    private IThreadChecker threadChecker;
    private boolean traceOptionsRequests;
    @ApiStatus.Internal
    @NotNull
    private final LazyEvaluator<SentryDateProvider> dateProvider;
    @NotNull
    private final List<IPerformanceCollector> performanceCollectors;
    @NotNull
    private CompositePerformanceCollector compositePerformanceCollector;
    private boolean enableTimeToFullDisplayTracing;
    @NotNull
    private FullyDisplayedReporter fullyDisplayedReporter;
    @NotNull
    private IConnectionStatusProvider connectionStatusProvider;
    private boolean enabled;
    private boolean enablePrettySerializationOutput;
    private boolean sendModules;
    @Nullable
    private BeforeEnvelopeCallback beforeEnvelopeCallback;
    private boolean enableSpotlight;
    @Nullable
    private String spotlightConnectionUrl;
    private boolean enableScopePersistence;
    @ApiStatus.Experimental
    @Nullable
    private List<FilterString> ignoredCheckIns;
    @ApiStatus.Experimental
    @Nullable
    private List<FilterString> ignoredSpanOrigins;
    @Nullable
    private List<FilterString> ignoredTransactions;
    @ApiStatus.Experimental
    @NotNull
    private IBackpressureMonitor backpressureMonitor;
    private boolean enableBackpressureHandling;
    private boolean enableAppStartProfiling;
    @NotNull
    private ISpanFactory spanFactory;
    private int profilingTracesHz;
    @ApiStatus.Experimental
    @Nullable
    private Cron cron;
    @NotNull
    private final ExperimentalOptions experimental;
    @NotNull
    private ReplayController replayController;
    @NotNull
    private IDistributionApi distributionController;
    @ApiStatus.Experimental
    private boolean enableScreenTracking;
    @NotNull
    private ScopeType defaultScopeType;
    @NotNull
    private InitPriority initPriority;
    private boolean forceInit;
    @Nullable
    private Boolean globalHubMode;
    @NotNull
    protected final AutoClosableReentrantLock lock;
    @NotNull
    private SentryOpenTelemetryMode openTelemetryMode;
    @NotNull
    private SentryReplayOptions sessionReplay;
    @NotNull
    private SentryFeedbackOptions feedbackOptions;
    @ApiStatus.Experimental
    private boolean captureOpenTelemetryEvents;
    @NotNull
    private IVersionDetector versionDetector;
    @Nullable
    private Double profileSessionSampleRate;
    @NotNull
    private ProfileLifecycle profileLifecycle;
    private boolean startProfilerOnAppStart;
    private long deadlineTimeout;
    @NotNull
    private Logs logs;
    @NotNull
    private ISocketTagger socketTagger;
    @NotNull
    private IRuntimeManager runtimeManager;
    @Nullable
    private String profilingTracesDirPath;
    @NotNull
    private DistributionOptions distribution;
    
    @NotNull
    public IProfileConverter getProfilerConverter() {
        return this.profilerConverter;
    }
    
    public void setProfilerConverter(@NotNull final IProfileConverter profilerConverter) {
        this.profilerConverter = profilerConverter;
    }
    
    public void addEventProcessor(@NotNull final EventProcessor eventProcessor) {
        this.eventProcessors.add(eventProcessor);
    }
    
    @NotNull
    public List<EventProcessor> getEventProcessors() {
        return this.eventProcessors;
    }
    
    public void addIntegration(@NotNull final Integration integration) {
        this.integrations.add(integration);
    }
    
    @NotNull
    public List<Integration> getIntegrations() {
        return this.integrations;
    }
    
    @Nullable
    public String getDsn() {
        return this.dsn;
    }
    
    @ApiStatus.Internal
    @NotNull
    Dsn retrieveParsedDsn() throws IllegalArgumentException {
        return this.parsedDsn.getValue();
    }
    
    public void setDsn(@Nullable final String dsn) {
        this.dsn = dsn;
        this.parsedDsn.resetValue();
        this.dsnHash = StringUtils.calculateStringHash(this.dsn, this.logger);
    }
    
    public boolean isDebug() {
        return this.debug;
    }
    
    public void setDebug(final boolean debug) {
        this.debug = debug;
    }
    
    @NotNull
    public ILogger getLogger() {
        return this.logger;
    }
    
    public void setLogger(@Nullable final ILogger logger) {
        this.logger = ((logger == null) ? NoOpLogger.getInstance() : new DiagnosticLogger(this, logger));
    }
    
    @ApiStatus.Experimental
    @NotNull
    public ILogger getFatalLogger() {
        return this.fatalLogger;
    }
    
    @ApiStatus.Experimental
    public void setFatalLogger(@Nullable final ILogger logger) {
        this.fatalLogger = ((logger == null) ? NoOpLogger.getInstance() : logger);
    }
    
    @NotNull
    public SentryLevel getDiagnosticLevel() {
        return this.diagnosticLevel;
    }
    
    public void setDiagnosticLevel(@Nullable final SentryLevel diagnosticLevel) {
        this.diagnosticLevel = ((diagnosticLevel != null) ? diagnosticLevel : SentryOptions.DEFAULT_DIAGNOSTIC_LEVEL);
    }
    
    @NotNull
    public ISerializer getSerializer() {
        return this.serializer.getValue();
    }
    
    public void setSerializer(@Nullable final ISerializer serializer) {
        this.serializer.setValue((serializer != null) ? serializer : NoOpSerializer.getInstance());
    }
    
    public int getMaxDepth() {
        return this.maxDepth;
    }
    
    public void setMaxDepth(final int maxDepth) {
        this.maxDepth = maxDepth;
    }
    
    @NotNull
    public IEnvelopeReader getEnvelopeReader() {
        return this.envelopeReader.getValue();
    }
    
    public void setEnvelopeReader(@Nullable final IEnvelopeReader envelopeReader) {
        this.envelopeReader.setValue((envelopeReader != null) ? envelopeReader : NoOpEnvelopeReader.getInstance());
    }
    
    public long getShutdownTimeoutMillis() {
        return this.shutdownTimeoutMillis;
    }
    
    public void setShutdownTimeoutMillis(final long shutdownTimeoutMillis) {
        this.shutdownTimeoutMillis = shutdownTimeoutMillis;
    }
    
    @Nullable
    public String getSentryClientName() {
        return this.sentryClientName;
    }
    
    public void setSentryClientName(@Nullable final String sentryClientName) {
        this.sentryClientName = sentryClientName;
    }
    
    @Nullable
    public BeforeSendCallback getBeforeSend() {
        return this.beforeSend;
    }
    
    public void setBeforeSend(@Nullable final BeforeSendCallback beforeSend) {
        this.beforeSend = beforeSend;
    }
    
    @Nullable
    public BeforeSendTransactionCallback getBeforeSendTransaction() {
        return this.beforeSendTransaction;
    }
    
    public void setBeforeSendTransaction(@Nullable final BeforeSendTransactionCallback beforeSendTransaction) {
        this.beforeSendTransaction = beforeSendTransaction;
    }
    
    @Nullable
    public BeforeSendCallback getBeforeSendFeedback() {
        return this.beforeSendFeedback;
    }
    
    public void setBeforeSendFeedback(@Nullable final BeforeSendCallback beforeSendFeedback) {
        this.beforeSendFeedback = beforeSendFeedback;
    }
    
    @Nullable
    public BeforeSendReplayCallback getBeforeSendReplay() {
        return this.beforeSendReplay;
    }
    
    public void setBeforeSendReplay(@Nullable final BeforeSendReplayCallback beforeSendReplay) {
        this.beforeSendReplay = beforeSendReplay;
    }
    
    @Nullable
    public BeforeBreadcrumbCallback getBeforeBreadcrumb() {
        return this.beforeBreadcrumb;
    }
    
    public void setBeforeBreadcrumb(@Nullable final BeforeBreadcrumbCallback beforeBreadcrumb) {
        this.beforeBreadcrumb = beforeBreadcrumb;
    }
    
    @Nullable
    public OnDiscardCallback getOnDiscard() {
        return this.onDiscard;
    }
    
    public void setOnDiscard(@Nullable final OnDiscardCallback onDiscard) {
        this.onDiscard = onDiscard;
    }
    
    @Nullable
    public String getCacheDirPath() {
        if (this.cacheDirPath == null || this.cacheDirPath.isEmpty()) {
            return null;
        }
        return (this.dsnHash != null) ? new File(this.cacheDirPath, this.dsnHash).getAbsolutePath() : this.cacheDirPath;
    }
    
    @Nullable
    String getCacheDirPathWithoutDsn() {
        if (this.cacheDirPath == null || this.cacheDirPath.isEmpty()) {
            return null;
        }
        return this.cacheDirPath;
    }
    
    @Nullable
    public String getOutboxPath() {
        final String cacheDirPath = this.getCacheDirPath();
        if (cacheDirPath == null) {
            return null;
        }
        return new File(cacheDirPath, "outbox").getAbsolutePath();
    }
    
    public void setCacheDirPath(@Nullable final String cacheDirPath) {
        this.cacheDirPath = cacheDirPath;
    }
    
    public int getMaxBreadcrumbs() {
        return this.maxBreadcrumbs;
    }
    
    public void setMaxBreadcrumbs(final int maxBreadcrumbs) {
        this.maxBreadcrumbs = maxBreadcrumbs;
    }
    
    public int getMaxFeatureFlags() {
        return this.maxFeatureFlags;
    }
    
    public void setMaxFeatureFlags(final int maxFeatureFlags) {
        this.maxFeatureFlags = maxFeatureFlags;
    }
    
    @Nullable
    public String getRelease() {
        return this.release;
    }
    
    public void setRelease(@Nullable final String release) {
        this.release = release;
    }
    
    @Nullable
    public String getEnvironment() {
        return (this.environment != null) ? this.environment : "production";
    }
    
    public void setEnvironment(@Nullable final String environment) {
        this.environment = environment;
    }
    
    @Nullable
    public Proxy getProxy() {
        return this.proxy;
    }
    
    public void setProxy(@Nullable final Proxy proxy) {
        this.proxy = proxy;
    }
    
    @Nullable
    public Double getSampleRate() {
        return this.sampleRate;
    }
    
    public void setSampleRate(@Nullable final Double sampleRate) {
        if (!SampleRateUtils.isValidSampleRate(sampleRate)) {
            throw new IllegalArgumentException("The value " + sampleRate + " is not valid. Use null to disable or values >= 0.0 and <= 1.0.");
        }
        this.sampleRate = sampleRate;
    }
    
    @Nullable
    public Double getTracesSampleRate() {
        return this.tracesSampleRate;
    }
    
    public void setTracesSampleRate(@Nullable final Double tracesSampleRate) {
        if (!SampleRateUtils.isValidTracesSampleRate(tracesSampleRate)) {
            throw new IllegalArgumentException("The value " + tracesSampleRate + " is not valid. Use null to disable or values between 0.0 and 1.0.");
        }
        this.tracesSampleRate = tracesSampleRate;
    }
    
    @Nullable
    public TracesSamplerCallback getTracesSampler() {
        return this.tracesSampler;
    }
    
    public void setTracesSampler(@Nullable final TracesSamplerCallback tracesSampler) {
        this.tracesSampler = tracesSampler;
    }
    
    @ApiStatus.Internal
    @NotNull
    public TracesSampler getInternalTracesSampler() {
        if (this.internalTracesSampler == null) {
            try (final ISentryLifecycleToken ignored = this.lock.acquire()) {
                if (this.internalTracesSampler == null) {
                    this.internalTracesSampler = new TracesSampler(this);
                }
            }
        }
        return this.internalTracesSampler;
    }
    
    @NotNull
    public List<String> getInAppExcludes() {
        return this.inAppExcludes;
    }
    
    public void addInAppExclude(@NotNull final String exclude) {
        this.inAppExcludes.add(exclude);
    }
    
    @NotNull
    public List<String> getInAppIncludes() {
        return this.inAppIncludes;
    }
    
    public void addInAppInclude(@NotNull final String include) {
        this.inAppIncludes.add(include);
    }
    
    @NotNull
    public ITransportFactory getTransportFactory() {
        return this.transportFactory;
    }
    
    public void setTransportFactory(@Nullable final ITransportFactory transportFactory) {
        this.transportFactory = ((transportFactory != null) ? transportFactory : NoOpTransportFactory.getInstance());
    }
    
    @Nullable
    public String getDist() {
        return this.dist;
    }
    
    public void setDist(@Nullable final String dist) {
        this.dist = dist;
    }
    
    @NotNull
    public ITransportGate getTransportGate() {
        return this.transportGate;
    }
    
    public void setTransportGate(@Nullable final ITransportGate transportGate) {
        this.transportGate = ((transportGate != null) ? transportGate : NoOpTransportGate.getInstance());
    }
    
    public boolean isAttachStacktrace() {
        return this.attachStacktrace;
    }
    
    public void setAttachStacktrace(final boolean attachStacktrace) {
        this.attachStacktrace = attachStacktrace;
    }
    
    public boolean isAttachThreads() {
        return this.attachThreads;
    }
    
    public void setAttachThreads(final boolean attachThreads) {
        this.attachThreads = attachThreads;
    }
    
    public boolean isEnableAutoSessionTracking() {
        return this.enableAutoSessionTracking;
    }
    
    public void setEnableAutoSessionTracking(final boolean enableAutoSessionTracking) {
        this.enableAutoSessionTracking = enableAutoSessionTracking;
    }
    
    @Nullable
    public String getServerName() {
        return this.serverName;
    }
    
    public void setServerName(@Nullable final String serverName) {
        this.serverName = serverName;
    }
    
    public boolean isAttachServerName() {
        return this.attachServerName;
    }
    
    public void setAttachServerName(final boolean attachServerName) {
        this.attachServerName = attachServerName;
    }
    
    public long getSessionTrackingIntervalMillis() {
        return this.sessionTrackingIntervalMillis;
    }
    
    public void setSessionTrackingIntervalMillis(final long sessionTrackingIntervalMillis) {
        this.sessionTrackingIntervalMillis = sessionTrackingIntervalMillis;
    }
    
    @Nullable
    public String getDistinctId() {
        return this.distinctId;
    }
    
    public void setDistinctId(@Nullable final String distinctId) {
        this.distinctId = distinctId;
    }
    
    public long getFlushTimeoutMillis() {
        return this.flushTimeoutMillis;
    }
    
    public void setFlushTimeoutMillis(final long flushTimeoutMillis) {
        this.flushTimeoutMillis = flushTimeoutMillis;
    }
    
    public boolean isEnableUncaughtExceptionHandler() {
        return this.enableUncaughtExceptionHandler;
    }
    
    public void setEnableUncaughtExceptionHandler(final boolean enableUncaughtExceptionHandler) {
        this.enableUncaughtExceptionHandler = enableUncaughtExceptionHandler;
    }
    
    public boolean isPrintUncaughtStackTrace() {
        return this.printUncaughtStackTrace;
    }
    
    public void setPrintUncaughtStackTrace(final boolean printUncaughtStackTrace) {
        this.printUncaughtStackTrace = printUncaughtStackTrace;
    }
    
    @ApiStatus.Internal
    @NotNull
    public ISentryExecutorService getExecutorService() {
        return this.executorService;
    }
    
    @ApiStatus.Internal
    @TestOnly
    public void setExecutorService(@NotNull final ISentryExecutorService executorService) {
        if (executorService != null) {
            this.executorService = executorService;
        }
    }
    
    public int getConnectionTimeoutMillis() {
        return this.connectionTimeoutMillis;
    }
    
    public void setConnectionTimeoutMillis(final int connectionTimeoutMillis) {
        this.connectionTimeoutMillis = connectionTimeoutMillis;
    }
    
    public int getReadTimeoutMillis() {
        return this.readTimeoutMillis;
    }
    
    public void setReadTimeoutMillis(final int readTimeoutMillis) {
        this.readTimeoutMillis = readTimeoutMillis;
    }
    
    @NotNull
    public IEnvelopeCache getEnvelopeDiskCache() {
        return this.envelopeDiskCache;
    }
    
    public void setEnvelopeDiskCache(@Nullable final IEnvelopeCache envelopeDiskCache) {
        this.envelopeDiskCache = ((envelopeDiskCache != null) ? envelopeDiskCache : NoOpEnvelopeCache.getInstance());
    }
    
    public int getMaxQueueSize() {
        return this.maxQueueSize;
    }
    
    public void setMaxQueueSize(final int maxQueueSize) {
        if (maxQueueSize > 0) {
            this.maxQueueSize = maxQueueSize;
        }
    }
    
    @Nullable
    public SdkVersion getSdkVersion() {
        return this.sdkVersion;
    }
    
    @Nullable
    public SSLSocketFactory getSslSocketFactory() {
        return this.sslSocketFactory;
    }
    
    public void setSslSocketFactory(@Nullable final SSLSocketFactory sslSocketFactory) {
        this.sslSocketFactory = sslSocketFactory;
    }
    
    @ApiStatus.Internal
    public void setSdkVersion(@Nullable final SdkVersion sdkVersion) {
        final SdkVersion replaySdkVersion = this.getSessionReplay().getSdkVersion();
        if (this.sdkVersion != null && replaySdkVersion != null && this.sdkVersion.equals(replaySdkVersion)) {
            this.getSessionReplay().setSdkVersion(sdkVersion);
        }
        this.sdkVersion = sdkVersion;
    }
    
    public boolean isSendDefaultPii() {
        return this.sendDefaultPii;
    }
    
    public void setSendDefaultPii(final boolean sendDefaultPii) {
        this.sendDefaultPii = sendDefaultPii;
    }
    
    public void addScopeObserver(@NotNull final IScopeObserver observer) {
        this.observers.add(observer);
    }
    
    @NotNull
    public List<IScopeObserver> getScopeObservers() {
        return this.observers;
    }
    
    @ApiStatus.Internal
    @Nullable
    public PersistingScopeObserver findPersistingScopeObserver() {
        for (final IScopeObserver observer : this.observers) {
            if (observer instanceof PersistingScopeObserver) {
                return (PersistingScopeObserver)observer;
            }
        }
        return null;
    }
    
    public void addOptionsObserver(@NotNull final IOptionsObserver observer) {
        this.optionsObservers.add(observer);
    }
    
    @NotNull
    public List<IOptionsObserver> getOptionsObservers() {
        return this.optionsObservers;
    }
    
    public boolean isEnableExternalConfiguration() {
        return this.enableExternalConfiguration;
    }
    
    public void setEnableExternalConfiguration(final boolean enableExternalConfiguration) {
        this.enableExternalConfiguration = enableExternalConfiguration;
    }
    
    @NotNull
    public Map<String, String> getTags() {
        return this.tags;
    }
    
    public void setTag(@Nullable final String key, @Nullable final String value) {
        if (key == null) {
            return;
        }
        if (value == null) {
            this.tags.remove(key);
        }
        else {
            this.tags.put(key, value);
        }
    }
    
    public long getMaxAttachmentSize() {
        return this.maxAttachmentSize;
    }
    
    public void setMaxAttachmentSize(final long maxAttachmentSize) {
        this.maxAttachmentSize = maxAttachmentSize;
    }
    
    public boolean isEnableDeduplication() {
        return this.enableDeduplication;
    }
    
    public void setEnableDeduplication(final boolean enableDeduplication) {
        this.enableDeduplication = enableDeduplication;
    }
    
    public boolean isEnableEventSizeLimiting() {
        return this.enableEventSizeLimiting;
    }
    
    public void setEnableEventSizeLimiting(final boolean enableEventSizeLimiting) {
        this.enableEventSizeLimiting = enableEventSizeLimiting;
    }
    
    @Nullable
    public OnOversizedEventCallback getOnOversizedEvent() {
        return this.onOversizedEvent;
    }
    
    public void setOnOversizedEvent(@Nullable final OnOversizedEventCallback onOversizedEvent) {
        this.onOversizedEvent = onOversizedEvent;
    }
    
    public boolean isTracingEnabled() {
        return this.getTracesSampleRate() != null || this.getTracesSampler() != null;
    }
    
    @NotNull
    public Set<Class<? extends Throwable>> getIgnoredExceptionsForType() {
        return this.ignoredExceptionsForType;
    }
    
    public void addIgnoredExceptionForType(@NotNull final Class<? extends Throwable> exceptionType) {
        this.ignoredExceptionsForType.add(exceptionType);
    }
    
    boolean containsIgnoredExceptionForType(@NotNull final Throwable throwable) {
        return this.ignoredExceptionsForType.contains(throwable.getClass());
    }
    
    @Nullable
    public List<FilterString> getIgnoredErrors() {
        return this.ignoredErrors;
    }
    
    public void setIgnoredErrors(@Nullable final List<String> ignoredErrors) {
        if (ignoredErrors == null) {
            this.ignoredErrors = null;
        }
        else {
            final List<FilterString> patterns = new ArrayList<FilterString>();
            for (final String pattern : ignoredErrors) {
                if (pattern != null && !pattern.isEmpty()) {
                    patterns.add(new FilterString(pattern));
                }
            }
            this.ignoredErrors = patterns;
        }
    }
    
    public void addIgnoredError(@NotNull final String pattern) {
        if (this.ignoredErrors == null) {
            this.ignoredErrors = new ArrayList<FilterString>();
        }
        this.ignoredErrors.add(new FilterString(pattern));
    }
    
    @ApiStatus.Experimental
    public int getMaxSpans() {
        return this.maxSpans;
    }
    
    @ApiStatus.Experimental
    public void setMaxSpans(final int maxSpans) {
        this.maxSpans = maxSpans;
    }
    
    public boolean isEnableShutdownHook() {
        return this.enableShutdownHook;
    }
    
    public void setEnableShutdownHook(final boolean enableShutdownHook) {
        this.enableShutdownHook = enableShutdownHook;
    }
    
    public int getMaxCacheItems() {
        return this.maxCacheItems;
    }
    
    public void setMaxCacheItems(final int maxCacheItems) {
        this.maxCacheItems = maxCacheItems;
    }
    
    @NotNull
    public RequestSize getMaxRequestBodySize() {
        return this.maxRequestBodySize;
    }
    
    public void setMaxRequestBodySize(@NotNull final RequestSize maxRequestBodySize) {
        this.maxRequestBodySize = maxRequestBodySize;
    }
    
    @ApiStatus.Experimental
    public boolean isTraceSampling() {
        return this.traceSampling;
    }
    
    @Deprecated
    public void setTraceSampling(final boolean traceSampling) {
        this.traceSampling = traceSampling;
    }
    
    public long getMaxTraceFileSize() {
        return this.maxTraceFileSize;
    }
    
    public void setMaxTraceFileSize(final long maxTraceFileSize) {
        this.maxTraceFileSize = maxTraceFileSize;
    }
    
    @NotNull
    public ITransactionProfiler getTransactionProfiler() {
        return this.transactionProfiler;
    }
    
    public void setTransactionProfiler(@Nullable final ITransactionProfiler transactionProfiler) {
        if (this.transactionProfiler == NoOpTransactionProfiler.getInstance() && transactionProfiler != null) {
            this.transactionProfiler = transactionProfiler;
        }
    }
    
    @NotNull
    public IContinuousProfiler getContinuousProfiler() {
        return this.continuousProfiler;
    }
    
    public void setContinuousProfiler(@Nullable final IContinuousProfiler continuousProfiler) {
        if (this.continuousProfiler == NoOpContinuousProfiler.getInstance() && continuousProfiler != null) {
            this.continuousProfiler = continuousProfiler;
        }
    }
    
    public boolean isProfilingEnabled() {
        return (this.profilesSampleRate != null && this.profilesSampleRate > 0.0) || this.profilesSampler != null;
    }
    
    @ApiStatus.Internal
    public boolean isContinuousProfilingEnabled() {
        return this.profilesSampleRate == null && this.profilesSampler == null && this.profileSessionSampleRate != null && this.profileSessionSampleRate > 0.0;
    }
    
    @Nullable
    public ProfilesSamplerCallback getProfilesSampler() {
        return this.profilesSampler;
    }
    
    public void setProfilesSampler(@Nullable final ProfilesSamplerCallback profilesSampler) {
        this.profilesSampler = profilesSampler;
    }
    
    @Nullable
    public Double getProfilesSampleRate() {
        return this.profilesSampleRate;
    }
    
    public void setProfilesSampleRate(@Nullable final Double profilesSampleRate) {
        if (!SampleRateUtils.isValidProfilesSampleRate(profilesSampleRate)) {
            throw new IllegalArgumentException("The value " + profilesSampleRate + " is not valid. Use null to disable or values between 0.0 and 1.0.");
        }
        this.profilesSampleRate = profilesSampleRate;
    }
    
    @Nullable
    public Double getProfileSessionSampleRate() {
        return this.profileSessionSampleRate;
    }
    
    public void setProfileSessionSampleRate(@Nullable final Double profileSessionSampleRate) {
        if (!SampleRateUtils.isValidContinuousProfilesSampleRate(profileSessionSampleRate)) {
            throw new IllegalArgumentException("The value " + profileSessionSampleRate + " is not valid. Use values between 0.0 and 1.0.");
        }
        this.profileSessionSampleRate = profileSessionSampleRate;
    }
    
    @NotNull
    public ProfileLifecycle getProfileLifecycle() {
        return this.profileLifecycle;
    }
    
    public void setProfileLifecycle(@NotNull final ProfileLifecycle profileLifecycle) {
        this.profileLifecycle = profileLifecycle;
        if (profileLifecycle == ProfileLifecycle.TRACE && !this.isTracingEnabled()) {
            this.logger.log(SentryLevel.WARNING, "Profiling lifecycle is set to TRACE but tracing is disabled. Profiling will not be started automatically.", new Object[0]);
        }
    }
    
    public boolean isStartProfilerOnAppStart() {
        return this.startProfilerOnAppStart;
    }
    
    public void setStartProfilerOnAppStart(final boolean startProfilerOnAppStart) {
        this.startProfilerOnAppStart = startProfilerOnAppStart;
    }
    
    public long getDeadlineTimeout() {
        return this.deadlineTimeout;
    }
    
    public void setDeadlineTimeout(final long deadlineTimeout) {
        this.deadlineTimeout = deadlineTimeout;
    }
    
    @Nullable
    public String getProfilingTracesDirPath() {
        if (this.profilingTracesDirPath != null && !this.profilingTracesDirPath.isEmpty()) {
            return (this.dsnHash != null) ? new File(this.profilingTracesDirPath, this.dsnHash).getAbsolutePath() : this.profilingTracesDirPath;
        }
        final String cacheDirPath = this.getCacheDirPath();
        if (cacheDirPath == null) {
            return null;
        }
        return new File(cacheDirPath, "profiling_traces").getAbsolutePath();
    }
    
    public void setProfilingTracesDirPath(@Nullable final String profilingTracesDirPath) {
        this.profilingTracesDirPath = profilingTracesDirPath;
    }
    
    @NotNull
    public List<String> getTracePropagationTargets() {
        if (this.tracePropagationTargets == null) {
            return this.defaultTracePropagationTargets;
        }
        return this.tracePropagationTargets;
    }
    
    public void setTracePropagationTargets(@Nullable final List<String> tracePropagationTargets) {
        if (tracePropagationTargets == null) {
            this.tracePropagationTargets = null;
        }
        else {
            final List<String> filteredTracePropagationTargets = new ArrayList<String>();
            for (final String target : tracePropagationTargets) {
                if (!target.isEmpty()) {
                    filteredTracePropagationTargets.add(target);
                }
            }
            this.tracePropagationTargets = filteredTracePropagationTargets;
        }
    }
    
    public boolean isPropagateTraceparent() {
        return this.propagateTraceparent;
    }
    
    public void setPropagateTraceparent(final boolean propagateTraceparent) {
        this.propagateTraceparent = propagateTraceparent;
    }
    
    @Nullable
    public String getProguardUuid() {
        return this.proguardUuid;
    }
    
    public void setProguardUuid(@Nullable final String proguardUuid) {
        this.proguardUuid = proguardUuid;
    }
    
    public void addBundleId(@Nullable final String bundleId) {
        if (bundleId != null) {
            final String trimmedBundleId = bundleId.trim();
            if (!trimmedBundleId.isEmpty()) {
                this.bundleIds.add(trimmedBundleId);
            }
        }
    }
    
    @NotNull
    public Set<String> getBundleIds() {
        return this.bundleIds;
    }
    
    @NotNull
    public List<String> getContextTags() {
        return this.contextTags;
    }
    
    public void addContextTag(@NotNull final String contextTag) {
        this.contextTags.add(contextTag);
    }
    
    @Nullable
    public Long getIdleTimeout() {
        return this.idleTimeout;
    }
    
    public void setIdleTimeout(@Nullable final Long idleTimeout) {
        this.idleTimeout = idleTimeout;
    }
    
    public boolean isSendClientReports() {
        return this.sendClientReports;
    }
    
    public void setSendClientReports(final boolean sendClientReports) {
        this.sendClientReports = sendClientReports;
        if (sendClientReports) {
            this.clientReportRecorder = new ClientReportRecorder(this);
        }
        else {
            this.clientReportRecorder = new NoOpClientReportRecorder();
        }
    }
    
    public boolean isEnableUserInteractionTracing() {
        return this.enableUserInteractionTracing;
    }
    
    public void setEnableUserInteractionTracing(final boolean enableUserInteractionTracing) {
        this.enableUserInteractionTracing = enableUserInteractionTracing;
    }
    
    public boolean isEnableUserInteractionBreadcrumbs() {
        return this.enableUserInteractionBreadcrumbs;
    }
    
    public void setEnableUserInteractionBreadcrumbs(final boolean enableUserInteractionBreadcrumbs) {
        this.enableUserInteractionBreadcrumbs = enableUserInteractionBreadcrumbs;
    }
    
    @Deprecated
    public void setInstrumenter(@NotNull final Instrumenter instrumenter) {
        this.instrumenter = instrumenter;
    }
    
    @NotNull
    public Instrumenter getInstrumenter() {
        return this.instrumenter;
    }
    
    @ApiStatus.Internal
    @NotNull
    public IClientReportRecorder getClientReportRecorder() {
        return this.clientReportRecorder;
    }
    
    @ApiStatus.Internal
    @NotNull
    public IModulesLoader getModulesLoader() {
        return this.modulesLoader;
    }
    
    @ApiStatus.Internal
    public void setModulesLoader(@Nullable final IModulesLoader modulesLoader) {
        this.modulesLoader = ((modulesLoader != null) ? modulesLoader : NoOpModulesLoader.getInstance());
    }
    
    @ApiStatus.Internal
    @NotNull
    public IDebugMetaLoader getDebugMetaLoader() {
        return this.debugMetaLoader;
    }
    
    @ApiStatus.Internal
    public void setDebugMetaLoader(@Nullable final IDebugMetaLoader debugMetaLoader) {
        this.debugMetaLoader = ((debugMetaLoader != null) ? debugMetaLoader : NoOpDebugMetaLoader.getInstance());
    }
    
    public List<GestureTargetLocator> getGestureTargetLocators() {
        return this.gestureTargetLocators;
    }
    
    public void setGestureTargetLocators(@NotNull final List<GestureTargetLocator> locators) {
        this.gestureTargetLocators.clear();
        this.gestureTargetLocators.addAll(locators);
    }
    
    @NotNull
    public final List<ViewHierarchyExporter> getViewHierarchyExporters() {
        return this.viewHierarchyExporters;
    }
    
    public void setViewHierarchyExporters(@NotNull final List<ViewHierarchyExporter> exporters) {
        this.viewHierarchyExporters.clear();
        this.viewHierarchyExporters.addAll(exporters);
    }
    
    @NotNull
    public IThreadChecker getThreadChecker() {
        return this.threadChecker;
    }
    
    public void setThreadChecker(@NotNull final IThreadChecker threadChecker) {
        this.threadChecker = threadChecker;
    }
    
    @ApiStatus.Internal
    @NotNull
    public CompositePerformanceCollector getCompositePerformanceCollector() {
        return this.compositePerformanceCollector;
    }
    
    @ApiStatus.Internal
    public void setCompositePerformanceCollector(@NotNull final CompositePerformanceCollector compositePerformanceCollector) {
        this.compositePerformanceCollector = compositePerformanceCollector;
    }
    
    public boolean isEnableTimeToFullDisplayTracing() {
        return this.enableTimeToFullDisplayTracing;
    }
    
    public void setEnableTimeToFullDisplayTracing(final boolean enableTimeToFullDisplayTracing) {
        this.enableTimeToFullDisplayTracing = enableTimeToFullDisplayTracing;
    }
    
    @ApiStatus.Internal
    @NotNull
    public FullyDisplayedReporter getFullyDisplayedReporter() {
        return this.fullyDisplayedReporter;
    }
    
    @ApiStatus.Internal
    @TestOnly
    public void setFullyDisplayedReporter(@NotNull final FullyDisplayedReporter fullyDisplayedReporter) {
        this.fullyDisplayedReporter = fullyDisplayedReporter;
    }
    
    public boolean isTraceOptionsRequests() {
        return this.traceOptionsRequests;
    }
    
    public void setTraceOptionsRequests(final boolean traceOptionsRequests) {
        this.traceOptionsRequests = traceOptionsRequests;
    }
    
    public boolean isEnabled() {
        return this.enabled;
    }
    
    public void setEnabled(final boolean enabled) {
        this.enabled = enabled;
    }
    
    public boolean isEnablePrettySerializationOutput() {
        return this.enablePrettySerializationOutput;
    }
    
    public boolean isSendModules() {
        return this.sendModules;
    }
    
    public void setEnablePrettySerializationOutput(final boolean enablePrettySerializationOutput) {
        this.enablePrettySerializationOutput = enablePrettySerializationOutput;
    }
    
    public boolean isEnableAppStartProfiling() {
        return (this.isProfilingEnabled() || this.isContinuousProfilingEnabled()) && this.enableAppStartProfiling;
    }
    
    public void setEnableAppStartProfiling(final boolean enableAppStartProfiling) {
        this.enableAppStartProfiling = enableAppStartProfiling;
    }
    
    public void setSendModules(final boolean sendModules) {
        this.sendModules = sendModules;
    }
    
    @ApiStatus.Experimental
    @Nullable
    public List<FilterString> getIgnoredSpanOrigins() {
        return this.ignoredSpanOrigins;
    }
    
    @ApiStatus.Experimental
    public void addIgnoredSpanOrigin(final String ignoredSpanOrigin) {
        if (this.ignoredSpanOrigins == null) {
            this.ignoredSpanOrigins = new ArrayList<FilterString>();
        }
        this.ignoredSpanOrigins.add(new FilterString(ignoredSpanOrigin));
    }
    
    @ApiStatus.Experimental
    public void setIgnoredSpanOrigins(@Nullable final List<String> ignoredSpanOrigins) {
        if (ignoredSpanOrigins == null) {
            this.ignoredSpanOrigins = null;
        }
        else {
            final List<FilterString> filtered = new ArrayList<FilterString>();
            for (final String origin : ignoredSpanOrigins) {
                if (origin != null && !origin.isEmpty()) {
                    filtered.add(new FilterString(origin));
                }
            }
            this.ignoredSpanOrigins = filtered;
        }
    }
    
    @ApiStatus.Experimental
    @Nullable
    public List<FilterString> getIgnoredCheckIns() {
        return this.ignoredCheckIns;
    }
    
    @ApiStatus.Experimental
    public void addIgnoredCheckIn(final String ignoredCheckIn) {
        if (this.ignoredCheckIns == null) {
            this.ignoredCheckIns = new ArrayList<FilterString>();
        }
        this.ignoredCheckIns.add(new FilterString(ignoredCheckIn));
    }
    
    @ApiStatus.Experimental
    public void setIgnoredCheckIns(@Nullable final List<String> ignoredCheckIns) {
        if (ignoredCheckIns == null) {
            this.ignoredCheckIns = null;
        }
        else {
            final List<FilterString> filteredIgnoredCheckIns = new ArrayList<FilterString>();
            for (final String slug : ignoredCheckIns) {
                if (!slug.isEmpty()) {
                    filteredIgnoredCheckIns.add(new FilterString(slug));
                }
            }
            this.ignoredCheckIns = filteredIgnoredCheckIns;
        }
    }
    
    @Nullable
    public List<FilterString> getIgnoredTransactions() {
        return this.ignoredTransactions;
    }
    
    @ApiStatus.Experimental
    public void addIgnoredTransaction(final String ignoredTransaction) {
        if (this.ignoredTransactions == null) {
            this.ignoredTransactions = new ArrayList<FilterString>();
        }
        this.ignoredTransactions.add(new FilterString(ignoredTransaction));
    }
    
    @ApiStatus.Experimental
    public void setIgnoredTransactions(@Nullable final List<String> ignoredTransactions) {
        if (ignoredTransactions == null) {
            this.ignoredTransactions = null;
        }
        else {
            final List<FilterString> filtered = new ArrayList<FilterString>();
            for (final String transactionName : ignoredTransactions) {
                if (transactionName != null && !transactionName.isEmpty()) {
                    filtered.add(new FilterString(transactionName));
                }
            }
            this.ignoredTransactions = filtered;
        }
    }
    
    @ApiStatus.Internal
    @NotNull
    public SentryDateProvider getDateProvider() {
        return this.dateProvider.getValue();
    }
    
    @ApiStatus.Internal
    public void setDateProvider(@NotNull final SentryDateProvider dateProvider) {
        this.dateProvider.setValue(dateProvider);
    }
    
    @ApiStatus.Internal
    public void addPerformanceCollector(@NotNull final IPerformanceCollector collector) {
        this.performanceCollectors.add(collector);
    }
    
    @ApiStatus.Internal
    @NotNull
    public List<IPerformanceCollector> getPerformanceCollectors() {
        return this.performanceCollectors;
    }
    
    @NotNull
    public IConnectionStatusProvider getConnectionStatusProvider() {
        return this.connectionStatusProvider;
    }
    
    public void setConnectionStatusProvider(@NotNull final IConnectionStatusProvider connectionStatusProvider) {
        this.connectionStatusProvider = connectionStatusProvider;
    }
    
    @ApiStatus.Internal
    @NotNull
    public IBackpressureMonitor getBackpressureMonitor() {
        return this.backpressureMonitor;
    }
    
    @ApiStatus.Internal
    public void setBackpressureMonitor(@NotNull final IBackpressureMonitor backpressureMonitor) {
        this.backpressureMonitor = backpressureMonitor;
    }
    
    @ApiStatus.Experimental
    public void setEnableBackpressureHandling(final boolean enableBackpressureHandling) {
        this.enableBackpressureHandling = enableBackpressureHandling;
    }
    
    @ApiStatus.Internal
    @NotNull
    public IVersionDetector getVersionDetector() {
        return this.versionDetector;
    }
    
    @ApiStatus.Internal
    public void setVersionDetector(@NotNull final IVersionDetector versionDetector) {
        this.versionDetector = versionDetector;
    }
    
    @ApiStatus.Internal
    public int getProfilingTracesHz() {
        return this.profilingTracesHz;
    }
    
    @ApiStatus.Internal
    public void setProfilingTracesHz(final int profilingTracesHz) {
        this.profilingTracesHz = profilingTracesHz;
    }
    
    @ApiStatus.Experimental
    public boolean isEnableBackpressureHandling() {
        return this.enableBackpressureHandling;
    }
    
    @ApiStatus.Internal
    public long getSessionFlushTimeoutMillis() {
        return this.sessionFlushTimeoutMillis;
    }
    
    @ApiStatus.Internal
    public void setSessionFlushTimeoutMillis(final long sessionFlushTimeoutMillis) {
        this.sessionFlushTimeoutMillis = sessionFlushTimeoutMillis;
    }
    
    @ApiStatus.Internal
    @Nullable
    public BeforeEnvelopeCallback getBeforeEnvelopeCallback() {
        return this.beforeEnvelopeCallback;
    }
    
    @ApiStatus.Internal
    public void setBeforeEnvelopeCallback(@Nullable final BeforeEnvelopeCallback beforeEnvelopeCallback) {
        this.beforeEnvelopeCallback = beforeEnvelopeCallback;
    }
    
    @ApiStatus.Experimental
    @Nullable
    public String getSpotlightConnectionUrl() {
        return this.spotlightConnectionUrl;
    }
    
    @ApiStatus.Experimental
    public void setSpotlightConnectionUrl(@Nullable final String spotlightConnectionUrl) {
        this.spotlightConnectionUrl = spotlightConnectionUrl;
    }
    
    @ApiStatus.Experimental
    public boolean isEnableSpotlight() {
        return this.enableSpotlight;
    }
    
    @ApiStatus.Experimental
    public void setEnableSpotlight(final boolean enableSpotlight) {
        this.enableSpotlight = enableSpotlight;
    }
    
    public boolean isEnableScopePersistence() {
        return this.enableScopePersistence;
    }
    
    public void setEnableScopePersistence(final boolean enableScopePersistence) {
        this.enableScopePersistence = enableScopePersistence;
    }
    
    @Nullable
    public Cron getCron() {
        return this.cron;
    }
    
    @ApiStatus.Experimental
    public void setCron(@Nullable final Cron cron) {
        this.cron = cron;
    }
    
    @NotNull
    public ExperimentalOptions getExperimental() {
        return this.experimental;
    }
    
    @NotNull
    public ReplayController getReplayController() {
        return this.replayController;
    }
    
    public void setReplayController(@Nullable final ReplayController replayController) {
        this.replayController = ((replayController != null) ? replayController : NoOpReplayController.getInstance());
    }
    
    @ApiStatus.Experimental
    @NotNull
    public IDistributionApi getDistributionController() {
        return this.distributionController;
    }
    
    @ApiStatus.Experimental
    public void setDistributionController(@Nullable final IDistributionApi distributionController) {
        this.distributionController = ((distributionController != null) ? distributionController : NoOpDistributionApi.getInstance());
    }
    
    @ApiStatus.Experimental
    public boolean isEnableScreenTracking() {
        return this.enableScreenTracking;
    }
    
    @ApiStatus.Experimental
    public void setEnableScreenTracking(final boolean enableScreenTracking) {
        this.enableScreenTracking = enableScreenTracking;
    }
    
    public void setDefaultScopeType(@NotNull final ScopeType scopeType) {
        this.defaultScopeType = scopeType;
    }
    
    @NotNull
    public ScopeType getDefaultScopeType() {
        return this.defaultScopeType;
    }
    
    @ApiStatus.Internal
    public void setInitPriority(@NotNull final InitPriority initPriority) {
        this.initPriority = initPriority;
    }
    
    @ApiStatus.Internal
    @NotNull
    public InitPriority getInitPriority() {
        return this.initPriority;
    }
    
    public void setForceInit(final boolean forceInit) {
        this.forceInit = forceInit;
    }
    
    public boolean isForceInit() {
        return this.forceInit;
    }
    
    public void setGlobalHubMode(@Nullable final Boolean globalHubMode) {
        this.globalHubMode = globalHubMode;
    }
    
    @Nullable
    public Boolean isGlobalHubMode() {
        return this.globalHubMode;
    }
    
    public void setOpenTelemetryMode(@NotNull final SentryOpenTelemetryMode openTelemetryMode) {
        this.openTelemetryMode = openTelemetryMode;
    }
    
    @NotNull
    public SentryOpenTelemetryMode getOpenTelemetryMode() {
        return this.openTelemetryMode;
    }
    
    @NotNull
    public SentryReplayOptions getSessionReplay() {
        return this.sessionReplay;
    }
    
    public void setSessionReplay(@NotNull final SentryReplayOptions sessionReplayOptions) {
        this.sessionReplay = sessionReplayOptions;
    }
    
    @NotNull
    public SentryFeedbackOptions getFeedbackOptions() {
        return this.feedbackOptions;
    }
    
    public void setFeedbackOptions(@NotNull final SentryFeedbackOptions feedbackOptions) {
        this.feedbackOptions = feedbackOptions;
    }
    
    @ApiStatus.Experimental
    public void setCaptureOpenTelemetryEvents(final boolean captureOpenTelemetryEvents) {
        this.captureOpenTelemetryEvents = captureOpenTelemetryEvents;
    }
    
    @ApiStatus.Experimental
    public boolean isCaptureOpenTelemetryEvents() {
        return this.captureOpenTelemetryEvents;
    }
    
    @NotNull
    public ISocketTagger getSocketTagger() {
        return this.socketTagger;
    }
    
    public void setSocketTagger(@Nullable final ISocketTagger socketTagger) {
        this.socketTagger = ((socketTagger != null) ? socketTagger : NoOpSocketTagger.getInstance());
    }
    
    @ApiStatus.Internal
    @NotNull
    public IRuntimeManager getRuntimeManager() {
        return this.runtimeManager;
    }
    
    @ApiStatus.Internal
    public void setRuntimeManager(@NotNull final IRuntimeManager runtimeManager) {
        this.runtimeManager = runtimeManager;
    }
    
    void loadLazyFields() {
        this.getSerializer();
        this.retrieveParsedDsn();
        this.getEnvelopeReader();
        this.getDateProvider();
    }
    
    @ApiStatus.Internal
    @NotNull
    public static SentryOptions empty() {
        return new SentryOptions(true);
    }
    
    public SentryOptions() {
        this(false);
    }
    
    private SentryOptions(final boolean empty) {
        this.eventProcessors = new CopyOnWriteArrayList<EventProcessor>();
        this.ignoredExceptionsForType = new CopyOnWriteArraySet<Class<? extends Throwable>>();
        this.ignoredErrors = null;
        this.integrations = new CopyOnWriteArrayList<Integration>();
        this.bundleIds = new CopyOnWriteArraySet<String>();
        this.parsedDsn = new LazyEvaluator<Dsn>(() -> new Dsn(this.dsn));
        this.shutdownTimeoutMillis = 2000L;
        this.flushTimeoutMillis = 15000L;
        this.sessionFlushTimeoutMillis = 15000L;
        this.logger = NoOpLogger.getInstance();
        this.fatalLogger = NoOpLogger.getInstance();
        this.diagnosticLevel = SentryOptions.DEFAULT_DIAGNOSTIC_LEVEL;
        this.serializer = new LazyEvaluator<ISerializer>(() -> new JsonSerializer(this));
        this.envelopeReader = new LazyEvaluator<IEnvelopeReader>(() -> new EnvelopeReader(this.serializer.getValue()));
        this.maxDepth = 100;
        this.maxCacheItems = 30;
        this.maxQueueSize = this.maxCacheItems;
        this.maxBreadcrumbs = 100;
        this.maxFeatureFlags = 100;
        this.inAppExcludes = new CopyOnWriteArrayList<String>();
        this.inAppIncludes = new CopyOnWriteArrayList<String>();
        this.transportFactory = NoOpTransportFactory.getInstance();
        this.transportGate = NoOpTransportGate.getInstance();
        this.attachStacktrace = true;
        this.enableAutoSessionTracking = true;
        this.sessionTrackingIntervalMillis = 30000L;
        this.attachServerName = true;
        this.enableUncaughtExceptionHandler = true;
        this.printUncaughtStackTrace = false;
        this.executorService = NoOpSentryExecutorService.getInstance();
        this.connectionTimeoutMillis = 30000;
        this.readTimeoutMillis = 30000;
        this.envelopeDiskCache = NoOpEnvelopeCache.getInstance();
        this.sendDefaultPii = false;
        this.observers = new CopyOnWriteArrayList<IScopeObserver>();
        this.optionsObservers = new CopyOnWriteArrayList<IOptionsObserver>();
        this.tags = new ConcurrentHashMap<String, String>();
        this.maxAttachmentSize = 20971520L;
        this.enableDeduplication = true;
        this.enableEventSizeLimiting = false;
        this.maxSpans = 1000;
        this.enableShutdownHook = true;
        this.maxRequestBodySize = RequestSize.NONE;
        this.traceSampling = true;
        this.maxTraceFileSize = 5242880L;
        this.transactionProfiler = NoOpTransactionProfiler.getInstance();
        this.continuousProfiler = NoOpContinuousProfiler.getInstance();
        this.profilerConverter = NoOpProfileConverter.getInstance();
        this.tracePropagationTargets = null;
        this.defaultTracePropagationTargets = Collections.singletonList(".*");
        this.propagateTraceparent = false;
        this.idleTimeout = 3000L;
        this.contextTags = new CopyOnWriteArrayList<String>();
        this.sendClientReports = true;
        this.clientReportRecorder = new ClientReportRecorder(this);
        this.modulesLoader = NoOpModulesLoader.getInstance();
        this.debugMetaLoader = NoOpDebugMetaLoader.getInstance();
        this.enableUserInteractionTracing = false;
        this.enableUserInteractionBreadcrumbs = true;
        this.instrumenter = Instrumenter.SENTRY;
        this.gestureTargetLocators = new ArrayList<GestureTargetLocator>();
        this.viewHierarchyExporters = new ArrayList<ViewHierarchyExporter>();
        this.threadChecker = NoOpThreadChecker.getInstance();
        this.traceOptionsRequests = true;
        this.dateProvider = new LazyEvaluator<SentryDateProvider>(() -> new SentryAutoDateProvider());
        this.performanceCollectors = new ArrayList<IPerformanceCollector>();
        this.compositePerformanceCollector = NoOpCompositePerformanceCollector.getInstance();
        this.enableTimeToFullDisplayTracing = false;
        this.fullyDisplayedReporter = FullyDisplayedReporter.getInstance();
        this.connectionStatusProvider = new NoOpConnectionStatusProvider();
        this.enabled = true;
        this.enablePrettySerializationOutput = true;
        this.sendModules = true;
        this.enableSpotlight = false;
        this.enableScopePersistence = true;
        this.ignoredCheckIns = null;
        this.ignoredSpanOrigins = null;
        this.ignoredTransactions = null;
        this.backpressureMonitor = NoOpBackpressureMonitor.getInstance();
        this.enableBackpressureHandling = true;
        this.enableAppStartProfiling = false;
        this.spanFactory = NoOpSpanFactory.getInstance();
        this.profilingTracesHz = 101;
        this.cron = null;
        this.replayController = NoOpReplayController.getInstance();
        this.distributionController = NoOpDistributionApi.getInstance();
        this.enableScreenTracking = true;
        this.defaultScopeType = ScopeType.ISOLATION;
        this.initPriority = InitPriority.MEDIUM;
        this.forceInit = false;
        this.globalHubMode = null;
        this.lock = new AutoClosableReentrantLock();
        this.openTelemetryMode = SentryOpenTelemetryMode.AUTO;
        this.captureOpenTelemetryEvents = false;
        this.versionDetector = NoopVersionDetector.getInstance();
        this.profileLifecycle = ProfileLifecycle.MANUAL;
        this.startProfilerOnAppStart = false;
        this.deadlineTimeout = 30000L;
        this.logs = new Logs();
        this.socketTagger = NoOpSocketTagger.getInstance();
        this.runtimeManager = new NeutralRuntimeManager();
        this.distribution = new DistributionOptions();
        final SdkVersion sdkVersion = this.createSdkVersion();
        this.experimental = new ExperimentalOptions(empty, sdkVersion);
        this.sessionReplay = new SentryReplayOptions(empty, sdkVersion);
        this.feedbackOptions = new SentryFeedbackOptions((associatedEventId, configurator) -> this.logger.log(SentryLevel.WARNING, "showDialog() can only be called in Android.", new Object[0]));
        if (!empty) {
            this.setSpanFactory(SpanFactoryFactory.create(new LoadClass(), NoOpLogger.getInstance()));
            (this.executorService = new SentryExecutorService(this)).prewarm();
            this.integrations.add(new UncaughtExceptionHandlerIntegration());
            this.integrations.add(new ShutdownHookIntegration());
            this.integrations.add(new SpotlightIntegration());
            this.eventProcessors.add(new MainEventProcessor(this));
            this.eventProcessors.add(new DuplicateEventDetectionEventProcessor(this));
            if (Platform.isJvm()) {
                this.eventProcessors.add(new SentryRuntimeEventProcessor());
            }
            this.setSentryClientName("sentry.java/8.29.0");
            this.setSdkVersion(sdkVersion);
            this.addPackageInfo();
        }
    }
    
    public void merge(@NotNull final ExternalOptions options) {
        if (options.getDsn() != null) {
            this.setDsn(options.getDsn());
        }
        if (options.getEnvironment() != null) {
            this.setEnvironment(options.getEnvironment());
        }
        if (options.getRelease() != null) {
            this.setRelease(options.getRelease());
        }
        if (options.getDist() != null) {
            this.setDist(options.getDist());
        }
        if (options.getServerName() != null) {
            this.setServerName(options.getServerName());
        }
        if (options.getProxy() != null) {
            this.setProxy(options.getProxy());
        }
        if (options.getEnableUncaughtExceptionHandler() != null) {
            this.setEnableUncaughtExceptionHandler(options.getEnableUncaughtExceptionHandler());
        }
        if (options.getPrintUncaughtStackTrace() != null) {
            this.setPrintUncaughtStackTrace(options.getPrintUncaughtStackTrace());
        }
        if (options.getTracesSampleRate() != null) {
            this.setTracesSampleRate(options.getTracesSampleRate());
        }
        if (options.getProfilesSampleRate() != null) {
            this.setProfilesSampleRate(options.getProfilesSampleRate());
        }
        if (options.getDebug() != null) {
            this.setDebug(options.getDebug());
        }
        if (options.getEnableDeduplication() != null) {
            this.setEnableDeduplication(options.getEnableDeduplication());
        }
        if (options.getSendClientReports() != null) {
            this.setSendClientReports(options.getSendClientReports());
        }
        if (options.isForceInit() != null) {
            this.setForceInit(options.isForceInit());
        }
        final Map<String, String> tags = new HashMap<String, String>(options.getTags());
        for (final Map.Entry<String, String> tag : tags.entrySet()) {
            this.tags.put(tag.getKey(), tag.getValue());
        }
        final List<String> inAppIncludes = new ArrayList<String>(options.getInAppIncludes());
        for (final String inAppInclude : inAppIncludes) {
            this.addInAppInclude(inAppInclude);
        }
        final List<String> inAppExcludes = new ArrayList<String>(options.getInAppExcludes());
        for (final String inAppExclude : inAppExcludes) {
            this.addInAppExclude(inAppExclude);
        }
        for (final Class<? extends Throwable> exceptionType : new HashSet(options.getIgnoredExceptionsForType())) {
            this.addIgnoredExceptionForType(exceptionType);
        }
        if (options.getTracePropagationTargets() != null) {
            final List<String> tracePropagationTargets = new ArrayList<String>(options.getTracePropagationTargets());
            this.setTracePropagationTargets(tracePropagationTargets);
        }
        final List<String> contextTags = new ArrayList<String>(options.getContextTags());
        for (final String contextTag : contextTags) {
            this.addContextTag(contextTag);
        }
        if (options.getProguardUuid() != null) {
            this.setProguardUuid(options.getProguardUuid());
        }
        if (options.getIdleTimeout() != null) {
            this.setIdleTimeout(options.getIdleTimeout());
        }
        for (final String bundleId : options.getBundleIds()) {
            this.addBundleId(bundleId);
        }
        if (options.isEnabled() != null) {
            this.setEnabled(options.isEnabled());
        }
        if (options.isEnablePrettySerializationOutput() != null) {
            this.setEnablePrettySerializationOutput(options.isEnablePrettySerializationOutput());
        }
        if (options.isSendModules() != null) {
            this.setSendModules(options.isSendModules());
        }
        if (options.getIgnoredCheckIns() != null) {
            final List<String> ignoredCheckIns = new ArrayList<String>(options.getIgnoredCheckIns());
            this.setIgnoredCheckIns(ignoredCheckIns);
        }
        if (options.getIgnoredTransactions() != null) {
            final List<String> ignoredTransactions = new ArrayList<String>(options.getIgnoredTransactions());
            this.setIgnoredTransactions(ignoredTransactions);
        }
        if (options.getIgnoredErrors() != null) {
            final List<String> ignoredExceptions = new ArrayList<String>(options.getIgnoredErrors());
            this.setIgnoredErrors(ignoredExceptions);
        }
        if (options.isEnableBackpressureHandling() != null) {
            this.setEnableBackpressureHandling(options.isEnableBackpressureHandling());
        }
        if (options.getMaxRequestBodySize() != null) {
            this.setMaxRequestBodySize(options.getMaxRequestBodySize());
        }
        if (options.isSendDefaultPii() != null) {
            this.setSendDefaultPii(options.isSendDefaultPii());
        }
        if (options.isCaptureOpenTelemetryEvents() != null) {
            this.setCaptureOpenTelemetryEvents(options.isCaptureOpenTelemetryEvents());
        }
        if (options.isEnableSpotlight() != null) {
            this.setEnableSpotlight(options.isEnableSpotlight());
        }
        if (options.getSpotlightConnectionUrl() != null) {
            this.setSpotlightConnectionUrl(options.getSpotlightConnectionUrl());
        }
        if (options.isGlobalHubMode() != null) {
            this.setGlobalHubMode(options.isGlobalHubMode());
        }
        if (options.getCron() != null) {
            if (this.getCron() == null) {
                this.setCron(options.getCron());
            }
            else {
                if (options.getCron().getDefaultCheckinMargin() != null) {
                    this.getCron().setDefaultCheckinMargin(options.getCron().getDefaultCheckinMargin());
                }
                if (options.getCron().getDefaultMaxRuntime() != null) {
                    this.getCron().setDefaultMaxRuntime(options.getCron().getDefaultMaxRuntime());
                }
                if (options.getCron().getDefaultTimezone() != null) {
                    this.getCron().setDefaultTimezone(options.getCron().getDefaultTimezone());
                }
                if (options.getCron().getDefaultFailureIssueThreshold() != null) {
                    this.getCron().setDefaultFailureIssueThreshold(options.getCron().getDefaultFailureIssueThreshold());
                }
                if (options.getCron().getDefaultRecoveryThreshold() != null) {
                    this.getCron().setDefaultRecoveryThreshold(options.getCron().getDefaultRecoveryThreshold());
                }
            }
        }
        if (options.isEnableLogs() != null) {
            this.getLogs().setEnabled(options.isEnableLogs());
        }
        if (options.getProfileSessionSampleRate() != null) {
            this.setProfileSessionSampleRate(options.getProfileSessionSampleRate());
        }
        if (options.getProfilingTracesDirPath() != null) {
            this.setProfilingTracesDirPath(options.getProfilingTracesDirPath());
        }
        if (options.getProfileLifecycle() != null) {
            this.setProfileLifecycle(options.getProfileLifecycle());
        }
    }
    
    @NotNull
    private SdkVersion createSdkVersion() {
        final String version = "8.29.0";
        final SdkVersion sdkVersion = new SdkVersion("sentry.java", "8.29.0");
        sdkVersion.setVersion("8.29.0");
        return sdkVersion;
    }
    
    private void addPackageInfo() {
        SentryIntegrationPackageStorage.getInstance().addPackage("maven:io.sentry:sentry", "8.29.0");
    }
    
    @ApiStatus.Internal
    @NotNull
    public ISpanFactory getSpanFactory() {
        return this.spanFactory;
    }
    
    @ApiStatus.Internal
    public void setSpanFactory(@NotNull final ISpanFactory spanFactory) {
        this.spanFactory = spanFactory;
    }
    
    @ApiStatus.Experimental
    @NotNull
    public Logs getLogs() {
        return this.logs;
    }
    
    @ApiStatus.Experimental
    public void setLogs(@NotNull final Logs logs) {
        this.logs = logs;
    }
    
    @ApiStatus.Experimental
    @NotNull
    public DistributionOptions getDistribution() {
        return this.distribution;
    }
    
    @ApiStatus.Experimental
    public void setDistribution(@NotNull final DistributionOptions distribution) {
        this.distribution = ((distribution != null) ? distribution : new DistributionOptions());
    }
    
    static {
        DEFAULT_DIAGNOSTIC_LEVEL = SentryLevel.DEBUG;
    }
    
    @ApiStatus.Experimental
    public static final class DistributionOptions
    {
        public String orgAuthToken;
        public String orgSlug;
        public String projectSlug;
        public String sentryBaseUrl;
        @Nullable
        public String buildConfiguration;
        
        public DistributionOptions() {
            this.orgAuthToken = "";
            this.orgSlug = "";
            this.projectSlug = "";
            this.sentryBaseUrl = "https://sentry.io";
            this.buildConfiguration = null;
        }
    }
    
    public static final class Proxy
    {
        @Nullable
        private String host;
        @Nullable
        private String port;
        @Nullable
        private String user;
        @Nullable
        private String pass;
        @Nullable
        private java.net.Proxy.Type type;
        
        public Proxy() {
            this(null, null, null, null, null);
        }
        
        public Proxy(@Nullable final String host, @Nullable final String port) {
            this(host, port, null, null, null);
        }
        
        public Proxy(@Nullable final String host, @Nullable final String port, @Nullable final java.net.Proxy.Type type) {
            this(host, port, type, null, null);
        }
        
        public Proxy(@Nullable final String host, @Nullable final String port, @Nullable final String user, @Nullable final String pass) {
            this(host, port, null, user, pass);
        }
        
        public Proxy(@Nullable final String host, @Nullable final String port, @Nullable final java.net.Proxy.Type type, @Nullable final String user, @Nullable final String pass) {
            this.host = host;
            this.port = port;
            this.type = type;
            this.user = user;
            this.pass = pass;
        }
        
        @Nullable
        public String getHost() {
            return this.host;
        }
        
        public void setHost(@Nullable final String host) {
            this.host = host;
        }
        
        @Nullable
        public String getPort() {
            return this.port;
        }
        
        public void setPort(@Nullable final String port) {
            this.port = port;
        }
        
        @Nullable
        public String getUser() {
            return this.user;
        }
        
        public void setUser(@Nullable final String user) {
            this.user = user;
        }
        
        @Nullable
        public String getPass() {
            return this.pass;
        }
        
        public void setPass(@Nullable final String pass) {
            this.pass = pass;
        }
        
        @Nullable
        public java.net.Proxy.Type getType() {
            return this.type;
        }
        
        public void setType(@Nullable final java.net.Proxy.Type type) {
            this.type = type;
        }
    }
    
    public static final class Cron
    {
        @Nullable
        private Long defaultCheckinMargin;
        @Nullable
        private Long defaultMaxRuntime;
        @Nullable
        private String defaultTimezone;
        @Nullable
        private Long defaultFailureIssueThreshold;
        @Nullable
        private Long defaultRecoveryThreshold;
        
        @Nullable
        public Long getDefaultCheckinMargin() {
            return this.defaultCheckinMargin;
        }
        
        public void setDefaultCheckinMargin(@Nullable final Long defaultCheckinMargin) {
            this.defaultCheckinMargin = defaultCheckinMargin;
        }
        
        @Nullable
        public Long getDefaultMaxRuntime() {
            return this.defaultMaxRuntime;
        }
        
        public void setDefaultMaxRuntime(@Nullable final Long defaultMaxRuntime) {
            this.defaultMaxRuntime = defaultMaxRuntime;
        }
        
        @Nullable
        public String getDefaultTimezone() {
            return this.defaultTimezone;
        }
        
        public void setDefaultTimezone(@Nullable final String defaultTimezone) {
            this.defaultTimezone = defaultTimezone;
        }
        
        @Nullable
        public Long getDefaultFailureIssueThreshold() {
            return this.defaultFailureIssueThreshold;
        }
        
        public void setDefaultFailureIssueThreshold(@Nullable final Long defaultFailureIssueThreshold) {
            this.defaultFailureIssueThreshold = defaultFailureIssueThreshold;
        }
        
        @Nullable
        public Long getDefaultRecoveryThreshold() {
            return this.defaultRecoveryThreshold;
        }
        
        public void setDefaultRecoveryThreshold(@Nullable final Long defaultRecoveryThreshold) {
            this.defaultRecoveryThreshold = defaultRecoveryThreshold;
        }
    }
    
    public static final class Logs
    {
        private boolean enable;
        @Nullable
        private BeforeSendLogCallback beforeSend;
        @NotNull
        private ILoggerBatchProcessorFactory loggerBatchProcessorFactory;
        
        public Logs() {
            this.enable = false;
            this.loggerBatchProcessorFactory = new DefaultLoggerBatchProcessorFactory();
        }
        
        public boolean isEnabled() {
            return this.enable;
        }
        
        public void setEnabled(final boolean enableLogs) {
            this.enable = enableLogs;
        }
        
        @Nullable
        public BeforeSendLogCallback getBeforeSend() {
            return this.beforeSend;
        }
        
        public void setBeforeSend(@Nullable final BeforeSendLogCallback beforeSendLog) {
            this.beforeSend = beforeSendLog;
        }
        
        @ApiStatus.Internal
        @NotNull
        public ILoggerBatchProcessorFactory getLoggerBatchProcessorFactory() {
            return this.loggerBatchProcessorFactory;
        }
        
        @ApiStatus.Internal
        public void setLoggerBatchProcessorFactory(@NotNull final ILoggerBatchProcessorFactory loggerBatchProcessorFactory) {
            this.loggerBatchProcessorFactory = loggerBatchProcessorFactory;
        }
        
        public interface BeforeSendLogCallback
        {
            @Nullable
            SentryLogEvent execute(@NotNull final SentryLogEvent p0);
        }
    }
    
    public enum RequestSize
    {
        NONE, 
        SMALL, 
        MEDIUM, 
        ALWAYS;
    }
    
    public interface BeforeSendCallback
    {
        @Nullable
        SentryEvent execute(@NotNull final SentryEvent p0, @NotNull final Hint p1);
    }
    
    public interface BeforeSendTransactionCallback
    {
        @Nullable
        SentryTransaction execute(@NotNull final SentryTransaction p0, @NotNull final Hint p1);
    }
    
    public interface BeforeSendReplayCallback
    {
        @Nullable
        SentryReplayEvent execute(@NotNull final SentryReplayEvent p0, @NotNull final Hint p1);
    }
    
    public interface BeforeBreadcrumbCallback
    {
        @Nullable
        Breadcrumb execute(@NotNull final Breadcrumb p0, @NotNull final Hint p1);
    }
    
    public interface OnDiscardCallback
    {
        void execute(@NotNull final DiscardReason p0, @NotNull final DataCategory p1, @NotNull final Long p2);
    }
    
    public interface TracesSamplerCallback
    {
        @Nullable
        Double sample(@NotNull final SamplingContext p0);
    }
    
    public interface OnOversizedEventCallback
    {
        @NotNull
        SentryEvent execute(@NotNull final SentryEvent p0, @NotNull final Hint p1);
    }
    
    public interface ProfilesSamplerCallback
    {
        @Nullable
        Double sample(@NotNull final SamplingContext p0);
    }
    
    @ApiStatus.Internal
    public interface BeforeEnvelopeCallback
    {
        void execute(@NotNull final SentryEnvelope p0, @Nullable final Hint p1);
    }
    
    @ApiStatus.Experimental
    public interface BeforeEmitMetricCallback
    {
        boolean execute(@NotNull final String p0, @Nullable final Map<String, String> p1);
    }
}
