      INTEGER FUNCTION MCSORT_ORDER(INDX,N,MAXN,IEXACT,
     >     ORDER_RULE,DATA1,ELEMENT1)
C---------------------------------------------------------------
C  MCSORT_ORDER
C  ------------
C
C
C  BINARY SEARCH ALGORITHM
C   ORDERING RULE SPECIFIED BY *EXTERNAL PASSED ROUTINE*
C      ORDER_RULE
C
C  VSN DMC 6 DEC 1985 ** ASSUMING SORTING ON CHARACTER DATA **
C
C  INPUT:
      INTEGER INDX(MAXN)	! SORTED INDEX ARRAY
      INTEGER N		! NUMBER OF ELEMENTS CURRENTLY SORTED
C
C	MAXN = MAX NUMBER OF ELEMENTS IN SORTED LIST
C
      CHARACTER*(*) DATA1(MAXN)
      CHARACTER*(*) ELEMENT1
C
C	DATAn= LIST CHARACTER DATA ARRAY
C       ELEMENTn = ELEMENT CHARACTER DATA
C
      INTEGER ORDER_RULE
      EXTERNAL ORDER_RULE
C
C  **EXTERNAL USER SUPPLIED INTEGER FUNCTION ORDER_RULE**
C	L = ORDER_RULE(I,INDX,MAXN,DATA1,ELEMENT1)
C
C       L = -1 IF ELEMENT IS "LESS THAN" DATA...(INDX(I))
C       L = 0  IF ELEMENT IS "EQUAL TO"  DATA...(INDX(I))
C	L = +1 IF ELEMENT IS "GREATER THAN" DATA...(INDX(I))
C
C  OUTPUT:
C       IEXACT=1 IF ELEMENT MATCHES EXISTING DATA ELEMENT PRECISELY
C             =0 O.W.
C
C       MCSORT_ORDER PTS TO SORT ARRAY INDX
C  ELEMENT... IS "LESS THAN OR EQUAL TO"  DATA...(INDX(MCSORT_ORDER))
C  IF ELEMENT IS "GREATER THAN" ALL DATA...ELEMENTS,
C       MCSERT_ORDER = N+1 IS RETURNED
C
C--------------------------------------------
C  EXECUTABLE CODE
C
C  CHECK FOR ZERO DATA IN LIST, OR ELEMENT .GT. GREATEST ELEMENT IN LIST
C
      IF(N.EQ.0) THEN
        IENDL=1
      ELSE
        L = ORDER_RULE(N,INDX,MAXN,DATA1,ELEMENT1)
        IF(L.EQ.1) THEN
          IENDL=1
        ELSE
          IENDL=0
        ENDIF
      ENDIF
C
C  SPECIFY ELEMENT OFF END OF LIST...
      IF(IENDL.EQ.1) THEN
        IEXACT=0
        MCSORT_ORDER=N+1
        RETURN
      ENDIF
C
C  BINARY SEARCH LOOP
C
 100  CONTINUE
C
C  ITOP,IBOT= RANGE REMAINING TO BE SEARCHED
C
      ITOP=N
      IBOT=1
      ITER=0
C
 110  CONTINUE
C
      ITER=ITER+1
C  ERROR CHECK
      IF(ITER.GT.N) THEN
        write(6,9902)
 9902 FORMAT(' ?MCSORT_ORDER FAILED:  TOO MANY ITERATIONS')
        ZANS=-FLOAT(ITER**2)
        ZANSI=1.0/SQRT(ZANS)  ! BRING ABOUT AN ABNORMAL PROGRAM TERMINATION
        WRITE(6,'(1PE11.4)') ZANSI
      ENDIF
C
      IMID=(ITOP+IBOT)/2
C
        L = ORDER_RULE(IMID,INDX,MAXN,DATA1,ELEMENT1)
C
      IF(L) 140,120,150
C
C  EQUALITY
C
 120  CONTINUE
      IEXACT=1
      MCSORT_ORDER=IMID
      RETURN
C
C  ELEMENT... .LT. DATA...(INDX(IMID))
C
 140  CONTINUE
      ITOP=IMID
C  DONE ?
      IF(IBOT.EQ.ITOP) THEN
        IEXACT=0
        MCSORT_ORDER=ITOP
        RETURN
      ENDIF
C
      GO TO 110  ! KEEP LOOKING
C
C  ELEMENT... .GT. DATA...(INDX(IMID))
 150  CONTINUE
      IBOT=IMID+1
C  ERROR CHECK
      IF(IBOT.GT.ITOP) THEN
        write(6,9901)
 9901 FORMAT(' ?MCSORT_ORDER FAILED:  OUT OF ORDER')
        ZANS=-FLOAT(ITER**2)
        ZANSI=1.0/SQRT(ZANS)  ! BRING ABOUT AN ABNORMAL PROGRAM TERMINATION
        WRITE(6,'(1PE11.4)') ZANSI
      ENDIF
      GO TO 110
C
      END
