text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.cosmos.implementation.directconnectivity;

import com.azure.cosmos.ConsistencyLevel;
import com.azure.cosmos.CosmosException;
import com.azure.cosmos.implementation.DiagnosticsClientContext;
import com.azure.cosmos.implementation.GoneException;
import com.azure.cosmos.implementation.InternalServerErrorException;
import com.azure.cosmos.implementation.Configs;
import com.azure.cosmos.implementation.IAuthorizationTokenProvider;
import com.azure.cosmos.implementation.JavaStreamUtils;
import com.azure.cosmos.implementation.MutableVolatile;
import com.azure.cosmos.implementation.Quadruple;
import com.azure.cosmos.implementation.RMResources;
import com.azure.cosmos.implementation.RequestChargeTracker;
import com.azure.cosmos.implementation.RxDocumentServiceRequest;
import com.azure.cosmos.implementation.apachecommons.lang.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import static com.azure.cosmos.implementation.Utils.ValueHolder;

//
//=================================================================================================================
// STRONG read logic:
//=================================================================================================================
//
//              ------------------- PerformPrimaryRead-------------------------------------------------------------
//              |                       ^                                                                         |
//        [RetryOnSecondary]            |                                                                         |
//              |                   [QuorumNotSelected]                                                           |
//             \/                      |                                                                         \/
// Start-------------------------->SecondaryQuorumRead-------------[QuorumMet]-------------------------------->Result
//                                      |                                                                         ^
//                                  [QuorumSelected]                                                              |
//                                      |                                                                         |
//                                      \/                                                                        |
//                                  PrimaryReadBarrier-------------------------------------------------------------
//
//=================================================================================================================
// BOUNDED_STALENESS quorum read logic:
//=================================================================================================================
//
//              ------------------- PerformPrimaryRead-------------------------------------------------------------
//              |                       ^                                                                         |
//        [RetryOnSecondary]            |                                                                         |
//              |                   [QuorumNotSelected]                                                           |
//             \/                      |                                                                         \/
// Start-------------------------->SecondaryQuorumRead-------------[QuorumMet]-------------------------------->Result
//                                      |                                                                         ^
//                                  [QuorumSelected]                                                              |
//                                      |                                                                         |
//                                      |                                                                         |
//                                      ---------------------------------------------------------------------------
//
/**
 * QuorumReader wraps the client side quorum logic on top of the StoreReader
 */
public class QuorumReader {
    private final static Logger logger = LoggerFactory.getLogger(QuorumReader.class);
    private final DiagnosticsClientContext diagnosticsClientContext;

    private final int maxNumberOfReadBarrierReadRetries;
    private final int maxNumberOfPrimaryReadRetries;
    private final int maxNumberOfReadQuorumRetries;
    private final int delayBetweenReadBarrierCallsInMs;

    private final int maxBarrierRetriesForMultiRegion;
    private final int barrierRetryIntervalInMsForMultiRegion;

    private final int maxShortBarrierRetriesForMultiRegion;
    private final int shortBarrierRetryIntervalInMsForMultiRegion;

    private final StoreReader storeReader;
    private final GatewayServiceConfigurationReader serviceConfigReader;
    private final IAuthorizationTokenProvider authorizationTokenProvider;

    public QuorumReader(
        DiagnosticsClientContext diagnosticsClientContext,
        Configs configs,
        TransportClient transportClient,
        AddressSelector addressSelector,
        StoreReader storeReader,
        GatewayServiceConfigurationReader serviceConfigReader,
        IAuthorizationTokenProvider authorizationTokenProvider) {
        this.diagnosticsClientContext = diagnosticsClientContext;
        this.storeReader = storeReader;
        this.serviceConfigReader = serviceConfigReader;
        this.authorizationTokenProvider = authorizationTokenProvider;

        this.maxNumberOfReadBarrierReadRetries = configs.getMaxNumberOfReadBarrierReadRetries();
        this.maxNumberOfPrimaryReadRetries = configs.getMaxNumberOfPrimaryReadRetries();
        this.maxNumberOfReadQuorumRetries = configs.getMaxNumberOfReadQuorumRetries();
        this.delayBetweenReadBarrierCallsInMs = configs.getDelayBetweenReadBarrierCallsInMs();
        this.maxBarrierRetriesForMultiRegion = configs.getMaxBarrierRetriesForMultiRegion();
        this.barrierRetryIntervalInMsForMultiRegion = configs.getBarrierRetryIntervalInMsForMultiRegion();
        this.maxShortBarrierRetriesForMultiRegion = configs.getMaxShortBarrierRetriesForMultiRegion();
        this.shortBarrierRetryIntervalInMsForMultiRegion = configs.getShortBarrierRetryIntervalInMsForMultiRegion();
    }

    public QuorumReader(
        DiagnosticsClientContext diagnosticsClientContext,
        TransportClient transportClient,
        AddressSelector addressSelector,
        StoreReader storeReader,
        GatewayServiceConfigurationReader serviceConfigReader,
        IAuthorizationTokenProvider authorizationTokenProvider,
        Configs configs) {
        this(diagnosticsClientContext, configs, transportClient, addressSelector, storeReader, serviceConfigReader, authorizationTokenProvider);
    }

    public Mono<StoreResponse> readStrongAsync(
        DiagnosticsClientContext diagnosticsClientContext,
        RxDocumentServiceRequest entity,
        int readQuorumValue,
        ReadMode readMode) {
        final MutableVolatile<Boolean> shouldRetryOnSecondary = new MutableVolatile<>(false);
        final MutableVolatile<Boolean> hasPerformedReadFromPrimary = new MutableVolatile<>(false);

        return Flux.defer(
            // the following will be repeated till the repeat().takeUntil(.) condition is satisfied.
            () -> {
                if (entity.requestContext.timeoutHelper.isElapsed()) {
                        return Flux.error(new GoneException());
                }

                shouldRetryOnSecondary.v = false;
                Mono<ReadQuorumResult> secondaryQuorumReadResultObs =
                    this.readQuorumAsync(entity, readQuorumValue, false, readMode);

                    return secondaryQuorumReadResultObs.flux().flatMap(
                    secondaryQuorumReadResult -> {

                        switch (secondaryQuorumReadResult.quorumResult) {
                            case QuorumMet:
                                try {
                                            return Flux.just(secondaryQuorumReadResult.getResponse());
                                } catch (CosmosException e) {
                                    return Flux.error(e);
                                }

                            case QuorumSelected:
                                Mono<RxDocumentServiceRequest> barrierRequestObs = BarrierRequestHelper.createAsync(
                                    this.diagnosticsClientContext,
                                    entity,
                                    this.authorizationTokenProvider,
                                    secondaryQuorumReadResult.selectedLsn,
                                    secondaryQuorumReadResult.globalCommittedSelectedLsn);

                                        return barrierRequestObs.flux().flatMap(barrierRequest -> {
                                    Mono<Boolean> readBarrierObs = this.waitForReadBarrierAsync(
                                        barrierRequest,
                                        true /* include primary */,
                                        readQuorumValue,
                                        secondaryQuorumReadResult.selectedLsn,
                                        secondaryQuorumReadResult.globalCommittedSelectedLsn,
                                        readMode);

                                            return readBarrierObs.flux().flatMap(
                                        readBarrier -> {

                                            if (readBarrier) {
                                                try {
                                                                return Flux.just(secondaryQuorumReadResult.getResponse());
                                                } catch (Exception e) {
                                                    return Flux.error(e);
                                                }
                                            }

                                            // else barrier was not successful
                                            logger.warn(
                                                "QuorumSelected: Could not converge on the LSN {} GlobalCommittedLSN {} after primary read barrier with read quorum {} for strong read, Responses: {}",
                                                secondaryQuorumReadResult.selectedLsn,
                                                secondaryQuorumReadResult.globalCommittedSelectedLsn,
                                                readQuorumValue,
                                                String.join(";", secondaryQuorumReadResult.storeResponses)
                                            );

                                            entity.requestContext.quorumSelectedStoreResponse = secondaryQuorumReadResult.selectedResponse;
                                            entity.requestContext.storeResponses = secondaryQuorumReadResult.storeResponses;
                                            entity.requestContext.quorumSelectedLSN = secondaryQuorumReadResult.selectedLsn;
                                            entity.requestContext.globalCommittedSelectedLSN = secondaryQuorumReadResult.globalCommittedSelectedLsn;

                                                        return Flux.empty();
                                        }
                                    );
                                });

                            case QuorumNotSelected:
                                if (hasPerformedReadFromPrimary.v) {
                                    logger.warn("QuorumNotSelected: Primary read already attempted. Quorum could not be selected after retrying on secondaries.");
                                    return Flux.error(new GoneException(RMResources.ReadQuorumNotMet));
                                }

                                logger.warn("QuorumNotSelected: Quorum could not be selected with read quorum of {}", readQuorumValue);
                                Mono<ReadPrimaryResult> responseObs = this.readPrimaryAsync(entity, readQuorumValue, false);

                                        return responseObs.flux().flatMap(
                                    response -> {
                                        if (response.isSuccessful && response.shouldRetryOnSecondary) {
                                            assert false : "QuorumNotSelected: PrimaryResult has both Successful and shouldRetryOnSecondary flags set";
                                            logger.error("PrimaryResult has both Successful and shouldRetryOnSecondary flags set");
                                        } else if (response.isSuccessful) {
                                            logger.debug("QuorumNotSelected: ReadPrimary successful");
                                            try {
                                                            return Flux.just(response.getResponse());
                                            } catch (CosmosException e) {
                                                return Flux.error(e);
                                            }
                                        } else if (response.shouldRetryOnSecondary) {
                                            shouldRetryOnSecondary.v = true;
                                            logger.warn("QuorumNotSelected: ReadPrimary did not succeed. Will retry on secondary.");
                                            hasPerformedReadFromPrimary.v = true;
                                        } else {
                                            logger.warn("QuorumNotSelected: Could not get successful response from ReadPrimary");
                                            return Flux.error(new GoneException(String.format(RMResources.ReadQuorumNotMet, readQuorumValue)));
                                        }

                                                    return Flux.empty();

                                    }
                                );

                            default:
                                logger.error("Unknown ReadQuorum result {}", secondaryQuorumReadResult.quorumResult.toString());
                                return Flux.error(new InternalServerErrorException(RMResources.InternalServerError));
                        }

                    });
            }).repeat(maxNumberOfReadQuorumRetries)
                   .takeUntil(dummy -> !shouldRetryOnSecondary.v)
                .concatWith(Flux.defer(() -> {
                       logger.warn("Could not complete read quorum with read quorum value of {}", readQuorumValue);

                    return Flux.error(new GoneException(
                           String.format(
                               RMResources.ReadQuorumNotMet,
                               readQuorumValue)));
                   }))
                   .take(1)
                   .single();
    }

    private Mono<ReadQuorumResult> readQuorumAsync(
        RxDocumentServiceRequest entity,
        int readQuorum,
        boolean includePrimary,
        ReadMode readMode) {
        if (entity.requestContext.timeoutHelper.isElapsed()) {
            return Mono.error(new GoneException());
        }

        return ensureQuorumSelectedStoreResponse(entity, readQuorum, includePrimary, readMode).flatMap(
            res -> {
                if (res.getLeft() != null) {
                    // no need for barrier
                    return Mono.just(res.getKey());
                }

                long readLsn = res.getValue().getValue0();
                long globalCommittedLSN = res.getValue().getValue1();
                StoreResult storeResult = res.getValue().getValue2();
                List<String> storeResponses = res.getValue().getValue3();

                // ReadBarrier required
                Mono<RxDocumentServiceRequest> barrierRequestObs = BarrierRequestHelper.createAsync(this.diagnosticsClientContext, entity, this.authorizationTokenProvider, readLsn, globalCommittedLSN);
                return barrierRequestObs.flatMap(
                    barrierRequest -> {
                        Mono<Boolean> waitForObs = this.waitForReadBarrierAsync(barrierRequest, false, readQuorum, readLsn, globalCommittedLSN, readMode);
                        return waitForObs.flatMap(
                            waitFor -> {
                                if (!waitFor) {
                                    return Mono.just(new ReadQuorumResult(
                                        entity.requestContext.requestChargeTracker,
                                        ReadQuorumResultKind.QuorumSelected,
                                        readLsn,
                                        globalCommittedLSN,
                                        storeResult,
                                        storeResponses));
                                }

                                return Mono.just(new ReadQuorumResult(
                                    entity.requestContext.requestChargeTracker,
                                    ReadQuorumResultKind.QuorumMet,
                                    readLsn,
                                    globalCommittedLSN,
                                    storeResult,
                                    storeResponses));
                            }
                        );
                    }
                );
            }
        );
    }

    private Mono<Pair<ReadQuorumResult, Quadruple<Long, Long, StoreResult, List<String>>>> ensureQuorumSelectedStoreResponse(RxDocumentServiceRequest entity, int readQuorum, boolean includePrimary, ReadMode readMode) {

        if (entity.requestContext.quorumSelectedStoreResponse == null) {
            Mono<List<StoreResult>> responseResultObs = this.storeReader.readMultipleReplicaAsync(
                entity, includePrimary, readQuorum, true /*required valid LSN*/, false, readMode);

            return responseResultObs.flatMap(
                responseResult -> {
                    List<String> storeResponses = responseResult.stream().map(response -> response.toString()).collect(Collectors.toList());
                    int responseCount = (int) responseResult.stream().filter(response -> response.isValid).count();
                    if (responseCount < readQuorum) {
                        return Mono.just(Pair.of(new ReadQuorumResult(entity.requestContext.requestChargeTracker,
                            ReadQuorumResultKind.QuorumNotSelected,
                            -1, -1, null, storeResponses), null));
                    }

                    //either request overrides consistency level with strong, or request does not override and account default consistency level is strong
                    boolean isGlobalStrongReadCandidate =
                        (ReplicatedResourceClient.isGlobalStrongEnabled() && this.serviceConfigReader.getDefaultConsistencyLevel() == ConsistencyLevel.STRONG) &&
                            (entity.requestContext.originalRequestConsistencyLevel == null || entity.requestContext.originalRequestConsistencyLevel == ConsistencyLevel.STRONG);

                    ValueHolder<Long> readLsn = new ValueHolder<>(-1L);
                    ValueHolder<Long> globalCommittedLSN = new ValueHolder<>(-1L);
                    ValueHolder<StoreResult> storeResult = new ValueHolder<>(null);

                    if (this.isQuorumMet(
                        responseResult,
                        readQuorum,
                        false,
                        isGlobalStrongReadCandidate,
                        readLsn,
                        globalCommittedLSN,
                        storeResult)) {
                        return Mono.just(Pair.of(new ReadQuorumResult(
                            entity.requestContext.requestChargeTracker,
                            ReadQuorumResultKind.QuorumMet,
                            readLsn.v,
                            globalCommittedLSN.v,
                            storeResult.v,
                            storeResponses), null));
                    }

                    // at this point, if refresh were necessary, we would have refreshed it in ReadMultipleReplicaAsync
                    // so set to false here to avoid further refrehses for this request.
                    entity.requestContext.forceRefreshAddressCache = false;

                    Quadruple<Long, Long, StoreResult, List<String>> state = Quadruple.with(readLsn.v, globalCommittedLSN.v, storeResult.v, storeResponses);
                    return Mono.just(Pair.of(null, state));
                }
            );
        } else {

            ValueHolder<Long> readLsn = ValueHolder.initialize(entity.requestContext.quorumSelectedLSN);
            ValueHolder<Long> globalCommittedLSN = ValueHolder.initialize(entity.requestContext.globalCommittedSelectedLSN);
            ValueHolder<StoreResult> storeResult = ValueHolder.initialize(entity.requestContext.quorumSelectedStoreResponse);
            List<String> storeResponses = entity.requestContext.storeResponses;
            Quadruple<Long, Long, StoreResult, List<String>> state = Quadruple.with(readLsn.v, globalCommittedLSN.v, storeResult.v, storeResponses);

            return Mono.just(Pair.of(null, state));
        }
    }

    /**
     * READ and get response from Primary
     *
     * @param entity
     * @param readQuorum
     * @param useSessionToken
     * @return
     */
    private Mono<ReadPrimaryResult> readPrimaryAsync(
        RxDocumentServiceRequest entity,
        int readQuorum,
        boolean useSessionToken) {
        if (entity.requestContext.timeoutHelper.isElapsed()) {
            return Mono.error(new GoneException());
        }

        // We would have already refreshed address before reaching here. Avoid performing here.
        entity.requestContext.forceRefreshAddressCache = false;

        Mono<StoreResult> storeResultObs = this.storeReader.readPrimaryAsync(
            entity, true /*required valid LSN*/, useSessionToken);

        return storeResultObs.flatMap(
            storeResult -> {
                if (!storeResult.isValid) {
                    try {
                        return Mono.error(storeResult.getException());
                    } catch (InternalServerErrorException e) {
                        return Mono.error(e);
                    }
                }

                if (storeResult.currentReplicaSetSize <= 0 || storeResult.lsn < 0 || storeResult.quorumAckedLSN < 0) {
                    String message = String.format(
                        "INVALID value received from response header. CurrentReplicaSetSize %d, StoreLSN %d, QuorumAckedLSN %d",
                        storeResult.currentReplicaSetSize, storeResult.lsn, storeResult.quorumAckedLSN);

                    // might not be returned if primary is still building the secondary replicas (during churn)
                    logger.error(message);

                    // throw exception instead of returning inconsistent result.
                    return Mono.error(new GoneException(String.format(RMResources.ReadQuorumNotMet, readQuorum)));

                }

                if (storeResult.currentReplicaSetSize > readQuorum) {
                    logger.warn(
                        "Unexpected response. Replica Set size is {} which is greater than min value {}", storeResult.currentReplicaSetSize, readQuorum);
                    return Mono.just(new ReadPrimaryResult(entity.requestContext.requestChargeTracker,  /*isSuccessful */ false,
                        /* shouldRetryOnSecondary: */ true, /* response: */ null));
                }

                // To accommodate for store latency, where an LSN may be acked by not persisted in the store, we compare the quorum acked LSN and store LSN.
                // In case of sync replication, the store LSN will follow the quorum committed LSN
                // In case of async replication (if enabled for bounded staleness), the store LSN can be ahead of the quorum committed LSN if the primary is able write to faster than secondary acks.
                // We pick higher of the 2 LSN and wait for the other to reach that LSN.
                if (storeResult.lsn != storeResult.quorumAckedLSN) {
                    logger.warn("Store LSN {} and quorum acked LSN {} don't match", storeResult.lsn, storeResult.quorumAckedLSN);
                    long higherLsn = storeResult.lsn > storeResult.quorumAckedLSN ? storeResult.lsn : storeResult.quorumAckedLSN;

                    Mono<RxDocumentServiceRequest> waitForLsnRequestObs = BarrierRequestHelper.createAsync(this.diagnosticsClientContext, entity, this.authorizationTokenProvider, higherLsn, null);
                    return waitForLsnRequestObs.flatMap(
                        waitForLsnRequest -> {
                            Mono<PrimaryReadOutcome> primaryWaitForLsnResponseObs = this.waitForPrimaryLsnAsync(waitForLsnRequest, higherLsn, readQuorum);
                            return primaryWaitForLsnResponseObs.map(
                                primaryWaitForLsnResponse -> {
                                    if (primaryWaitForLsnResponse == PrimaryReadOutcome.QuorumNotMet) {
                                        return new ReadPrimaryResult(
                                            entity.requestContext.requestChargeTracker, /*(isSuccessful: */ false, /* shouldRetryOnSecondary: */ false, /* response: */null);
                                    } else if (primaryWaitForLsnResponse == PrimaryReadOutcome.QuorumInconclusive) {
                                        return new ReadPrimaryResult(
                                            entity.requestContext.requestChargeTracker, /* isSuccessful: */ false, /* shouldRetryOnSecondary: */
                                            true, /* response: */ null);
                                    }

                                    return new ReadPrimaryResult(
                                        entity.requestContext.requestChargeTracker, /* isSuccessful: */ true, /* shouldRetryOnSecondary: */ false, /*response: */ storeResult);
                                }
                            );
                        }
                    );
                }

                return Mono.just(new ReadPrimaryResult(
                    /* requestChargeTracker: */ entity.requestContext.requestChargeTracker, /* isSuccessful: */ true, /* shouldRetryOnSecondary:*/  false,
                    /*response: */ storeResult));
            }
        );
    }

    private Mono<PrimaryReadOutcome> waitForPrimaryLsnAsync(
        RxDocumentServiceRequest barrierRequest,
        long lsnToWaitFor,
        int readQuorum) {

        return Flux.defer(() -> {
            if (barrierRequest.requestContext.timeoutHelper.isElapsed()) {
                return Flux.error(new GoneException());
            }

            // We would have already refreshed address before reaching here. Avoid performing here.
            barrierRequest.requestContext.forceRefreshAddressCache = false;

            Mono<StoreResult> storeResultObs = this.storeReader.readPrimaryAsync(barrierRequest, true /*required valid LSN*/, false);

            return storeResultObs.flux().flatMap(
                storeResult -> {
                    if (!storeResult.isValid) {
                        try {
                                return Flux.error(storeResult.getException());
                        } catch (InternalServerErrorException e) {
                            return Flux.error(e);
                        }
                    }

                    if (storeResult.currentReplicaSetSize > readQuorum) {
                        logger.warn(
                            "Unexpected response. Replica Set size is {} which is greater than min value {}", storeResult.currentReplicaSetSize, readQuorum);
                            return Flux.just(PrimaryReadOutcome.QuorumInconclusive);
                    }

                    // Java this will move to the repeat logic
                    if (storeResult.lsn < lsnToWaitFor || storeResult.quorumAckedLSN < lsnToWaitFor) {
                        logger.warn(
                            "Store LSN {} or quorum acked LSN {} are lower than expected LSN {}", storeResult.lsn, storeResult.quorumAckedLSN, lsnToWaitFor);

                            return Flux.just(0L).delayElements(Duration.ofMillis(delayBetweenReadBarrierCallsInMs)).flatMap(dummy -> Flux.empty());
                    }

                        return Flux.just(PrimaryReadOutcome.QuorumMet);
                }
            );
        }).repeat(maxNumberOfPrimaryReadRetries)  // Loop for store and quorum LSN to match
                   .defaultIfEmpty(PrimaryReadOutcome.QuorumNotMet)
                   .take(1)
                   .single();

    }

    private Mono<Boolean> waitForReadBarrierAsync(
        RxDocumentServiceRequest barrierRequest,
        boolean allowPrimary,
        final int readQuorum,
        final long readBarrierLsn,
        final long targetGlobalCommittedLSN,
        ReadMode readMode) {
        AtomicInteger readBarrierRetryCount = new AtomicInteger(maxNumberOfReadBarrierReadRetries);
        AtomicInteger readBarrierRetryCountMultiRegion = new AtomicInteger(maxBarrierRetriesForMultiRegion);

        AtomicLong maxGlobalCommittedLsn = new AtomicLong(0);

        return Flux.defer(() -> {

            if (barrierRequest.requestContext.timeoutHelper.isElapsed()) {
                return Flux.error(new GoneException());
            }

            Mono<List<StoreResult>> responsesObs = this.storeReader.readMultipleReplicaAsync(
                barrierRequest, allowPrimary, readQuorum,
                true /*required valid LSN*/, false /*useSessionToken*/, readMode, false /*checkMinLSN*/, true /*forceReadAll*/);

            return responsesObs.flux().flatMap(
                responses -> {

                    long maxGlobalCommittedLsnInResponses = responses.size() > 0 ? responses.stream()
                                                                                .mapToLong(response -> response.globalCommittedLSN).max().getAsLong() : 0;

                    if ((responses.stream().filter(response -> response.lsn >= readBarrierLsn).count() >= readQuorum) &&
                        (!(targetGlobalCommittedLSN > 0) || maxGlobalCommittedLsnInResponses >= targetGlobalCommittedLSN)) {
                            return Flux.just(true);
                    }

                    maxGlobalCommittedLsn.set(maxGlobalCommittedLsn.get() > maxGlobalCommittedLsnInResponses ?
                        maxGlobalCommittedLsn.get() : maxGlobalCommittedLsnInResponses);

                    //only refresh on first barrier call, set to false for subsequent attempts.
                    barrierRequest.requestContext.forceRefreshAddressCache = false;

                    if (readBarrierRetryCount.decrementAndGet() == 0) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("QuorumReader: waitForReadBarrierAsync - Last barrier for single-region requests. Responses: {}",
                                         JavaStreamUtils.toString(responses, "; "));
                        }
                        // retries exhausted
                            return Flux.just(false);

                    } else {
                        // delay
                        //await Task.Delay(QuorumReader.delayBetweenReadBarrierCallsInMs);
                            return Flux.empty();

                    }
                }
            );
        }).repeatWhen(obs -> obs.flatMap(aVoid -> Flux.just(0L).delayElements(Duration.ofMillis(delayBetweenReadBarrierCallsInMs))))
                .take(1) // Retry loop
                   .flatMap(barrierRequestSucceeded ->
                        Flux.defer(() -> {

                           if (barrierRequestSucceeded) {
                                return Flux.just(true);
                           }

                           // we will go into global strong read barrier mode for global strong requests after regular barrier calls have been exhausted.
                           if (targetGlobalCommittedLSN > 0) {
                                return Flux.defer(() -> {

                                   if (barrierRequest.requestContext.timeoutHelper.isElapsed()) {
                                        return Flux.error(new GoneException());
                                   }

                                   Mono<List<StoreResult>> responsesObs = this.storeReader.readMultipleReplicaAsync(
                                       barrierRequest, allowPrimary, readQuorum,
                                       true /*required valid LSN*/, false /*useSessionToken*/, readMode, false /*checkMinLSN*/, true /*forceReadAll*/);

                                    return responsesObs.flux().flatMap(
                                       responses -> {
                                           long maxGlobalCommittedLsnInResponses = responses.size() > 0 ? responses.stream()
                                                                                .mapToLong(response -> response.globalCommittedLSN).max().getAsLong() : 0;

                                           if ((responses.stream().filter(response -> response.lsn >= readBarrierLsn).count() >= readQuorum) &&
                                               maxGlobalCommittedLsnInResponses >= targetGlobalCommittedLSN) {
                                                    return Flux.just(true);
                                           }

                                           maxGlobalCommittedLsn.set(maxGlobalCommittedLsn.get() > maxGlobalCommittedLsnInResponses ?
                                               maxGlobalCommittedLsn.get() : maxGlobalCommittedLsnInResponses);

                                           //trace on last retry.
                                           if (readBarrierRetryCountMultiRegion.getAndDecrement() == 0) {
                                               if (logger.isDebugEnabled()) {
                                                   logger.debug("QuorumReader: waitForReadBarrierAsync - Last barrier for mult-region strong requests. Responses: {}",
                                                                JavaStreamUtils.toString(responses, "; "));
                                               }
                                               return Flux.just(false);
                                           } else {
                                               return Flux.empty();
                                           }
                                       }
                                   );

                               }).repeatWhen(obs -> obs.flatMap(aVoid -> {

                                       if ((maxBarrierRetriesForMultiRegion - readBarrierRetryCountMultiRegion.get()) > maxShortBarrierRetriesForMultiRegion) {
                                                      return Flux.just(0L).delayElements(Duration.ofMillis(barrierRetryIntervalInMsForMultiRegion));
                                       } else {
                                                      return Flux.just(0L).delayElements(Duration.ofMillis(shortBarrierRetryIntervalInMsForMultiRegion));
                                       }

                                   })
                                   // stop predicate, simulating while loop
                                ).take(1);
                           }

                            return Flux.empty();
                       })).
                       concatWith(
                                Flux.defer(() -> {
                               logger.debug("QuorumReader: waitForReadBarrierAsync - TargetGlobalCommittedLsn: {}, MaxGlobalCommittedLsn: {}.", targetGlobalCommittedLSN, maxGlobalCommittedLsn);
                                    return Flux.just(false);
                           })
                       ).take(1).single();
    }

    private boolean isQuorumMet(
        List<StoreResult> readResponses,
        int readQuorum,
        boolean isPrimaryIncluded,
        boolean isGlobalStrongRead,
        ValueHolder<Long> readLsn,
        ValueHolder<Long> globalCommittedLSN,
        ValueHolder<StoreResult> selectedResponse) {
        long maxLsn = 0;
        long minLsn = Long.MAX_VALUE;
        int replicaCountMaxLsn = 0;
        List<StoreResult> validReadResponses = readResponses.stream().filter(response -> response.isValid).collect(Collectors.toList());
        int validResponsesCount = validReadResponses.size();

        if (validResponsesCount == 0) {
            readLsn.v = 0l;
            globalCommittedLSN.v = -1l;
            selectedResponse.v = null;

            return false;
        }

        assert !validReadResponses.isEmpty();
        long numberOfReadRegions = validReadResponses.stream().map(res -> res.numberOfReadRegions).max(Comparator.naturalOrder()).get();
        boolean checkForGlobalStrong = isGlobalStrongRead && numberOfReadRegions > 0;

        // Pick any R replicas in the response and check if they are at the same LSN
        for (StoreResult response : validReadResponses) {
            if (response.lsn == maxLsn) {
                replicaCountMaxLsn++;
            } else if (response.lsn > maxLsn) {
                replicaCountMaxLsn = 1;
                maxLsn = response.lsn;
            }

            if (response.lsn < minLsn) {
                minLsn = response.lsn;
            }
        }

        final long maxLsnFinal = maxLsn;
        selectedResponse.v = validReadResponses.stream().filter(s -> s.lsn == maxLsnFinal).findFirst().get();

        readLsn.v = selectedResponse.v.itemLSN == -1 ?
            maxLsn : Math.min(selectedResponse.v.itemLSN, maxLsn);
        globalCommittedLSN.v = checkForGlobalStrong ? readLsn.v : -1l;

        long maxGlobalCommittedLSN = validReadResponses.stream().mapToLong(res -> res.globalCommittedLSN).max().getAsLong();

        logger.debug("QuorumReader: MaxLSN {} ReplicaCountMaxLSN {} bCheckGlobalStrong {} MaxGlobalCommittedLSN {} NumberOfReadRegions {} SelectedResponseItemLSN {}",
            maxLsn, replicaCountMaxLsn, checkForGlobalStrong, maxGlobalCommittedLSN, numberOfReadRegions, selectedResponse.v.itemLSN);

        // quorum is met if one of the following conditions are satisfied:
        // 1. readLsn is greater than zero
        //    AND the number of responses that have the same LSN as the selected response is greater than or equal to the read quorum
        //    AND if applicable, the max GlobalCommittedLSN of all responses is greater than or equal to the lsn of the selected response.

        // 2. if the request is a point-read request,
        //    AND there are more than one response in the readResponses
        //    AND the LSN of the returned resource of the selected response is less than or equal to the minimum lsn of the all the responses,
        //    AND if applicable, the LSN of the returned resource of the selected response is less than or equal to the minimum globalCommittedLsn of all the responses.
        //    This means that the returned resource is old enough to have been committed by at least all the received responses,
        //    which should be larger than or equal to the read quorum, which therefore means we have strong consistency.
        boolean isQuorumMet = false;

        if ((readLsn.v > 0 && replicaCountMaxLsn >= readQuorum) &&
            (!checkForGlobalStrong || maxGlobalCommittedLSN >= maxLsn)) {
            isQuorumMet = true;
        }

        if (!isQuorumMet && validResponsesCount >= readQuorum && selectedResponse.v.itemLSN != -1 &&
            (minLsn != Long.MAX_VALUE && selectedResponse.v.itemLSN <= minLsn) &&
            (!checkForGlobalStrong || (selectedResponse.v.itemLSN <= maxGlobalCommittedLSN))) {
            isQuorumMet = true;
        }

        return isQuorumMet;
    }

    private enum ReadQuorumResultKind {
        QuorumMet,
        QuorumSelected,
        QuorumNotSelected
    }

    private abstract class ReadResult {
        private final StoreResult response;
        private final RequestChargeTracker requestChargeTracker;

        protected ReadResult(RequestChargeTracker requestChargeTracker, StoreResult response) {
            this.requestChargeTracker = requestChargeTracker;
            this.response = response;
        }

        public StoreResponse getResponse() {
            if (!this.isValidResult()) {
                logger.error("getResponse called for invalid result");
                throw new InternalServerErrorException(RMResources.InternalServerError);
            }

            return this.response.toResponse(requestChargeTracker);
        }

        protected abstract boolean isValidResult();
    }

    private class ReadQuorumResult extends ReadResult {
        public ReadQuorumResult(
            RequestChargeTracker requestChargeTracker,
            ReadQuorumResultKind QuorumResult,
            long selectedLsn,
            long globalCommittedSelectedLsn,
            StoreResult selectedResponse,
            List<String> storeResponses) {
            super(requestChargeTracker, selectedResponse);

            this.quorumResult = QuorumResult;
            this.selectedLsn = selectedLsn;
            this.globalCommittedSelectedLsn = globalCommittedSelectedLsn;
            this.selectedResponse = selectedResponse;
            this.storeResponses = storeResponses;
        }

        public final ReadQuorumResultKind quorumResult;

        /**
         * Response selected to lock on the LSN. This is the response with the highest LSN
         */
        public final StoreResult selectedResponse;

        /**
         * ALL store responses from Quorum READ.
         */
        public final List<String> storeResponses;

        public final long selectedLsn;

        public final long globalCommittedSelectedLsn;

        protected boolean isValidResult() {
            return this.quorumResult == ReadQuorumResultKind.QuorumMet || this.quorumResult == ReadQuorumResultKind.QuorumSelected;
        }
    }

    private class ReadPrimaryResult extends ReadResult {
        public final boolean shouldRetryOnSecondary;
        public final boolean isSuccessful;

        public ReadPrimaryResult(RequestChargeTracker requestChargeTracker, boolean isSuccessful, boolean shouldRetryOnSecondary, StoreResult response) {
            super(requestChargeTracker, response);
            this.isSuccessful = isSuccessful;
            this.shouldRetryOnSecondary = shouldRetryOnSecondary;
        }

        protected boolean isValidResult() {
            return isSuccessful;
        }
    }

    private enum PrimaryReadOutcome {
        QuorumNotMet,       // Primary LSN is not committed.
        QuorumInconclusive, // Secondary replicas are available. Must read R secondary's to deduce current quorum.
        QuorumMet,
    }
}


I really have no idea what this site is exactly for or if you are looking for any more information, but I came across it on a search for a family member. I see that you have an Andreas Foeh listed in here and one of his daughters. Andreas Foeh was my great-great granfather, and I have pages from our family Bible, including the whole genealogy, if you are interested. I have left my email address.


text:
American football quarterback
Theismann in 2003
(1949-09-09) September 9, 1949 (age 69)
6 ft 0 in (1.83 m)
(South River, New Jersey)
Toronto Argonauts (1971–1973)
Washington Redskins (1974–1985)
Super Bowl champion (XVII)
NFL Most Valuable Player (1983)
2× Pro Bowl (1982, 1983)
First-team All-Pro (1983)
NFL Offensive Player of the Year (1983)
Bert Bell Award (1982)
2× CFL All-Star (1971, 1973)
NFL Man of the Year (1982)
70 Greatest Redskins
Washington Redskins Ring of Fame
First-team All-American (1970)
TD–INT:
Passing yards:
Passer rating:
Career CFL statistics
College Football Hall of Fame
Joseph Robert "Joe" Theismann (born September 9, 1949) is a former professional gridiron football player, sports commentator, corporate speaker and restaurateur. He played quarterback in the National Football League (NFL) and Canadian Football League (CFL). Theismann spent 12 seasons with the Washington Redskins, where he was a two-time Pro Bowler and helped the team to consecutive Super Bowl appearances, winning Super Bowl XVII and losing Super Bowl XVIII. He was inducted into the College Football Hall of Fame in 2003.
Following his retirement from football in 1985 after a career-ending injury, Theismann worked as a sportscaster and an analyst on pro football broadcasts with ESPN for nearly 20 years.[1] He primarily partnered with Mike Patrick, for the network's Sunday Night Football package and for one season of Monday Night Football with Mike Tirico and Tony Kornheiser. Theismann also worked as a color analyst on NFL Network's Thursday Night Football package with play-by-play voice Bob Papa and Matt Millen. Theismann also co-hosts the network's weekly show Playbook.
Since 2011, he has worked on the Redskins preseason television broadcast team.[2] Additionally, he works on the NFL Network on a variety of programs, primarily as an analyst.[3]
Theismann is the owner of Theismann's Restaurant and Bar[4] in Alexandria, Virginia, founded in 1975.[5] He also performs as a speaker for corporate events, speaking on topics such as leadership and self-motivation.[6][7]
3.1 Canadian Football League
3.2 National Football League
3.2.1 Lawrence Taylor tackle
3.3 NFL career statistics
3.4 Redskins franchise records
4 Broadcast and acting career
4.1 Acting appearances
Theismann was born to Austrian Joseph John Theismann who "ran a gas station and worked in his brother's liquor store."[1] His Hungarian mother, Olga Tóbiás[8] worked for Johnson & Johnson until her retirement. Theismann was raised in South River, New Jersey,[9] and attended South River High School, where he lettered in baseball, basketball, and football.[1] He was a high school teammate of Drew Pearson. Theismann accepted a college football scholarship to attend the University of Notre Dame.
College career[edit]
At Notre Dame, Theismann became the starting quarterback in his sophomore year, after Terry Hanratty was injured late in the season.[10] In the three remaining games in the regular season, he led the Irish to two wins and a tie. In 1969, Theismann led the Irish to a number five ranking, but lost to the University of Texas in the 1970 Cotton Bowl Classic, 21–17. The next year, the Irish had a 10–1 record, a number two ranking, and won against Texas in the 1971 Cotton Bowl Classic, 24–11.[10] That year, Theismann was an All-American and an Academic All-American, and was in contention for the Heisman Trophy. Theismann, whose last name was actually pronounced "Theesman", recounted in 2007 that it was Notre Dame publicity man Roger Valdiserri who insisted that he change the pronunciation of his name to rhyme with "Heisman",[11] but he finished second to Jim Plunkett of Stanford University.[1][10][12]
Theismann set school records for passing yards in a season (2,429) and touchdowns in a season (16).[10] He also set a school record for passing yards in a game (526) and completions in a game (33) while playing against the University of Southern California in a torrential downpour in 1970, which they lost 38–28.[13] As a starting quarterback, Theismann compiled a 20–3–2 record while throwing for 4,411 yards and 31 touchdowns.[10] His 4,411 passing yards rank fifth on Notre Dame's career passing list.[13]
Theismann was inducted into the College Football Hall of Fame in 2003.[10] He was the eighth Notre Dame quarterback enshrined into the hall, joining former Heisman Trophy winners Angelo Bertelli, John Lujack, and Paul Hornung.[13]
Canadian Football League[edit]
Theismann was selected in the fourth round of the 1971 NFL Draft by the Miami Dolphins and in the 39th round of the 1971 Major League Baseball Draft by the Minnesota Twins.[14] After prolonged negotiations with the Dolphins failed, Theismann elected to sign with the Toronto Argonauts of the Canadian Football League for $50,000 per season. In his rookie year, Theismann quarterbacked the Argonauts to a 10–4 record, led the league's Eastern Conference in passing statistics and won a berth in the Grey Cup championship game in Vancouver, British Columbia versus the Calgary Stampeders (59th Grey Cup). A fumble late in the fourth quarter by Argonaut running back Leon McQuay close to the goal line cost the Argonauts what would have been their first Grey Cup victory since 1952.
In 1971, Theismann completed 148 of 278 passes for 2,440 yards and 17 touchdowns (with 21 interceptions). His 1972 season was shortened by injury, but he hit 77 of 127 passes for 1,157 yards and ten touchdowns. During his last CFL season, 1973, 157 of his 274 passes were complete, for 2,496 yards and both 13 touchdowns and interceptions. He was an all-star in both 1971 and 1973.
National Football League[edit]
Theismann at practice
In 1974, the Washington Redskins obtained Theismann's rights from the Dolphins in exchange for the team's first-round draft pick in 1976 (the Dolphins selected linebacker Larry Gordon with the pick).[15] Theismann left the CFL and joined the Redskins, where he served as the team's punt returner during his first season.[16] In 1978, Theismann became the Redskins' starting quarterback, succeeding Billy Kilmer.
In 1982, Theismann led the Redskins to their first championship in 40 years against the Dolphins in Super Bowl XVII. He threw two touchdowns and, with the Redskins trailing 17–13 in the third quarter, made arguably the most important defensive play of the game—after his pass was deflected by Dolphins lineman Kim Bokamper, causing what appeared to be an interception and sure touchdown (which would have given Miami a two-score lead and effectively taken MVP running back John Riggins out of the game), Theismann himself was able to knock the ball out of Bokamper's hands,[17] keeping the score close enough for Washington to stick to the run-heavy strategy that would eventually lead to victory. He also led the team to an appearance in Super Bowl XVIII the following year, and would go on to set several Redskins franchise records, including most career passing attempts (3,602), most career passing completions (2,044) and most career passing yards (25,206), while also throwing 160 touchdown passes, with 138 interceptions. On the ground, he rushed for 1,815 yards and 17 touchdowns. He was named NFL MVP in 1983 by four organizations.[16] He earned the Player of the Game Award in the second of his two Pro Bowl appearances. Theismann also punted once in his career, for one yard against the Chicago Bears.[16][18]
Joe Theismann's NFL rings (2006); his 1983 NFC Championship ring (left), and his 1982 Super Bowl XVII Championship ring (right)
In an era when most quarterbacks had long since used variations of a double-bar facemask (or even triple-bar facemasks) that afforded more protection, Theismann refused to use anything but a one-bar face mask throughout his career.[19] However, on at least one occasion, Theismann wore a helmet with a more standard facemask. Substituting for an ineffective Billy Kilmer against the Dallas Cowboys on October 16, 1977, Theismann entered the game wearing a facemask similar to the style worn by Kenny Stabler at the time.[20]
Lawrence Taylor tackle[edit]
Theismann's career ended on November 18, 1985 when he suffered a comminuted compound fracture of his leg while being sacked by linebackers Lawrence Taylor and Harry Carson during a Monday Night Football game telecast by ABC from RFK Stadium in Washington, D.C..
The injury was later voted the NFL's "Most Shocking Moment in History" by viewers in an ESPN poll, and the tackle was ultimately dubbed "The Hit That No One Who Saw It Can Ever Forget" by The Washington Post.[21]
The game's score was 7-7 in the second quarter when the Redskins attempted to run a "flea-flicker" play; Theismann had handed off to fullback John Riggins, who subsequently lateralled the ball back to the quarterback. The Giants' defense, however, was not fooled, and they tried to blitz Theismann. As Taylor pulled Theismann down, Taylor's knee came down and drove straight into Theismann's lower right leg, fracturing both the tibia and the fibula as Giants linebackers Gary Reasons and Harry Carson also joined Taylor in the sack.[22]
The pain was unbelievable, it snapped like a breadstick. It sounded like two muzzled gunshots off my left shoulder. Pow, pow!" Theismann said during a 2005 interview.[23] "It was at that point, I also found out what a magnificent machine the human body is. Almost immediately, from the knee down, all the feeling was gone in my right leg. The endorphins had kicked in, and I was not in pain."[21]
As Theismann lay on the field, a horrified Taylor screamed and waved for emergency medical technicians. Initially, many Redskins personnel thought Taylor's screaming and pointing directed at their sideline was him taunting over the fact that he had successfully stopped their play, and it was a few moments later that they realized Theismann was injured. (The Monday Night Football announcer team of Frank Gifford, O. J. Simpson and Joe Namath had correctly inferred from the start that Taylor was calling for help.)
While initially only the players on the field could see the extent of the damage to Theismann's leg, the reverse-angle instant replay (shown multiple times) provided a clearer view of what had actually happened: Theismann's lower leg bones were broken midway between his knee and his ankle, such that his leg from his foot to his mid-shin was lying flat against the ground while the upper part of his shin up to his knee was at a 45-degree angle to the lower part of his leg.
The compound fracture of the tibia led to insufficient bone growth during Theismann's recovery, leaving his right leg shorter than his left. As a result, the injury forced Theismann into retirement at the age of 36.
Theismann has never blamed Lawrence Taylor for his injury; indeed, while Taylor has apologized to Theismann many times, the quarterback insists that the Giant was merely doing his job.
Theismann's injury was highlighted in the film The Blind Side as the reason that, after the quarterback, one of the highest paid football players is the left tackle, who protects a right-handed quarterback's blind side.[24] The same injury occurred exactly 33 years later to another Redskins quarterback, Alex Smith, on November 18, 2018, against the Houston Texans when cornerback Kareem Jackson and defensive end J.J. Watt sacked Smith.
NFL career statistics[edit]
Led the league
Won the Super Bowl
AP NFL MVP
Bold Career high
Regular season[16]
1974 WAS 9 0 9 11 81.8 145 1 0 69 13.2 149.1 2 11
1975 WAS 14 0 10 22 45.5 96 1 3 30 4.4 33.7 2 18
1976 WAS 14 5 79 163 48.5 1,036 8 10 44 6.4 59.8 22 172
1977 WAS 14 6 84 182 46.2 1,097 7 9 52 6.0 57.9 30 241
1978 WAS 16 14 187 390 47.9 2,593 13 18 63 6.6 61.6 42 391
1982 WAS 9 9 161 252 63.9 2,033 13 9 78 8.1 91.3 30 223
1985 WAS 11 11 167 301 55.5 1,774 8 16 55 5.9 59.6 37 314
Redskins franchise records[edit]
Most career wins by a quarterback (87) [25]
Most career passing yards (25,206) [26]
Most career passing completions (2,044)
Most career passing attempts (3,602)
Broadcast and acting career[edit]
In 1985, Theismann helped call Super Bowl XIX for ABC alongside Frank Gifford and Don Meredith, becoming only the second player to do commentary on a Super Bowl telecast while still an active player at the time (the first was Jack Kemp when he helped call Super Bowl II for CBS). Theismann served as a color commentator on regional CBS NFL coverage in 1986 and 1987, then worked on ESPN's Sunday Night Football telecasts from 1988-2005, and on their Monday Night Football coverage in 2006.
In addition to covering football, Theismann hosted the first half of the first season of American Gladiators in 1989.
On March 26, 2007, ESPN announced that Ron Jaworski would replace Theismann in the Monday Night Football booth. Theismann rejected an offer to work on the network's college football coverage. He has since done a number of Washington Redskins pre-season games on CSN. On September 16, 2009, the NFL Network announced that Theismann would analyze game films on the show Playbook, airing Thursday and Friday nights at 6 p.m. Eastern.
On January 9, 2010, Theismann and his former head coach Joe Gibbs served as color commentators, along with play-by-play man Tom Hammond, for the Saturday AFC Wild Card Game between the New York Jets and the Cincinnati Bengals.
On September 6, 2010, NFL network announced that they had added Theismann to their Thursday Night Football broadcast crew alongside Bob Papa and Matt Millen.[27] The grouping lasted one season. He also co-hosted NFL games on NBC in 2010,[28] and co-hosted NFL Network's No Huddle in 2011.[29]
Acting appearances[edit]
Theismann has occasionally acted, although most appearances are as himself or as himself in a fictional context. He does have several TV and movie appearances, including the B.J. and the Bear (1981), Cannonball Run II (1984), and The Man from Left Field (1993).[30]
More recently, Theismann appeared as himself as part as a buyer group for the fictional "New York Hawks" football team on the TV series Necessary Roughness (2013) and on the post-Super Bowl episode "Operation: Broken Feather" of Brooklyn Nine-Nine (2014). On September 5, 2014, Theismann was honored by the Ride of Fame as they christened a double decker sightseeing bus in Washington DC dedicated to him and his achievements.[31] His most recent acting appearances were in movies for the Hallmark Channel. In 2016's "Love on the Sidelines," he appeared as the father of an injured professional football player. In 2019's "SnowComing," he played an agent for professional athletes (in particular, a professional football player.) Theismann has acted as a national spokesman for several companies including Colonial Penn Life Insurance Company and for Super Beta Prostate.[32][33]
Theismann fathered three children—Joseph Jr., Amy, and Patrick—with his first wife, the former Shari Brown. Amy died in 2016 at the age of 43.[34] Soon after the couple divorced in 1984, Theismann began a seven-year relationship, including a brief engagement, with television personality Cathy Lee Crosby.[35] Early in 1991, Crosby sued for $4.5 million,[36] touching off a counter suit. The suits were settled several months later.[37]
His second marriage, to former Miss Connecticut and Miss America contestant Jeanne Caruso, ended in divorce after three years in 1995. Theismann was ordered to pay nearly $1 million of marital property and $3,500 a month in alimony.[38]
Theismann is currently married to the former Robin Smith, self described as "a country girl from Memphis." They have homes in Virginia, Tennessee, and the Florida Panhandle.[1]
Theismann's son, Joseph W., pleaded guilty in 2002 to drug charges[39] of dealing cocaine and possessing drug paraphernalia. He received a 10-year suspended prison term, was placed on five years of probation and fined.[40]
Theismann was inducted into the New Jersey State Interscholastic Athletic Association Hall of Fame in 1997.[41]
On August 19, 2010, head coach Jay Gruden of the UFL's Florida Tuskers "confirmed that Theismann introduced himself to the Tuskers as the team's new part owner".[42] Theismann expressed disappointment at the way he was treated during his time in the league and left the team when it was folded into the Virginia Destroyers in January 2011.[43]
In 2011, Theismann was inducted into the New Jersey Hall of Fame.
^ a b c d e Harry Jaffe (December 1, 2007). "Joe Theismann Sounds Off". Washingtonian. Retrieved December 26, 2008.
^ "Redskins Announce Broadcast Teams For 2015 Preseason". Archived from the original on August 1, 2015. Retrieved August 9, 2015.
^ "Joe Theismann, On-Air Talent". Retrieved August 9, 2015.
^ "Joe Theismann's Restaurant". theismanns.com. Retrieved November 23, 2018.
^ Paul Attner (October 29, 1976). "Theismann Plans, but does not wait, for future". The Milwaukee Journal (via Google News Archive). The Washington Post.
^ "Washington Speakers Bureau: Joe Theismann". Retrieved November 23, 2018.
^ "Joe Theismann Speaker Profile". Retrieved November 23, 2018.
^ "A kommentátorrá lett irányító és az erdélyi magyar punter – Magyarok az NFL-ben 3". Retrieved October 6, 2018.
^ Amdur, Neil. "Theismann Pleases Irish Coach In Every Statistic Except One; Quarterback From Jersey Is Intercepted 16 Times -- Awaits Biggest Chance", The New York Times, December 27, 1969. Accessed March 20, 2011. "The snow was stacked as high and tight as a goal-line defense near Joe Theismann's house at 3 Arlington Avenue in South River, N. J., yesterday."
^ a b c d e f "Joe Theismann". College Football Hall of Fame. Football Foundation. Retrieved December 26, 2008.
^ Joe Theismann (July 31, 2007). America's Game – 1982 Redskins – Joe Theismann (video). NFL.com. Event occurs at 0:40.
^ "Heisman Winners : 1970 – 36th Award : Jim Plunkett". Heisman.com. 1970. Archived from the original on February 10, 2010. Retrieved September 30, 2010.
^ a b c "Green, Sanders also among inductees". ESPN.com College Football. Associated Press. August 12, 2004. Retrieved December 26, 2008.
^ "Baseball Draft: 39th Round of the 1971 June Draft". Baseball-Reference.com. Retrieved December 27, 2008.
^ "Allen Trades Pick for Theismann". The Milwaukee Journal. January 26, 1974. Retrieved March 30, 2015.
^ a b c d "Joe Theismann Stats". pro-football-reference.com. Sports Reference, LLC. Retrieved January 7, 2019.
^ "Joe Theismann strips Kim Bokamper, preventing game changing TD in Super Bowl XVII". YouTube. September 21, 2010. Retrieved October 14, 2013.
^ UPI (September 30, 1985). "Bears Show Redskins A Team On The Rise". Lodi News-Sentinel, p. 17.
^ Graham, Tim (August 11, 2009). "Face of the NFL is gone – an ode to the single-bar". ESPN.go.com.
^ "YouTube". www.youtube.com. Retrieved October 6, 2018.
^ a b Leonard Shapiro (November 18, 2005). "The Hit That Changed a Career". The Washington Post. Retrieved June 30, 2008.
^ Stone, Kevin (November 18, 2015). "Ten things you might not know about Joe Theismann's injury 30 years ago". ESPN.com. ESPN. Retrieved December 12, 2016.
^ Sandomir, Richard (December 26, 2005). "20 Years Later, Theismann Revisits Replay". The New York Times. Retrieved October 14, 2013.
^ Sonny Bunch (November 20, 2009). "Movie Review: The Blind Side". The Washington Times. Retrieved February 4, 2015.
^ "In multiple seasons, from 1950 to 2018, playing for the Washington Redskins, requiring Pass Completion % >= 1, sorted by most games matching criteria". www.pro-football-reference.com. Pro Football Reference. Retrieved November 23, 2018.
^ "Washington Redskins Career Passing Leaders". www.pro-football-reference.com. Sports Reference LLC. Retrieved November 23, 2018.
^ Gregg Rosenthal (September 6, 2010). "Joe Theismann to join NFL Network booth". NBCSports.com
^ Michael Hiestand (December 6, 2009). "Gibbs, Theismann to reunite for NBC wild-card game". USA Today. Retrieved December 8, 2009.
^ "Joe Theismann's 'Danny Woodcock' Gaffe: NFL Network Analyst Slips On Air (VIDEO)". Huffingtonpost.com. January 14, 2011. Retrieved August 16, 2012.
^ "IMDb Joe Theismann". Retrieved November 23, 2018.
^ Ride Of Fame With Joe Theismann Archived May 27, 2015, at the Wayback Machine Yahoo! Sport. September 5, 2014
^ "Super Beta Prostate® - America's #1 Prostate Supplement". www.superbeta.com. Retrieved October 6, 2018.
^ "Joe Theismann's Super Beta Prostate Commercial". YouTube. November 3, 2014. Retrieved November 3, 2014.
^ "Amy Theismann Obituary". Retrieved September 11, 2016
^ Michael J. Weiss (December 9, 1985). "A Bone-Breaking Tackle Leaves Joe Theismann Relying on L.C. from C.L.C." People. Retrieved August 9, 2015.
^ "Crosby Sues Theismann Over Financial Support". Orlando Sentinel. February 4, 1991. Retrieved August 9, 2015.
^ "Theismann, Crosby settle estate lawsuit". The Free Lance-Star (Fredricksburg, VA). June 8, 1991. Retrieved August 9, 2015.
^ Roberts, Roxanne (September 4, 1995). "COMMITMENTS : Split Decision". The Washington Post. Retrieved August 9, 2015.
^ AP (February 12, 2002). "Son of football great Joe Theismann faces cocaine charges". SignOnSanDiego.com; Union-Tribune. Retrieved July 8, 2010.
^ AP (January 15, 2003). "Joe Theismann's Son Gets Drug Sentence". Highbeam Research archive.
^ "Hall of Fame Annual Awards, 1997". New Jersey State Interscholastic Athletic Association. 1997. Archived from the original on May 21, 2007. Retrieved December 25, 2008.
^ Radcliffe, Jeff (August 19, 2010). Joe Theismann in talks to become part owner of Florida Tuskers[permanent dead link]. BHSN.com. Retrieved August 19, 2010.
^ Masters, Mark (June 24, 2011). "Unplugged: Theismann on the CFL, NFL and Marc Trestman Archived 2012-07-20 at Archive.today". National Post. Retrieved 2011-06-25.
Wikimedia Commons has media related to Joe Theismann.
Career statistics and player information from NFL.com · Pro-Football-Reference
Joe Theismann at the College Football Hall of Fame
Joe Theismann CFL & NFL Statistics – totalfootballstats.com
Joe Theismann on IMDb
Joe Theismann's Restaurant
Washington Times article about Theismann's injury
Media offices
None Super Bowl television color commentator
(prime-time package carrier)
1984 (with Don Meredith) Succeeded by
Frank Gifford and Dan Dierdorf
Joe Theismann—championships, awards, and honors
Washington Redskins Super Bowl XVII champions
3 Mark Moseley
5 Jeff Hayes
7 Joe Theismann
8 Bob Holly
17 Tom Owen
20 Joe Lavender
21 Mike Nelms
22 Curtis Jordan
23 Tony Peters
25 Joe Washington
29 Mark Murphy
30 Nick Giaquinto
32 Vernon Dean
38 Clarence Harmon
39 Otis Wonsley
40 Wilbur Jackson
44 John Riggins (MVP)
45 Jeris White
46 LeCharls McDaniel
47 Greg Williams
50 Larry Kubin
51 Monte Coleman
52 Neal Olkewicz
53 Jeff Bostic
54 Peter Cronan
55 Mel Kaufman
56 Quentin Lowry
57 Rich Milot
58 Stuart Anderson
62 Donald Laster
63 Fred Dean
65 Dave Butz
66 Joe Jacoby
68 Russ Grimm
69 Perry Brooks
71 Garry Puetz
72 Dexter Manley
73 Mark May
74 George Starke
75 Pat Ogrin
76 Mat Mendenhall
77 Darryl Grant
78 Tony McGee
79 Todd Liebenstein
80 Virgil Seay
81 Art Monk
82 Rich Caster
84 Mike Williams
85 Don Warren
86 Clint Didier
87 Charlie Brown
88 Rick Walker
89 Alvin Garrett
Head coach: Joe Gibbs
Coaches: Don Breaux
Joe Bugel
Dan Henning
Larry Peccatiello
Richie Petitbon
Wayne Sevier
Warren Simmons
Charley Taylor
LaVern Torgeson
Notre Dame Fighting Irish starting quarterbacks
Cusack
E. Coady
P. Coady
Diebold
McGlew
Dorais
Stuhldreher
Niemiec
Carideo
Jaskwhich
Bonar
Fromhart
Puplis
Sitko
Bertelli (1941–1943)
Lujack (1943, 1946–1947)
Dancewicz (1944–1945)
Tripucka (1948)
B. Williams (1949–1950)
Mazur (1950–1951)
Guglielmi (1951–1954)
Carey (1952, 1954)
Hornung (1955–1956)
R. Williams (1956–1958)
Izo (1958–1959)
Haffner (1960)
Lamonica (1960–1962)
Budka (1961, 1963)
Szot (1962–1963)
Huarte (1963–1964)
Bonvechio (1963)
Zloch (1965)
Schoen (1965)
Hanratty (1966–1968)
O'Brien (1966)
Theismann (1968–1970)
Steenberge (1971)
Etter (1971)
Clements (1972–1974)
Slager (1975–1976)
Montana (1975, 1977–1978)
Lisch (1976–1977, 1979)
Koegel (1979, 1981)
Courey (1979–1980)
Kiel (1980–1983)
Karcher (1982)
O'Hara (1982)
Beuerlein (1983–1986)
Grooms (1984)
Andrysiak (1985–1987)
Rice (1987–1989)
Mirer (1990–1992)
Failla (1991, 1993)
McDougal (1993)
Powlus (1994–1997)
Krug (1995)
Jackson (1998–1999)
Chappell (1998)
Battle (2000)
Godsey (2000)
LoVecchio (2000–2001)
Holiday (2001–2003)
Dillingham (2002)
Quinn (2003–2006)
Jones (2007)
Clausen (2007–2009)
Sharpley (2007)
Crist (2010–2011)
Rees (2010–2013)
Golson (2012, 2014)
Zaire (2014–2015)
Kizer (2015–2016)
Wimbush (2017–2018)
Book (2017–2018)
Associated Press NFL Most Valuable Player Award winners
1957: J. Brown
1959: Unitas
1960: Van Brocklin
1961: Hornung
1962: J. Taylor
1963: Tittle
1966: Starr
1968: Morrall
1969: Gabriel
1970: Brodie
1971: Page
1972: L. Brown
1973: Simpson
1974: Stabler
1975: Tarkenton
1976: Jones
1977: Payton
1978: Bradshaw
1979: Campbell
1980: Sipe
1981: Anderson
1982: Moseley
1983: Theismann
1984: Marino
1985: Allen
1986: L. Taylor
1987: Elway
1988: Esiason
1989: Montana
1991: Thomas
1992: Young
1995: Favre
1997: Favre & Sanders
1999: Warner
2000: Faulk
2002: Gannon
2003: Manning & McNair
2004: Manning
2005: Alexander
2006: Tomlinson
2007: Brady
2011: Rodgers
2012: Peterson
2015: Newton
2018: Mahomes
Associated Press NFL Offensive Player of the Year Award winners
1982: Fouts
1986: Dickerson
1987: Rice
1988: Craig
1990: Moon
1994: Sanders
2002: Holmes
2008: Brees
2009: Johnson
2014: Murray
2017: Gurley
Walter Payton NFL Man of the Year Award
1971: Hadl
1972: Lanier
1973: Dawson
1974: Blanda
1976: Harris
1978: Staubach
1979: Greene
1980: Carmichael
1981: Swann
1983: Benirschke
1984: Lyons
1985: Stephenson
1987: Duerson
1988: Largent
1990: Singletary
1991: Muñoz
1994: Seau
1996: Green
1997: Aikman
1999: Carter
2000: Flanigan & Brooks
2001: Bettis
2002: Vincent
2003: Shields
2004: Dunn
2005: P. Manning
2006: Brees & Tomlinson
2009: Waters
2011: Birk
2012: Witten
2013: Tillman
2015: Boldin
2016: Fitzgerald & E. Manning
2017: Watt
2018: Long
Bert Bell Award winners
1962: Robustelli
1965: Retzlaff
1966: Meredith
1968: Kelly
1974: Olsen
1977: Griese
1980: Jaworski
1983: Riggins
1988: Cunningham
2010: Vick
2017: Wentz
Toronto Argonauts starting quarterbacks
Stukus
Krol
Dekdebrun
Wirkowski
Galiffa
Dublinski
Liske
Gabler
Theismann
Ealey
Congemi
Foggie
Dunigan
Flutie
K. Bell
S. Jackson
Pickett
D. Bell
Jyles
J. Jackson
Collaros
LeFevour
Bethel-Thompson
Boston Braves / Boston Redskins / Washington Redskins starting quarterbacks
Hank Hughes (1932)
Jim Musick (1933)
Steve Hokuf (1934)
Pug Rentner (1934–1935)
Bill Shepherd (1935)
Eddie Britt (1936)
Ed Smith (1936)
Sammy Baugh (1937–1952)
Bill Hartman (1938)
Frank Filchock (1938–1939, 1941, 1944)
Jim German (1939)
Roy Zimmerman (1942)
George Cafego (1943)
Jim Youel (1946–1947)
Jack Jacobs (1946)
Tommy Mont (1948)
Harry Gilmer (1949–1951)
Eddie LeBaron (1952–1953, 1955–1959)
Jack Scarbath (1953–1954)
Al Dorow (1954–1956)
Ralph Guglielmi (1955, 1958–1960)
Eagle Day (1960)
Norm Snead (1961–1963)
Sonny Jurgensen (1964–1974)
Dick Shiner (1965)
Jim Ninowski (1968)
Billy Kilmer (1971–1978)
Randy Johnson (1975)
Joe Theismann (1976–1985)
Mike Kruczek (1980)
Jay Schroeder (1985–1987)
Ed Rubbert (1987)
Doug Williams (1987–1989)
Mark Rypien (1988–1993)
Stan Humphries (1990)
Jeff Rutledge (1990)
Rich Gannon (1993)
Cary Conklin (1993)
Heath Shuler (1994–1995)
John Friesz (1994)
Gus Frerotte (1994–1998)
Jeff Hostetler (1997)
Trent Green (1998)
Brad Johnson (1999–2000)
Jeff George (2000–2001)
Tony Banks (2001)
Shane Matthews (2002)
Patrick Ramsey (2002–2005)
Danny Wuerffel (2002)
Tim Hasselbeck (2003)
Mark Brunell (2004–2006)
Jason Campbell (2006–2009)
Todd Collins (2007)
Donovan McNabb (2010)
Rex Grossman (2010–2011)
John Beck (2011)
Robert Griffin III (2012–2014)
Kirk Cousins (2012–2017)
Colt McCoy (2014, 2018)
Alex Smith (2018)
Mark Sanchez (2018)
Josh Johnson (2018)
21 Terry Allen RB 1995–98
41 Mike Bass CB 1969–75
20 Cliff Battles B 1932–37
33 Sammy Baugh QB 1937–52
31 Don Bosseler B 1957–64
53 Jeff Bostic C 1980–93
4 Mike Bragg P 1968–79
80 Gene Brito DE 1951–53, 1955–58
43 Larry Brown RB 1969–76
77 Bill Brundige DE 1970–77
65 Dave Butz DT 1975–88
21 Earnest Byner RB 1989–93
84 Gary Clark WR 1985–92
51 Monte Coleman LB 1979–94
53 Al DeMao C 1945–53
36 Chuck Drazenovich LB 1950–59
35 Bill Dudley RB 1950–51, 1953
17 Turk Edwards T 1932–40
44 Andy Farkas FB 1938–44
37 Pat Fischer CB 1968–77
28 Darrell Green CB 1983–2002
68 Russ Grimm G 1981–91
55 Chris Hanburger LB 1965–78
57 Ken Harvey LB 1994–98
56 Len Hauss C 1964–77
27 Ken Houston S 1973–80
70 Sam Huff LB 1964–67, 1969
66 Joe Jacoby T/G 1981–93
47 Dick James RB 1955–63
9 Sonny Jurgensen QB 1964–74
22 Charlie Justice RB 1950, 1952–54
17 Billy Kilmer QB 1971–78
26 Paul Krause DB 1964–67
79 Jim Lachey T 1988–95
14 Eddie LeBaron QB 1952–53, 1955–59
72 Dexter Manley DE 1981–89
71 Charles Mann DE 1983–93
58 Wilber Marshall LB 1988–92
73 Mark May T 1981–89
79 Ron McDole DE 1971–78
63 Raleigh McKenzie G 1985–94
53 Harold McLinton LB 1969–78
40 Wayne Millner E 1936–41, 1945
49 Bobby Mitchell FL 1962–68
30 Brian Mitchell RB 1990–99
81 Art Monk WR 1980–93
3 Mark Moseley K 1974–86
29 Mark Murphy S 1977–84
21 Mike Nelms KR 1980–84
52 Neal Olkewicz LB 1979–89
23 Brig Owens LB 1966–77
65 Vince Promuto G 1960–70
44 John Riggins RB 1976–79, 1981–85
11 Mark Rypien QB 1987–93
83 Ricky Sanders WR 1986–93
76 Ed Simmons T 1987–93
87 Jerry Smith TE 1965–77
60 Dick Stanfel G 1956–58
74 George Starke T 1973–84
72 Diron Talbert DT 1971–80
84 Hugh (Bones) Taylor E 1947–54
42 Charley Taylor WR 1964–77
7 Joe Theismann QB 1974–85
67 Rusty Tillman LB 1970–77
85 Don Warren TE 1979–92
25 Joe Washington RB 1981–84
17 Doug Williams QB 1986–89
George Allen Head Coach 1971–77
Ray Flaherty Head Coach 1936–42
Joe Gibbs Head Coach 1981–92
Cliff Battles RB 1932–37
Sammy Baugh QB 1937–52
Gene Brito DE, 1951–53, 1955–58
Larry Brown RB 1969–76
Dave Butz DT 1975–88
Gary Clark WR 1985–92
Jack Kent Cooke Owner 1961–97
Bill Dudley RB, 1950–51, 1953
Wayne Curry Prince George's County Executive 1994–2002
Pat Fischer CB 1968–77
Joe Gibbs Head Coach, 1981–92, 2004–07
Darrell Green CB 1983–2002
Russ Grimm G 1981–91
Chris Hanburger LB 1965–78
Ken Harvey LB 1994–98
Len Hauss C 1964–77
Phil Hochberg PA Announcer 1963–2000
Ken Houston S 1973–80
Sam Huff LB, 1964–67, 1969
Joe Jacoby T/G 1981–93
Dick James RB 1956–63
Sonny Jurgensen QB 1964–74
Charlie Justice RB, 1950, 1952–54
Billy Kilmer QB 1971–78
Eddie LeBaron QB, 1952–53, 1955–59
Vince Lombardi Head Coach/General Manager 1969
Dexter Manley DE 1981–89
Charles Mann DE 1983–93
George Preston Marshall Team Founder & Owner 1932–69
Wayne Millner End, 1936–41, 1945
Bobby Mitchell Flanker 1962–68
Brian Mitchell RB/KR 1990–99
Art Monk WR 1980–93
Mark Moseley PK 1974–86
Brig Owens DB 1966–77
Richie Petitbon S 1971-72, defensive coordinator 1981-92, Head Coach 1993
Vince Promuto G 1960–70
John Riggins RB, 1976–79, 1981–85
Jerry Smith TE 1965–77
Charley Taylor WR 1964–77
Sean Taylor S 2004–07
Joe Theismann QB 1974–85
Lamar "Bubba" Tyer Head Athletic Trainer, 1971–2002, 2004–08
Doug Williams QB 1986–89
Super Bowl champion starting quarterbacks
I: Starr
II: Starr
III: Namath
IV: Dawson
V: Unitas
VI: Staubach
VII: Griese
VIII: Griese
IX: Bradshaw
X: Bradshaw
XI: Stabler
XII: Staubach
XIII: Bradshaw
XIV: Bradshaw
XV: Plunkett
XVI: Montana
XVII: Theismann
XVIII: Plunkett
XIX: Montana
XX: McMahon
XXI: Simms
XXII: Williams
XXIII: Montana
XXIV: Montana
XXV: Hostetler
XXVI: Rypien
XXVII: Aikman
XXVIII: Aikman
XXIX: Young
XXX: Aikman
XXXI: Favre
XXXII: Elway
XXXIII: Elway
XXXIV: Warner
XXXV: Dilfer
XXXVI: Brady
XXXVII: Johnson
XXXVIII: Brady
XXXIX: Brady
XL: Roethlisberger
XLI: P. Manning
XLII: E. Manning
XLIII: Roethlisberger
XLIV: Brees
XLV: Rodgers
XLVI: E. Manning
XLVII: Flacco
XLVIII: Wilson
XLIX: Brady
50: P. Manning
LI: Brady
LII: Foles
LIII: Brady
Thursday Night Football on CBS, Fox, NBC and NFL Network
Pregame
Colleen Wolfe
Steve Mariucci
Joe Buck - Play-by-Play
Troy Aikman - Color Commentary
Erin Andrews - Sideline Reporter
Kristina Pink - Sideline Reporter
Mike Pereira - Rules Analyst
Scott Hanson
Bob Papa
Matt Millen
Fran Charles
Kara Henderson
Sterling Sharpe
Brad Nessler
Mike Mayock
Alex Flanagan
Liam McHugh
Rodney Harrison
Tracy Wolfson
Mike Tirico
Heather Cox
Notable broadcasts
Bills Toronto Series
World Bowl
2007 New England Patriots–New York Giants game
"The Miracle in Motown"
Retrieved from "https://en.wikipedia.org/w/index.php?title=Joe_Theismann&oldid=905379973"
American football quarterbacks
American people of Austrian descent
American people of Hungarian descent
American players of Canadian football
American restaurateurs
Canadian football quarterbacks
College football announcers
College Football Hall of Fame inductees
National Conference Pro Bowl players
National Football League announcers
Washington Redskins broadcasters
National High School Hall of Fame inductees
Notre Dame Fighting Irish baseball players
Notre Dame Fighting Irish football players
People from Germantown, Tennessee
People from South River, New Jersey
Players of American football from New Jersey
Sportspeople from New Brunswick, New Jersey
Super Bowl champions
Toronto Argonauts players
United Football League (2009–12) owners
Washington Redskins players
Articles with dead external links from March 2018
Webarchive template archiveis links
NFL player missing current team parameter
Infobox NFL biography articles missing alt text

redpajama_set_name: RedPajamaCommonCrawl


This listing is for 1 piece of 3D chrome finished S logo emblem badge sticker, especailly for all Audi Sport cars.
These 3 inches 3D S logo emblem decal made with high quality chrome finished and also with double-sided tape on the back for easy application. It can be placed to anywhere you think is the best. It will give your Audi an awesome eye-catching sport look!


text:
Ryan Rauschenberger
North Dakota Tax Laws & Regulations
Major Publications & Info
Tax Facts - Doing Business in ND
Media Contact(s)
Powers/Duties of Tax Commissioner
Responsibilities of Office Divisions
For Individuals ►
For Tax Professionals ►
For Local Governments ►
Forms/Publications
Exemptions/Refunds/Credits
Angel Fund Investment Credit
The information on this page only applies to angel funds certified, and to investments made in them, before July 1, 2017.
Note: This credit is subject to the state and local tax clearance requirements.
An individual, estate, trust, partnership, corporation, or limited liability company is allowed an income tax credit for investing in an angel fund in North Dakota certified by the Department of Commerce Division of Economic Development and Finance.
The credit is equal to 45% of the investment, up to a maximum credit of $45,000 per year. An unused credit may be carried forward up to seven tax years. A taxpayer claiming this credit may not claim an income tax credit passed through to the taxpayer by the angel fund resulting from the angel fund's investment in a qualified business for purposes of the seed capital or agricultural commodity processing facility investment tax credit programs.
Lifetime credit limit. For credits based on investments made on or after January 1, 2013, and before July 1, 2017, a taxpayer is allowed no more than $500,000 in cumulative credits over the taxpayer's lifetime. Married individuals are treated as one taxpayer for this limit.
See the following links for more information:
Reference: N.D.C.C. § 57-38-01.26 (effective for investments made before July 1, 2017)
Certification as North Dakota angel fund - To obtain certification as a North Dakota angel fund for purposes of the Angel Fund Investment Tax Credit Program, an Application For Certification As An Angel Fund must be completed and submitted to the North Dakota Commerce Department's Division of Economic Development and Finance.
Questions relating to certification should be directed to the North Dakota Commerce Department's Division of Economic Development and Finance as follows:
North Dakota Commerce Department
Division of Economic Development and Finance
Bismarck ND 58503
Email: commerce@nd.gov
Website: www.business.nd.gov
Program provisions - For a rundown of the Program's provisions, see Angel Fund Investment Tax Credit Program - Program provisions.
Once certified, a North Dakota angel fund must report each qualified investment it receives by completing and submitting an Angel Fund Investment Reporting Form to the North Dakota Office of State Tax Commissioner.
Credit rates, limitations, and other features by tax year - For a summary of the applicable rates, limitations, and other features on a year-by-year basis, see Angel Fund Investment Tax Credit Program - Rates, limitations, and other features of the tax credit by tax year.
Annual reporting requirement for angel funds – Every North Dakota angel fund certified for purposes of the angel fund investment tax credit program under N.D.C.C. § 57-38-01.26 must file Form AFI, Angel Fund Investment Report, at the end each calendar year. For more information, see the instructions to the applicable year's Form AFI.
The following forms are only for angel funds first certified before July 1, 2017:
2018 Form AFI
Personal Property Tax Exemption
Property Tax Reduction
Payment in Lieu of Property Tax
Oil Tax Incentives
Sales Tax Exemptions
Income Tax Incentives
Renaissance Zone Incentives
Jobs Training Assistance
Office of State Tax Commissioner
600 E. Boulevard Ave.
Taxinfo@nd.gov
Voluntary Disclosure
The link you have selected will direct you to an external website not operated by the North Dakota Office of State Tax Commissioner.
This link is provided for convenience and informational purposes only. The North Dakota Office of State Tax Commissioner has no responsibility for the content, accuracy or propriety of any information located there.


text:
Q: Right assert for testing Doctrine entities in Symfony2 I'm writing some test for my entities and this is the code:
$device = new Device();
$strTool = new StringTools();

$imei = $strTool->randomNumber(17);
$device->setImei($imei);
$device->setDescription($strTool->generateRandomString(50));

$this->em->persist($device);
$this->em->flush();

$devices = $this->em->getRepository('DeviceBundle:Device')->findOneBy(array('imei' => $imei));

$this->assertCount(1, $devices);
$this->assertTrue(is_object($device));

But first test assertCount is failing with this message:

PHPUnit_Framework_Exception: Argument #2 (No Value) of
  PHPUnit_Framework_Assert::assertCount() must be a countable or
  traversable

What is the right way to test I get results from DB?

A: findOneBy return only one element, use findBy instead.
btw, what you are testing here is Doctrine itself. Doctrine is pretty well tested so there is no need for you to do that.

redpajama_set_name: RedPajamaStackExchange


text:
Institutions step into the decline
Pension funds bought big as most investors ran fast for the exits
Near panic at the open gave way to calm later in the day as institutional investors came into the Korean market in a big way.
One minute after the 9 a.m. open, the benchmark Kospi was down 2.39 percent as foreign and retail investors dumped their shares wholesale.
They were not only responding to the trade war between Korea and Japan, but they were also reacting to the decision by the U.S. to name China as a currency manipulator.
Three minutes into the day, the benchmark index fell below 1,900 for the first time in three years. It was June 24, 2016, the day after the Brexit vote, when the Kospi dropped to 1,892.75.
Yesterday, the index went as low as 1,891.81, down 2.8 percent.
The Kosdaq - where futures were suspended Monday for the first time in three years - moved in sympathy. It fell as much as 5.1 percent but closed down 3.21 percent to 551.50.
"The overnight drop in global stock markets was largely due to the intensifying trade dispute between the U.S. and China, which could spill over to a currency war," said Kim Hwan, analyst at NH Investment & Securities.
The Kospi ended 1.51 percent lower to end the day Tuesday at 1,917.50.
Over five consecutive days, the index has lost 5.94 percent of its value, or 121.18 points. It is down a full 10 percent from July 1, when Japan first announced its trade restrictions targeting Korea.
The drop Tuesday was not nearly as bad as it might have been in part due to heavy buying from institutional investors, especially pension funds.
The pension funds net bought 429 billion won of Kospi stocks. From Friday through Monday, they purchased in total 1 trillion won of shares, stepping in as Japan removed Korea from its "white list" of countries qualified for simplified export procedures.
The last time the pension funds net purchased more than 500 billion won worth of Korean shares was eight years ago on June 4, 2012.
These intuitions have often played pivotal roles in times of crisis. During the 2008 global financial crisis, they net purchased a total of 9 trillion won worth of shares.
On Tuesday, Financial Services Commission (FSC) Vice Chairman Sohn Byung-doo stressed that Korean institutional investors will aid in the stabilization of the financial markets.
Financial institutional investors joined the pensions in buying local shares. They were net sellers on Friday but purchased 288.4 billion won of shares on Monday and 417.2 billion won on Tuesday.
"It will be difficult to expect foreign investors to make a distinctive [stock] purchase anytime soon as overall global securities transactions are shrinking and the won is depreciating against the U.S. dollar," said Kim Kwang-hyun, Yuanta Securities analyst.
"It is the appropriate time for institutional investors to be increasing their purchases in the market."
Foreign investors until recently were net buyers of local shares. Since the beginning of this year until Aug. 2, they net purchased 6.79 trillion won worth of stocks on the Korean market, while retail investors sold off 5.62 trillion won worth and institutional investors dumped 1.18 trillion won worth.
Foreign investors recently have turned negative as they have been offloading shares over the last five consecutive trading days, selling a net 1.38 trillion won worth of Korean shares.
Despite the institutional investor support, market experts say the current bearishness is likely to continue.
"We're likely to see additional declines rather than local stocks rebounding as there is the possibility of the Japanese government adding new trade restrictions and the trade dispute between U.S. and China continuing," said Kim Hyo-jin, SK Securities analyst.
BY LEE HO-JEONG [lee.hojeong@joongang.co.kr]


text:
Auto rally includes BOSS car show
Weekly FMWR briefing for May 16
The BOSS Armed Forces Day Car Show and related activities will be from 9 a.m.-3 p.m. Saturday at the parking lot off East Bultman Avenue, adjacent to the Fort Stewart Education Center. - photo by Stock photo
The BOSS Armed Forces Day Car Show will be held from 9 a.m.-3 p.m. Saturday at the parking lot off East Bultman Avenue, adjacent to the Fort Stewart Education Center
Judging will be in the categories of best (car or bike) in show; best import; best SUV or truck; best classic; biggest rim; most chrome and best sound. Admission to watch the show is $2 per person. There is no charge for children ages 10 and younger.
Car entry fees are $25 per car; $10 per car for clubs entering five cars or more; $10 for the sound competition and $30 for the show and sound combination.
Concessions and vendors will be available.
The Installation Safety Office will have a non-emergency vehicle operation course set up for drivers to test their skills. Instructors will offer tips and to talk about vehicle dynamics. Licensed drivers are invited to bring their own vehicle and test their skills.
For more information or to enter the competition, call 767-4316 or 767-9917.
Armed Forces Kid's Day Runs
Children ages 5-13 from Fort Stewart and Hunter Army Airfield will join military-connected children around the world Saturday in America's Armed Forces Kids Day Runs.
At Stewart, the run will be from 8 a.m.-noon at Jordan Youth Gym. At Hunter, it's from 8 a.m.-1 p.m. at the corner of Steven Douglas and North Perimeter Road.
The events provide an opportunity for youth to participate in America's Kids Run in conjunction with Armed Forces Day and as part of the We Can! (Ways to Enhance Children's Activity and Nutrition) program to combat childhood obesity.
Each child will get a T-shirt upon finishing the run. Younger kids will run half a mile, 7- and 8-year-olds one mile, and older kids two miles.
Activities and games will begin when the runs are completed.
For more information, call 767-1428 at Stewart or 912-315-9781 at Hunter.
Offshore Soldier Fishing Sign-up
Registration continues through May 25 for the free Offshore Outlaw Fishing Club's June fishing tournament.
Soldiers must pre-register at the Fort Stewart or Hunter Leisure Travel Office. The number of spaces available is limited. Participants must have a Georgia fishing license, available for purchase at http://www.dnr.state.ga.us.
The club, as it did in 2009, has extended an invitation to active duty, National Guard and Army Reserve soldiers to take part in the tournament.
A mandatory captains meeting and Lowcountry boil on June 3 will finalize details. Club captains will take soldiers out June 4 and provide all fishing equipment/tackle and bait needed.
The club is based out of the Fort McAllister Marina in Richmond Hill.
For event details, call Leisure Travel at Stewart, 767-8609, or at Hunter, (912) 315-3674.
Teen Skate Jam at Corkan
Teens (ages 13-18) are invited to a skate jam under the cool lights and music from 8-10 p.m. May 28 at Corkan Family Fun Center. Bring your favorite music and it may be played on the sound system. Stewart's curfew rules apply. The $5-per-person cost includes skate rental.
Dinner and Bowling Special at Stewart Lanes
Stewart Lanes Bowling Center is offering a family discount night with dinner and bowling from 6-9 p.m. May 29. For $25, your family gets 10 games of bowling, five shoe rentals and an all-American dinner of chili cheese dogs, fries and refillable sodas.
Summer Reading Program Storytime Kickoff
Special shows launching the Midsummer Knight's Read 2011 Summer Reading Program will be presented from 3-4 p.m. and from 4-5 p.m. June 1 at the George P. Hays Library. The reading program, for children up to age 12, is free.
Sean Driscoll, an entertainer, will present his "Wand of Dreams" program, a mathematical fairy tale combining animation, puppetry, comedy theater, magic and music.
Space is limited, so early sign-up is encouraged. Parents need to sign up their children at the library or call 767-2828 for more information.
Free Youth Dance Aerobics
An aerobics class for youth (ages 10-18) is designed to strengthen the body through dance movement, aid in weight loss and build muscle tone, all while having fun. Youth dance aerobics consists of 10-minute warm up, followed by 25 minutes of dance aerobics, zumba and a 15-minute cool-down.
Classes are 6-7:30 p.m. Wednesdays and Friday from June 1-July 29 at Jordan Youth Gym. Registration required. For more information, call 767-5079 or 767-2815
CYSS Youth Action Council Meeting
Teens, get involved and make a difference in your quality of life and attend the CYSS Youth Action Council meeting at 5 p.m. June 2 at Bryan Village Youth Center, building 7338.
The meeting is an opportunity to make new friends, have fun and enjoy pizza. There is no charge.
For more information, call School Liaison at 767-6533.
Youth Sponsorship Gator Galore & Asian Festival Sign-up Deadline
Register by June 2 for the Youth Sponsorship Gator Galore & Asian Festival trip to the Savannah Wildlife Refuge and the Savannah Civic Center on June 4. There is no charge.
The trip is open to CYSS-registered youth in grades 4-12. Although the trip is free, there is a $5 fee for any cancellations after June 2 or no-shows.
During the four-mile loop through the refuge, participants will likely see gators and other wildlife indigenous to the coastal region. From the refuge, the group will go to the Savannah Civic Center for the Savannah Asian Festival.
The Asian festival will feature live stage performances, martial arts demonstrations, authentic cuisine, cultural displays, arts and crafts and more. Youth can bring a lunch or buy lunch at the festival.
For more information, call the Fort Stewart School Liaison Offices at 767-6533 or the Hunter offices at (912) 315-6586.
Baby Loves Disco Tickets
Free tickets for Baby Loves Disco, whose Lemonade Tour music and fun had Club Stewart rocking for three hours last November, are available on a first-come, first-served basis at the Stewart and Hunter Leisure Travel Offices.
Distribution of tickets, which are needed for admission, began on May 2.
The party for kids ages 4 months to 7 years will be in the Club Stewart Ballroom from 5 to 8 p.m. on May 31. Children will dance to groovy '70s and '80s disco music and have a ball with games and activities such as face-painting, sock puppets, an art wall and more.
At Stewart, the Leisure Travel office is in the PX Furniture Mall complex. At Hunter, the office is in building 1286.
Call 767-2841 at Stewart and (912) 315-3674 at Hunter for more information.
Aerification Work at Hunter Golf Club
Weather permitting, aerification maintenance will be performed on the greens at Hunter Golf Club on May 31 and June 1. The work will require that nine holes be closed each day.
Patrons are asked to call 315-9115 for updates.
Aerification work on the greens at Taylors Creek Golf Course has already been completed, according to Tommie McArthur, director of golf for Stewart/Hunter.
DoDEA School Day Schedule Changes
An important parent letter has been sent to all currently enrolled Fort Stewart DoDEA school families regarding the upcoming 2011-12 school year.
In an effort to provide teachers and staff a consistent time for professional development and collaboration, a change to the student schedule for the upcoming school year has been proposed. Due to the schedule change, students will be dismissed at 1:30 p.m. each Thursday.
The change and DoDEA parent letter along with the complete 2011-12 calendar can be found on the Fort Stewart School Liaison Website at: http://www.stewartmwr.com/index.php/child_youth_school_services/school_transition_support/school_liaison_services/.
For more information, call the Stewart School Liaison Office at 767-6533.


text:
Science : Variations on an evolutionary theme
By Jeff Hecht
EVER since On the Origin of Species, studies on evolution have
focused primarily on individual organisms. But now some palaeontologists are
expanding their field of research and looking at changes not just within
species, but within entire ecosystems. Their work is challenging accepted ideas
about the process of evolution.
The latest surprise comes in a paper in last week's Science (vol
273, p 1091) which reports that it took just 12 500 years for more than 300
endemic species of cichlid fish to evolve in Africa's Lake Victoria. Geologists
knew that water levels in the lake dropped dramatically at the end of the Ice
Age, and it was thought the fish evolved slowly by taking refuge in satellite
lakes during the period.
But Thomas Johnson of the University of Minnesota at Duluth, and others, have
found that the deepest parts of Lake Victoria were dry for several thousand
years, until around 12 500 years ago. Without water from the main lake, the
satellite lakes could not have survived. Thus the lake's diverse assortment of
cichlid fish must have evolved since the lake began to refill.
One recent model for evolution, known as "coordinated stasis", suggests that
entire communities of species evolved together in short spurts, and that these
evolutionary explosions were separated by long periods of little change. This
model seeks to extrapolate to the community level the "punctuated equilibrium"
theory that Niles Eldredge and Stephen Jay Gould espoused for individual
species.
"Not only do [individual] lineages persist for millions of years, but they do
it [together] in bundles, says William Miller of Humboldt State University in
California. These bundles, or groups of species, often originate and disappear
at the same time.
In a special issue of Palaeogeography, Palaeoclimatology,
Palaeoecology to be published in December, Carlton Brett of the University
of Rochester and Linda Ivany and Kenneth Schopf of Harvard University note that
in ancient seafloor communities found in New York State, 60 to 80 per cent of
species persisted for 3 to 7 million years.
Evolutionary and ecological change were concentrated in brief periods that
were less than 10 per cent as long as the stable intervals. During these periods
of change, 70 per cent of existing species vanished from the region, new species
arose from old lineages and immigrants became established.
One suggested explanation for this pattern is that, during stable periods,
the interactions between species constrain the number and type of available
ecological niches, leaving no room for new species to immigrate from elsewhere.
This would also prevent extreme variations of existing species, according to
Paul Morris of the University of Massachusetts at Amherst, who worked with
Ivany, Schopf and Brett.
But Peter Sheldon of the Open University claims that barriers to evolutionary
change are lower in a stable environment than in a dynamic one. His
controversial "plus ça change" model suggests that in stable
environments, species have the chance to adapt to their particular niches and
they become specialists. In a dynamic environment, however, they must remain
generalists in order to cope with the changing conditions, and are unable to
develop far along a particular evolutionary path.
Sheldon says his model can explain why large climate fluctuations since the
end of the ice age 18 000 years ago caused little change in temperate faunas.
And he points out that in the more stable environment of the tropics "the
tremendous species variation in the rainforest is evidence for rapid evolution".
He believes the "coordinated statis" model is more popular than his "because the
vast majority of the fossil record comes from dynamic environments".
Magazine issue 2045 , published 31 August 1996
Science : US successes fuel hopes for gene therapy
Science : Life, but not as we know it