      SUBROUTINE REPAIR(NC,ISATC,LOCSAT,NEST,IEST,NPR,IPR,LOCPR,
     2                   NR,ISR,UVECS,ZVEC,FLEN,LPRDB,NDATP,NAMB)

C     REPAIR examines a list of available satellites that are
C     candidates for double differencing, compares the list with
C     the previous lists of established satellites and double-
C     differenced candidate pairs, and makes appropriate changes
C     in the lists of established satellites and pair assignments.
C     REPAIR is used by BTRACK.

C     Arguments:
C        NC            [I*4]: Number of satellites currently visible
C                             (at both ends of the baseline).
C        ISATC(*)      [I*4]: PRN numbers of the NC available satellites,
C                             in ascending PRN order.
C        LOCSAT(*)     [I*4]: Location of PRN i in the array ISATC;  If
C                             PRN i is not present, LOCSAT(i) = 0.
C        NEST          [I*4]: Number of established satellites: input is
C                             previous number, output is current number.
C        IEST(*)       [I*4]: List of PRN's of established satellites,
C                             in ascending PRN order:
C                             input is previous list, output is current list.
C        NPR           [I*4]: Number of candidate satellite pairs, in which
C                             at least one member is not yet established:
C                             input is previous number, output is current
C                             number.
C        IPR(2,*)      [I*4]: Array of PRN's of the NPR satellite pairs:
C                             input is previous list, output is current list.
C        LOCPR(*)      [I*4]: LOCPR(i) is the index number of IPR(*,i) in
C                             the satellite-pair database.
C        NR            [I*4]: Number of satellites in the previous ISATC list
C                             that are not in the current list.
C        ISR(*)        [I*4]: PRN numbers of the NR removed satellites, in
C                             order of ascending PRN.
C        UVECS(3,*)    [R*8]: Unit vectors from the approximate location of
C                             the receivers to the corresponding satellites
C                             in ISATC.
C        ZVEC(3)       [R*8]: Unit vector toward zenith at reference antenna.
C        FLEN(*)       [R*8]: Maximum double-differenced range, in units of
C                             the baseline length.  Index is slot number in
C                             pairs database.
C        LPRDB(MAXPRS) [L*1]: TRUE iff slot i in the pairs database is
C                             in use.
C        NDATP(MAXPRS) [I*4]: Number of epochs at which pair has been
C                             measured (in pairs database)
C        NAMB(MAXPRS)  [I*4]: Number of ambiguities found so far for this
C                             pair (in pairs database)

      IMPLICIT REAL*8 (A-H,O-Z)

      LOGICAL*1 DONE,FOUND,LPRDB

      PARAMETER (MAXSAT = 10, MXXSAT = 32)
      PARAMETER (PI = 3.14159 26535 89793 24D0)
      PARAMETER (MAXPRS = MAXSAT - 1, MAXGRP = MAXSAT/2)
      PARAMETER (RADDEG = 1.8D2/PI)

      DIMENSION FLEN(*),IEST(*),IPR(2,*),ISATC(*),ISR(*),LOCPR(*),
     2   LOCSAT(MXXSAT),LPRDB(*),NAMB(*),NDATP(*),UVECS(3,*),ZVEC(3)

      DATA ISATD /0/                   ! PRN of central satellite

                     ! SEARCH FOR LOST SATELLITES IN ESTABLISHED & PAIRS LISTS
      DO  I=1,NR                       ! For each satellite removed
         ISGONE = ISR(I)               ! Unsubscripted version of its PRN
         IF (ISGONE.EQ.ISATD)  THEN    ! Central satellite is gone
            WRITE(6,'(''# REMOVE CNETRAL SATELLITE, PRN'',I3.2,'' #'')')
     2         ISATD
            ISATD = 0                  ! Indicate there is now no central sat.
         END IF
         J = 0                         ! Initialize index in established list
         DONE = .FALSE.                ! TRUE when finished looking for ISGONE
         DO WHILE ((.NOT.DONE).AND.(J.LT.NEST))
            J = J + 1                  ! Increment search location
            IF (IEST(J).EQ.ISGONE)  THEN     ! Have found ISGONE in est. list
               DO  K=J,NEST-1                ! Drop higher elements down,
                  IEST(K) = IEST(K+1)        ! covering the lost satellite
               END DO
               NEST = NEST - 1         ! Decrement number is established list
               DONE = .TRUE.           ! Needn't look further
               WRITE(6,'(''# REMOVE ESTABLISHED SATELLITE #'',I2.2,
     2            '' #'')' )  ISGONE
            END IF
         END DO
                              ! NOW TRY THE PAIRS LIST
         DO  JPR=NPR,1,-1  ! Must go top down because pair numbers change
            IF ((IPR(1,JPR).EQ.ISGONE).OR.(IPR(2,JPR).EQ.ISGONE))  THEN
               WRITE(6,'(''# REMOVE PAIR ('',I2.2,''-'',I2.2,'') #'')' )
     2            IPR(1,JPR),IPR(2,JPR) ! This pair contains the deleted sat.
               CALL DELPAIR(JPR,NPR,IPR,LOCPR,LPRDB,NAMB)   ! Delete the pair
            END IF
         END DO
      END DO
      IF (NEST.EQ.1)  NEST = 0      ! One established satellite is meaningless

      IF ((NEST + NPR).EQ.NC)  RETURN     ! There are no pairs to add
                              ! ASSIGN A NEW CENTRAL SATELLITE, IF NECESSARY
      IF (ISATD.EQ.0)  THEN         ! There is no central satellite
         CZAMAX = -2.0D0            ! Init. cosine of zenith angle
         IF (NEST.GT.0)  THEN       ! Use established sat. closest to zenith
            DO  I=1,NEST            ! Search established satellites
               CZA = DPROD3(UVECS(1,LOCSAT(IEST(I))),ZVEC)  ! Cosine z.a.
               IF (CZA.GT.CZAMAX)  THEN         ! It's the closest so far
                  ISATD = IEST(I)               ! Assign central satellite
                  CZAMAX = CZA                  ! New maximum cos(z.a.)
               END IF
            END DO
         ELSE                       ! Use closest sat. to zenith
            DO  I=1,NC              ! Search all satellites in common list
               CZA = DPROD3(UVECS(1,I),ZVEC)    ! Cosine of zenith angle
               IF (CZA.GT.CZAMAX)  THEN         ! Closest so far
                  ISATD = ISATC(I)              ! Assign central satellite
                  CZAMAX = CZA                  ! New maximum cos(z.a.)
               END IF
            END DO
         END IF
         WRITE(6,'(''# ASSIGN NEW CENTRAL SATELLITE, PRN'',I3.2,
     2      '' #'')' ) ISATD                    ! Tell user which it is
      END IF
                              ! ASSIGN NEW SATELLITES TO PAIRS
      DO  I=1,NC                       ! For each satellite being tracked
         JSAT = ISATC(I)                        ! PRN number
         IF (JSAT.NE.ISATD)  THEN               ! Don't process central sat.
            FOUND = .FALSE.                     ! Haven't found this sat. yet
            J = 1                               ! Try estab. satellites first
            DO WHILE ((J.LE.NEST).AND.(.NOT.FOUND))   ! Scan established list
               FOUND = IEST(J).EQ.JSAT                ! Here it is
               J = J + 1
            END DO
            JPR = 1     ! Search existing pairs for this sat. if not yet found
            DO WHILE ((JPR.LE.NPR).AND.(.NOT.FOUND))
               FOUND = ((IPR(1,JPR).EQ.JSAT).OR.(IPR(2,JPR).EQ.JSAT))
               JPR = JPR + 1     ! Look in each pair until found or past end
            END DO
            IF (.NOT.FOUND)  THEN         ! This sat. needs to be assigned
               NPR = NPR + 1                       ! Incr. number of pairs
               IPR(1,NPR) = JMIN0(ISATD,JSAT)      ! Assign PRN numbers to
               IPR(2,NPR) = JMAX0(ISATD,JSAT)      ! the pair
               IPRDB = 1         ! Init. loc. of empty slot in pairs database
               DO WHILE (LPRDB(IPRDB))             ! Search for an unused slot
                  IPRDB = IPRDB + 1
               END DO
               LOCPR(NPR) = IPRDB   ! Assign pairs database slot to this pair
               LPRDB(IPRDB) = .TRUE.   ! Mark pairs database slot in use
               COSSEP = DPROD3(UVECS(1,LOCSAT(JSAT)),
     2                         UVECS(1,LOCSAT(ISATD)))
               FLEN(IPRDB) = 2.0D0*DSQRT(5.0D-1*(1.0D0 - COSSEP)) ! Max. ddiff
               NDATP(IPRDB) = 0        ! Init. number of epochs for this pair
               NAMB(IPRDB) = 0         ! Init. number of different ambiguities
               WRITE(6,'(''# PUT NEW PAIR #'',I2,'' ('',I2.2,''-'',
     2            I2.2,'')  IN SLOT'',I2,'' #'')' )
     3               NPR, IPR(1,NPR),IPR(2,NPR), IPRDB
            END IF
         END IF
      END DO

      RETURN
      END
