(FILECREATED "17-Jul-86 00:20:11" {QV}<NOTECARDS>1.3K>RHTPATCH077.;2 55162  

      changes to:  (FNS NC.CardInspectorAttachedMenuWhenSelectedFn NC.BuildCardPartsInspector 
			NC.MessageWinAttachedMenuWhenSelectedFn NC.ScavengerPhase1 
			NC.BuildTitlesInspectorMenu NC.ScavengeDatabaseFile NC.CardInspectorCloseFn 
			NC.GetScavengerInfo NC.BuildBadCardsList)
		   (VARS RHTPATCH077COMS)

      previous date: "16-Jul-86 22:11:43" {QV}<NOTECARDS>1.3K>RHTPATCH077.;1)


(* Copyright (c) 1986 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT RHTPATCH077COMS)

(RPAQQ RHTPATCH077COMS ((* * Changes to NCREPAIR)
			  (VARS (NC.CardsPerMenuLimit 100))
			  (FNS NC.CardInspectorAttachedMenuWhenSelectedFn NC.CardInspectorCloseFn 
			       NC.MessageWinAttachedMenuWhenSelectedFn NC.GetScavengerInfo 
			       NC.BuildBadCardsList NC.ScavengerPhase1 NC.BuildCardPartsInspector 
			       NC.BuildTitlesInspectorMenu NC.ScavengeDatabaseFile)))
(* * Changes to NCREPAIR)


(RPAQQ NC.CardsPerMenuLimit 100)
(DEFINEQ

(NC.CardInspectorAttachedMenuWhenSelectedFn
  (LAMBDA (Item Menu MouseKey)                               (* rht: "16-Jul-86 23:59")

          (* * Called when leaving the main cards inspector menu. User is either aborting the scavenge or absorbing changes 
	  and continuing. In latter case, we need to recompute scavenger array to check for if she has fixed whatever 
	  problems there were. If so, then continue with link scavenge.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object formats.)



          (* * kirk 23Jan86 Changed to use NC.AskYesOrNo)



          (* * rht 3/24/86: Added call to NC.CloseInspectorWindows.)



          (* * rht 7/16/86: Added NC.AttachPromptWindow calls. String search is now case INsensitive.)


    (LET ((MainWin (MAINWINDOW (WFROMMENU Menu)))
	  (Operation (CAR Item))
	  MessageWin NoteFile InspectorWins NextWin MenuWindows SearchString)
         (SETQ MessageWin (MAINWINDOW MainWin))
         (SETQ MenuWindows (WINDOWPROP MessageWin (QUOTE MENUWINDOWS)))
         (if (AND (OR (NEQ Operation (QUOTE Abort))
			    (PROGN (NC.AskYesOrNo 
				     "Do you really want to abort the Inspect & Repair process? "
						      NIL
						      (QUOTE Yes)
						      T
						      (NC.AttachPromptWindow MessageWin)
						      NIL NIL)))
		      (OR (NOT (FMEMB Operation (QUOTE (Abort Done))))
			    (for Win in (SETQ InspectorWins (WINDOWPROP MessageWin
										(QUOTE 
										 INSPECTORWINDOWS)))
			       never (OPENWP Win))
			    (PROG2 (NC.PrintMsg (NC.AttachPromptWindow MessageWin)
						    T "There are open card inspector windows.")
				     (if (NC.YesP (NC.AskUser "Want to close them? " NIL "Yes" 
								    NIL (NC.AttachPromptWindow
								      MessageWin)
								    NIL NIL T))
					 then (for Win in InspectorWins when (OPENWP Win)
						   do (CLOSEW Win))
						T))))
	     then (SETQ NoteFile (WINDOWPROP MainWin (QUOTE NOTEFILE)))
		    (SELECTQ Operation
			       (Abort (WINDOWDELPROP MainWin (QUOTE CLOSEFN)
						       (FUNCTION NC.CardInspectorCloseFn))
				      (NC.CardInspectorCloseFn MainWin T)
				      (CLOSEW MainWin))
			       (Done (DETACHWINDOW MainWin)
				     (WINDOWDELPROP MainWin (QUOTE CLOSEFN)
						      (FUNCTION NC.CardInspectorCloseFn))
				     (NC.CloseInspectorWindows MessageWin)
				     (for MenuWin in (WINDOWPROP MessageWin (QUOTE 
										      MENUWINDOWS))
					unless (EQ MenuWin MainWin)
					do (WINDOWDELPROP MenuWin (QUOTE CLOSEFN)
							      (FUNCTION NC.CardInspectorCloseFn))
					     (CLOSEW MenuWin))
				     (if (WINDOWPROP MainWin (QUOTE MADECHANGES))
					 then (WINDOWPROP MessageWin (QUOTE NEEDCHECKPOINT)
							      T))
				     (WINDOWPROP MessageWin (QUOTE NEEDLINKSCAVENGE)
						   (OR (WINDOWPROP MessageWin (QUOTE 
										 NEEDLINKSCAVENGE))
							 (WINDOWPROP MainWin (QUOTE 
										 NEEDLINKSCAVENGE))))
				     (CLOSEW MainWin)

          (* This "recursive" call will check to make sure everything is okay before invoking link scavenge.
	  I'm calling with ReadSubstancesFlg off, even if this call had it on. That's because we don't want it to be so slow 
	  on the second go-around.)


				     (NC.ScavengerPhase1 NoteFile NIL MessageWin NIL (
							     NC.AttachPromptWindow MessageWin)))
			       (Search 

          (* Simple-minded search for titles of cards containing the given search string. User is asked for string in the 
	  prompt window, but answer appears in MessageWin for easy access.)


				       (SETQ SearchString (NC.AskUser "Search string? " NIL NIL T
									  (NC.AttachPromptWindow
									    MessageWin)
									  T T NIL))
				       (NC.PrintMsg (NC.AttachPromptWindow MessageWin)
						      T "Searching ... ")
				       (NC.PrintMsg MessageWin NIL 
						      "Card titles containing string '"
						      SearchString "': "
						      (NC.MapCards
							NoteFile
							(FUNCTION (LAMBDA (Card PredicateResult)
							    PredicateResult))
							(FUNCTION (LAMBDA (Card)
							    (LET ((Title (
								   NC.FetchTitleFromScavengerInfo
									   Card)))
							         (if (STRPOS (U-CASE 
										     SearchString)
										 (U-CASE Title))
								     then (CONCAT (
										  NC.FetchSlotNum
											Card)
										      ": " Title)
								   else NIL)))))
						      (CHARACTER 13))
				       (NC.ClearMsg (NC.AttachPromptWindow MessageWin)
						      T))
			       (Previous% Page               (* Get previous menu window by accessing list of 
							     windows cached on MessageWin.)
					       (DETACHWINDOW MainWin)
					       (MOVEW MainWin NC.OffScreenPosition)
					       (ATTACHWINDOW (SETQ NextWin
								 (if (EQ MainWin (CAR 
										      MenuWindows))
								     then (CAR (LAST 
										      MenuWindows))
								   else (CAR (NLEFT
										   MenuWindows 1
										   (FMEMB MainWin 
										      MenuWindows)))))
							       MessageWin
							       (QUOTE BOTTOM)
							       (QUOTE LEFT)))
			       (Next% Page                   (* Get next menu window by accessing list of windows 
							     cached on MessageWin.)
					   (DETACHWINDOW MainWin)
					   (MOVEW MainWin NC.OffScreenPosition)
					   (ATTACHWINDOW (SETQ NextWin
							     (if (EQ MainWin (CAR (LAST
											  MenuWindows)
											))
								 then (CAR MenuWindows)
							       else (CADR (FMEMB MainWin 
										      MenuWindows))))
							   MessageWin
							   (QUOTE BOTTOM)
							   (QUOTE LEFT)))
			       (First% Page                  (* Get first menu window by accessing list of windows 
							     cached on MessageWin.)
					    (if (EQ MainWin (SETQ NextWin (CAR MenuWindows)))
						then (FLASHW MainWin)
					      else (DETACHWINDOW MainWin)
						     (MOVEW MainWin NC.OffScreenPosition)
						     (ATTACHWINDOW NextWin MessageWin (QUOTE
								       BOTTOM)
								     (QUOTE LEFT))))
			       NIL)))))

(NC.CardInspectorCloseFn
  (LAMBDA (Win Don'tAskFlg)                                  (* rht: "16-Jul-86 22:02")

          (* * Closing inspector window is just like selecting "abort" from attached menu, i.e. abort the repair process.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object formats.)



          (* * kirk 23Jan86 Changed to use NC.AskYesOrNo)



          (* * rht 3/24/86: Added call to NC.CloseInspectorWindows.)



          (* * rht 7/16/86: Added NC.AttachPromptWindow call.)


    (LET ((MainWin (MAINWINDOW Win)))
         (if (OR Don'tAskFlg (NC.AskUser 
				     "Do you really want to abort the Inspect & Repair process? "
					       NIL
					       (QUOTE Yes)
					       T
					       (NC.AttachPromptWindow MainWin)
					       NIL NIL))
	     then (DETACHWINDOW Win)
		    (NC.CloseInspectorWindows MainWin)
		    (for MenuWin in (WINDOWPROP MainWin (QUOTE MENUWINDOWS))
		       unless (EQ MenuWin Win)
		       do (WINDOWDELPROP MenuWin (QUOTE CLOSEFN)
					     (FUNCTION NC.CardInspectorCloseFn))
			    (DETACHWINDOW MenuWin)
			    (CLOSEW MenuWin))
		    (WINDOWDELPROP MainWin (QUOTE CLOSEFN)
				     (FUNCTION NC.MessageWinCloseFn))
		    (CLOSEW MainWin)
		    (MOVEW Win NC.OffScreenPosition)
		    (NC.ScavengerCleanup MainWin)
	   else (QUOTE DON'T)))))

(NC.MessageWinAttachedMenuWhenSelectedFn
  (LAMBDA (Item Menu MouseKey)                               (* rht: "17-Jul-86 00:05")

          (* * Called when selecting from the attached menu to the main message window.)



          (* * rht 9/17/85: Now gets MaxIDNum from WINDOWPROP of MessageWin and uses it for looping through cards.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object fomats.)



          (* * rht 3/22/86: Took out NOTIFY.EVENT stuff since NC.ScavengerPhase1 is no longer hanging on completion of phase 
	  3.0)



          (* * rht 7/16/86: Added NC.AttachPromptWindow calls.)


    (LET ((MenuWin (WFROMMENU Menu))
	  (Operation (CAR Item))
	  MessageWin NoteFile InspectorWins BadNewsList ExtraBadNews)
         (SETQ MessageWin (MAINWINDOW MenuWin))
         (SETQ NoteFile (WINDOWPROP MessageWin (QUOTE NOTEFILE)))
         (SETQ BadNewsList (WINDOWPROP MessageWin (QUOTE BADNEWSLIST)))
         (SETQ ExtraBadNews (WINDOWPROP MessageWin (QUOTE EXTRABADNEWS)))
         (SELECTQ Operation
		    (Abort (if (NC.AskYesOrNo 
				     "Do you really want to abort the Inspect & Repair process? "
						  NIL
						  (QUOTE Yes)
						  T
						  (NC.AttachPromptWindow MessageWin)
						  NIL NIL)
			       then                        (* Bail out.)
				      (WINDOWDELPROP MessageWin (QUOTE CLOSEFN)
						       (FUNCTION NC.MessageWinCloseFn))
				      (CLOSEW MessageWin)
				      (NC.ScavengerCleanup MessageWin)))
		    (Recheck% Bad% Cards                     (* Rerun the end of phase1.)
					 (DETACHWINDOW MenuWin)
					 (CLOSEW MenuWin)
					 (NC.ScavengerPhase1 NoteFile NIL MessageWin T
							       (NC.AttachPromptWindow MessageWin)))
		    (Inspect% Cards                          (* Bring up the big card inspector menu.)
				    (DETACHWINDOW MenuWin)
				    (CLOSEW MenuWin)
				    (NC.BuildCardInspectorMenu
				      (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
							 Card))
						     (FUNCTION (LAMBDA (Card)
							 (AND (FMEMB (NC.FetchStatus Card)
									 (QUOTE (ACTIVE BADPOINTER 
											  NIL)))
								(NOT (NC.WorthlessCardP Card))))))
				      (APPEND ExtraBadNews BadNewsList)
				      NoteFile MessageWin))
		    (Include% Deleted% Cards                 (* Like above except include also the deleted cards.)
					     (DETACHWINDOW MenuWin)
					     (CLOSEW MenuWin)
					     (NC.BuildCardInspectorMenu
					       (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
								  Card))
							      (FUNCTION (LAMBDA (Card)
								  (AND (FMEMB
									   (NC.FetchStatus Card)
									   (QUOTE (ACTIVE 
										       BADPOINTER NIL 
											  DELETED)))
									 (NOT (NC.WorthlessCardP
										  Card))))))
					       (APPEND ExtraBadNews BadNewsList)
					       NoteFile MessageWin))
		    (Continue% Repair                        (* If changes were made, then checkpoint the 
							     notefile.)
				      (if (NEQ (NC.CheckForBadLinksAndTitlesAndPropLists 
											 NoteFile 
										       MessageWin 
										      BadNewsList)
						   (QUOTE ABORT))
					  then (if (WINDOWPROP MessageWin (QUOTE 
										   NEEDCHECKPOINT))
						     then (NC.CheckpointDatabase NoteFile NIL NIL 
										     NIL NIL
										     (
									    NC.AttachPromptWindow
										       MessageWin)))
						 (WINDOWDELPROP MessageWin (QUOTE CLOSEFN)
								  (FUNCTION NC.MessageWinCloseFn))
						 (CLOSEW MessageWin) 
                                                             (* Rebuild the links.)
						 (NC.ScavengeDatabaseFile NoteFile
									    (WINDOWPROP
									      MessageWin
									      (QUOTE 
										  LINKSLABELSNEWS))
									    (WINDOWPROP
									      MessageWin
									      (QUOTE BADBOXES))
									    (WINDOWPROP
									      MessageWin
									      (QUOTE 
									      CARDSWITHLINKSRESET))
									    (WINDOWPROP
									      MessageWin
									      (QUOTE 
										 INTERESTEDWINDOW)))))
		    (End% Inspect&Repair                     (* Don't have to scavenge links.
							     Close up gracefully.)
					 (NC.CheckForBadLinksAndTitlesAndPropLists NoteFile 
										     MessageWin 
										     BadNewsList)
					 (WINDOWDELPROP MessageWin (QUOTE CLOSEFN)
							  (FUNCTION NC.MessageWinCloseFn))
					 (CLOSEW MessageWin)
					 (NC.CloseDatabaseFile NoteFile))
		    NIL))))

(NC.GetScavengerInfo
  (LAMBDA (NoteFile ReadSubstancesFlg MessageWin InterestedWindow)
                                                             (* rht: "16-Jul-86 22:08")

          (* * Return an array containing pointers to all valid versions of notecard parts, i.e. substances, titles, links, 
	  and proplists. If ReadSubstancesFlg is non-nil, then read substances when checking rather than just checking that 
	  start and end substance pointers make sense.)



          (* * rht 9/17/85: Now keeps track of largest ID seen and caches on MessageWin's WINDOWPROP.)



          (* * rht 12/1/85: Updated to handle new notefile and card format. Ripped out MaxIDNum stuff.)



          (* * rht 7/16/86: Added InterestedWindow arg.)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
	  EndPtr CurPtr BadCardTypesList)
         (SETQ EndPtr (GETEOFPTR Stream))                (* Initialize bad card types list to nil.
							     NC.RobustReadCardPart will add to it as it finds 
							     unknown card types.)
         (WINDOWPROP MessageWin (QUOTE BADCARDTYPESLIST)
		       NIL)
         (NC.PrintMsg InterestedWindow T "Processing data area of notefile ..." (CHARACTER 13)
			"Searching for start of data area ..."
			(CHARACTER 13))                    (* Find start of data area)
         (SETQ CurPtr (NC.SearchFor### Stream 0))        (* Walk, don't run, through the data area trying to 
							     find good card parts.)
         (if (for bind (LastPtrHighBits ← 0)
			     CurPtrHighBits Card
		  eachtime (BLOCK) while (AND CurPtr (LESSP CurPtr EndPtr))
		  do                                       (* Print a message every 8K or so bytes.)
		       (if (GREATERP (SETQ CurPtrHighBits (LRSH CurPtr 13))
					 LastPtrHighBits)
			   then (NC.PrintMsg InterestedWindow T 
						 "Processing data area of notefile ..."
						 (CHARACTER 13)
						 "Byte number: "
						 (QUOTIENT CurPtr 1000)
						 "K out of "
						 (QUOTIENT EndPtr 1000)
						 "K."
						 (CHARACTER 13))
				  (SETQ LastPtrHighBits CurPtrHighBits))
                                                             (* Try to read a card part.
							     If returns nil, then search for next # marker and try 
							     again.)
		       (if (SETQ Card (NC.RobustReadCardPart NoteFile ReadSubstancesFlg 
								   MessageWin EndPtr))
			   then (SETQ CurPtr (GETFILEPTR Stream))
			 else (SETQ CurPtr (NC.SearchFor### Stream (PLUS 4 CurPtr))))
		  finally (RETURN (QUOTE SUCCESS)))
	     then (NC.ClearMsg InterestedWindow T)
		    (QUOTE SUCCESS)))))

(NC.BuildBadCardsList
  (LAMBDA (NoteFile MessageWin FirstTimeFlg InterestedWindow)
                                                             (* rht: "16-Jul-86 22:10")

          (* * Returns a list of all IDs with illegal index pointers, i.e. pointers not to valid data areas recorded in 
	  ScavengerArray. Also record those IDs with pointers beyond checkpoint ptr.)



          (* * rht 9/17/85: Now takes MessageWin argument so can extract the MaxIDNum off its props.)



          (* * rht 12/7/85: Modified to reflect new card and notefile object formats.)



          (* * fgh 2/4/86 Fixed minor bug where UNKNOWNCARDTYPE apeeared in a singleton list.)



          (* * rht 7/16/86: Added InterestedWindow arg.)


    (LET ((CardTotal (SUB1 (fetch (NoteFile NextIndexNum) of NoteFile)))
	  (CheckptPtr (fetch (NoteFile CheckptPtr) of NoteFile))
	  (Num 0)
	  Results)
         (NC.PrintMsg InterestedWindow T "Building bad cards list ..." (CHARACTER 13)
			"Processing item number " 1 " out of " CardTotal "." (CHARACTER 13))
         (NC.MapCards NoteFile
			(FUNCTION (LAMBDA (Card)
			    (LET (Problems)
			         (SETQ Num (ADD1 Num))
			         (if (ZEROP (IREMAINDER Num 100))
				     then (NC.PrintMsg InterestedWindow T 
							   "Building bad cards list ..."
							   (CHARACTER 13)
							   "Processing item number " Num " out of " 
							   CardTotal "." (CHARACTER 13)))
                                                             (* If card is not worthless, has reasonable status, 
							     and at least one problem, then make a bad card entry 
							     for it.)
			         (if (AND (NOT (NC.WorthlessCardP Card))
					      (FMEMB (NC.FetchStatus Card)
						       (QUOTE (ACTIVE DELETED SPECIAL BADPOINTER 
									NIL)))
					      (SETQ Problems
						(LET ((IndexLocsProblems (NC.CheckIndexLocs Card 
										       MessageWin 
										       CheckptPtr 
										     FirstTimeFlg))
						      (Type (NC.FetchTypeFromScavengerInfo Card)))
						     (if (AND Type (NOT (NCP.ValidCardType
										Type)))
							 then (CONS (QUOTE UNKNOWNCARDTYPE)
									IndexLocsProblems)
						       else IndexLocsProblems))))
				     then (push Results (BQUOTE (, Card , (NC.FetchStatus
									   Card)
									 ,
									 (NC.EncodeCardProblems
									   Problems)
									 ,@ Problems))))))))
         (NC.ClearMsg InterestedWindow T)
     Results)))

(NC.ScavengerPhase1
  (LAMBDA (FileNameOrNoteFile ReadSubstancesFlg ScavengerInteractionWin RecheckBadCardsFlg 
			      InterestedWindow)              (* rht: "17-Jul-86 00:08")

          (* * This is the first phase of the scavenger. Runs over entire data portion of the notefile, accumulating pointers
	  to healthy parts of cards. Then runs over index array asking user what to do with bad or outdated pointers.
	  If ReadSubstancesFlg is non-nil then it'll do robust gets of the substances. This slows things down, but makes 
	  checking more comprehensive.)



          (* * rht 12/7/85: Updated to handle new notefile and card object formats.)



          (* * rht 3/22/86: No longer hangs bad cards off proplist of Reason atoms. Uses local var ReasonsHashArray instead.
	  NC.ScavengerPhase1 no longer hanging on completion of phase 3)



          (* * rht 7/7/86: Now passes non-nil Don'tCheckOperationInProgress flg to NC.OpenDatabaseFile.)



          (* * rht 7/16/86: Added InterestedWindow arg.)


    (PROG (FileName NoteFile UnknownCardTypesList ReasonsList ReasonsHashArray CardsToDelete Menu 
		      MenuItems LinkLabelsNews CardTotal BadNewsList BadBoxes ExtraBadNews 
		      FirstTimeFlg InspectorPendingEvent NoteFileMenu NoteFileOpsMenuItem 
		      CanDoPhase3Flg NoteFileStream)

          (* * First, take care of opening notefile if needed.)


	    (if (AND (type? NoteFile FileNameOrNoteFile)
			 (SETQ NoteFileStream (fetch (NoteFile Stream) of FileNameOrNoteFile))
			 (OPENP NoteFileStream))
		then                                       (* This notefile is already open For when we do 
							     recursive call.)
		       (SETQ NoteFile FileNameOrNoteFile)
	      else                                         (* Get file name and open the file if conditions are 
							     okay.)
		     (SETQ FileName FileNameOrNoteFile)
		     (AND (NULL FileName)
			    (NULL (SETQ FileName (NC.DatabaseFileName 
					   "What is the name of the NoteFile to Inspect&Repair? "
									    NIL T NIL NIL 
									    InterestedWindow)))
			    (RETURN NIL))
		     (AND (NULL (SETQ NoteFile
				      (NC.OpenDatabaseFile FileName NIL T NIL NIL NIL NIL T T NIL 
							     InterestedWindow T)))
			    (NC.PrintMsg InterestedWindow NIL "Couldn't open " FileName "."
					   (CHARACTER 13)
					   "Repair aborted."
					   (CHARACTER 13))
			    (RETURN NIL))
		     (NC.ClearMsg InterestedWindow T))
	    (SETQ CardTotal (SUB1 (fetch (NoteFile NextIndexNum) of NoteFile)))
                                                             (* Build a window for talking to the user if one 
							     wasn't passed in.)
	    (if (WINDOWP ScavengerInteractionWin)
		then (CLEARW ScavengerInteractionWin)
	      else (SETQ ScavengerInteractionWin (CREATEW NC.ScavengerInteractionWinRegion 
							      "Inspect&Repair Interaction Window"
								NIL T))
                                                             (* This flg indicates that we're in the first call to 
							     the scavenger.)
		     (SETQ FirstTimeFlg T)
		     (WINDOWADDPROP ScavengerInteractionWin (QUOTE CLOSEFN)
				      (FUNCTION NC.MessageWinCloseFn)
				      T))                    (* Stash InterestedWindow for calls to phase 3 under 
							     menu whenselected fn.)
	    (OR (WINDOWPROP ScavengerInteractionWin (QUOTE INTERESTEDWINDOW))
		  (WINDOWPROP ScavengerInteractionWin (QUOTE INTERESTEDWINDOW)
				InterestedWindow))           (* Get all relevant info about the data area of the 
							     notefile onto the cards' prop lists.)
	    (if (OR (NOT FirstTimeFlg)
			(EQ (NC.GetScavengerInfo NoteFile ReadSubstancesFlg 
						     ScavengerInteractionWin InterestedWindow)
			      (QUOTE SUCCESS)))
		then (WINDOWPROP ScavengerInteractionWin (QUOTE NOTEFILE)
				     NoteFile)
		       (WINDOWPROP ScavengerInteractionWin (QUOTE CARDTOTAL)
				     CardTotal)
	      else                                         (* Something's wrong. Couldn't get scavenger info.
							     Bail out.)
		     (NC.ScavengerCleanup ScavengerInteractionWin InterestedWindow)
		     (CLOSEW ScavengerInteractionWin)
		     (RETURN NIL))

          (* * Check the list of card types that are undefined to see if user has loaded a definition since the last time we 
	  checked. If he has, then go try to read the substance card parts for those newly defined card types.)


	    (NC.CheckUnknownCardTypes NoteFile ReadSubstancesFlg ScavengerInteractionWin)

          (* * Next step is to run down the in-core index and find those cards having pointers to bad items in the data area.
	  We also need to look for undefined card types and for pointers past the checkpoint pointer.
	  However, we can reuse old bad news list if nothing has changed.)


	    (if (OR FirstTimeFlg RecheckBadCardsFlg (WINDOWPROP ScavengerInteractionWin
								      (QUOTE NEEDCHECKPOINT)))
		then (WINDOWPROP ScavengerInteractionWin (QUOTE ORIGINALBADNEWSLIST)
				     (SETQ BadNewsList (NC.BuildBadCardsList NoteFile 
									  ScavengerInteractionWin 
										 FirstTimeFlg 
										 InterestedWindow)))
	      else (SETQ BadNewsList (WINDOWPROP ScavengerInteractionWin (QUOTE 
									      ORIGINALBADNEWSLIST))))

          (* * Okay, now all the troublesome IDs and the reasons for their troubles are recorded in BadNewsList.
	  We next need to get directives from the user as to what to do for each problem card.)


	    (NC.RepositionWindowIfNeeded ScavengerInteractionWin)
                                                             (* If there's bad news for link labels then take off 
							     list and store in a local var.)
	    (if (SETQ LinkLabelsNews (for BadCardEntry in BadNewsList
					    bind (LinkLabelsCard ←(fetch (NoteFile LinkLabelsCard)
								       of NoteFile))
					    eachtime (BLOCK) when (NC.SameCardP 
										   LinkLabelsCard
											(CAR 
										     BadCardEntry))
					    do (RETURN BadCardEntry)))
		then (SETQ BadNewsList (DREMOVE LinkLabelsNews BadNewsList)))
                                                             (* Accumulate general statistics on the problems.)
	    (SETQ ReasonsHashArray (HASHARRAY 100))
	    (for BadNews in BadNewsList bind Card Type eachtime (BLOCK)
	       unless (FMEMB (CADR BadNews)
				 (QUOTE (DELETED FREE)))
	       do (SETQ Card (CAR BadNews))
		    (for Reason in (CDDDR BadNews) eachtime (BLOCK)
		       do (PUTHASH Reason (CONS Card (GETHASH Reason ReasonsHashArray))
				       ReasonsHashArray)
			    (if (NOT (FMEMB Reason ReasonsList))
				then (SETQ ReasonsList (CONS Reason ReasonsList)))
			    (if (EQ Reason (QUOTE UNKNOWNCARDTYPE))
				then                       (* Accumulate the list of unknown card types for 
							     nondeleted cards.)
				       (if (NOT (FMEMB (SETQ Type (
								 NC.FetchTypeFromScavengerInfo
								 Card))
							     UnknownCardTypesList))
					   then (push UnknownCardTypesList Type)))))
                                                             (* Build the menu entries that we know will be present
							     regardless of which cards are bad.)
	    (SETQ MenuItems (QUOTE ((Abort (QUOTE Abort)
					       "Quit this Inspect&Repair operation.")
					 (Recheck% Bad% Cards (QUOTE Recheck% Bad% Cards)
							      
	    "Recompute bad cards list.  Useful if you've just loaded some card type definitions.")
					 (Inspect% Cards (QUOTE Inspect% Cards)
							 "Bring up the cards inspector menu."
							 (SUBITEMS (Include% Deleted% Cards
								     (QUOTE Include% Deleted% Cards)
								     
								"Throw in deleted cards as well.")))))
	      )                                              (* Print a message if news on link labels is worse 
							     than just past checkpoint.)
	    (if (AND LinkLabelsNews (NOT (EQUAL (CDDDR LinkLabelsNews)
							(QUOTE (MAINDATAPASTCHKPT)))))
		then (push ExtraBadNews LinkLabelsNews)
		       (NC.PrintMsg ScavengerInteractionWin NIL "The link types are bad."
				      (CHARACTER 13)
				      
"If you don't back them up to a previous version, then phase 3 of Inspect&Repair will rebuild them."
				      (CHARACTER 13))
		       (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE)
				     T))                     (* Collect any fileboxes that have bad substances.)
	    (if (SETQ BadBoxes (LET (Boxes)
				        (SETQ BadNewsList
					  (for News in BadNewsList bind Box eachtime
										   (BLOCK)
					     unless (if (AND (EQ (
								    NC.FetchTypeFromScavengerInfo
									   (SETQ Box (CAR News)))
									 (QUOTE FileBox))
								   (FMEMB (QUOTE BADMAINDATA)
									    (CDDDR News)))
							  then (push Boxes Box) 
                                                             (* If nothing else is wrong with those boxes, then 
							     take off bad news list.)
								 (EQ (LENGTH (CDDDR News))
								       1)
							else NIL)
					     collect News))
				    Boxes))
		then (NC.PrintMsg ScavengerInteractionWin NIL "Fileboxes "
				      (for Box in BadBoxes collect (
								   NC.FetchTitleFromScavengerInfo
									   Box))
				      " have bad substance(s)."
				      (CHARACTER 13)
				      
"If you don't delete them or back up to a previous version, then phase 3 of Inspect&Repair will rebuild their contents."
				      (CHARACTER 13))
		       (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE)
				     T))                     (* Print out totals of active and deleted cards.)
	    (LET ((ActivesTotal 0)
		  (DeletedsTotal 0))
	         (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
				    (SELECTQ (NC.FetchStatus Card)
					       (ACTIVE (SETQ ActivesTotal (ADD1 ActivesTotal)))
					       (DELETED (SETQ DeletedsTotal (ADD1 DeletedsTotal)))
					       NIL))))
	         (NC.PrintMsg ScavengerInteractionWin NIL "Out of " CardTotal " cards:"
				(CHARACTER 13)
				"there are " ActivesTotal " active cards and " DeletedsTotal 
				" deleted cards."
				(CHARACTER 13)))
	    (if ReasonsList
		then                                       (* Print out messages for bad cards.)
		       (NC.PrintMsg ScavengerInteractionWin NIL "Of the non-deleted ones,"
				      (CHARACTER 13))
		       (for Reason in ReasonsList eachtime (BLOCK)
			  do (NC.PrintMsg ScavengerInteractionWin NIL (LENGTH (GETHASH Reason 
										 ReasonsHashArray))
					      " have "
					      (GETPROP Reason (QUOTE ReasonString))
					      (CHARACTER 13))
			       (if (EQ Reason (QUOTE UNKNOWNCARDTYPE))
				   then (NC.PrintMsg ScavengerInteractionWin NIL 
							 "The unknown types are: "
							 UnknownCardTypesList "." (CHARACTER 13))))
	      else (NC.PrintMsg ScavengerInteractionWin NIL "All non-deleted cards look okay."
				    (CHARACTER 13)))

          (* Only allow continuation to phase 3 of repair, links rebuilding, if there's no bad news that can't be fixed.
	  We can fix bad proplist, titles or links. We can also fix even bad substances if they're for fileboxes.)


	    (if (for News in BadNewsList eachtime (BLOCK)
		     unless (FMEMB (CADR News)
				       (QUOTE (DELETED FREE)))
		     unless (EQ (NC.FetchTypeFromScavengerInfo (CAR News))
				    (QUOTE FileBox))
		     never (INTERSECTION (CDDDR News)
					     (QUOTE (BADMAINDATA UNKNOWNCARDTYPE))))
		then                                       (* Add the appropriate menu items.)
		       (if (NOT (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE)))
			   then (SETQ MenuItems (CONS (QUOTE (End% Inspect&Repair
								       (QUOTE End% Inspect&Repair)
								       
				      "This exits Inspect&Repair normally, closing the notefile."))
							    MenuItems)))
		       (SETQ CanDoPhase3Flg T)
		       (SETQ MenuItems (CONS (QUOTE (Continue% Repair (QUOTE Continue% Repair)
									    
					       "Complete Inspect&Repair by rebuilding the links."))
						 MenuItems)))
                                                             (* Make sure a checkpoint will happen before 
							     continuing to phase 3 if there are any card parts 
							     beyond the checkpt pointer.)
	    (if (INTERSECTION ReasonsList (QUOTE (MAINDATAPASTCHKPT LINKSPASTCHKPT 
									  TITLEPASTCHKPT 
									  PROPLISTPASTCHKPT)))
		then (AND CanDoPhase3Flg (NC.PrintMsg ScavengerInteractionWin NIL 
		  "'Continue Repair' will integrate any card part versions beyond chkpt pointer."
							    (CHARACTER 13)))
		       (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDCHECKPOINT)
				     T))                     (* Ugliness! Have to cache all these vars on window so
							     that attached menu's whenselectedfn will be able to 
							     grab them.)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE BADNEWSLIST)
			  BadNewsList)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE EXTRABADNEWS)
			  ExtraBadNews)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE LINKSLABELSNEWS)
			  LinkLabelsNews)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE BADBOXES)
			  BadBoxes)
	    (ATTACHMENU (create MENU
				    ITEMS ← MenuItems
				    WHENSELECTEDFN ←(FUNCTION 
				      NC.MessageWinAttachedMenuWhenSelectedFn)
				    MENUFONT ← NC.ScavengerAttachedMenuFont)
			  ScavengerInteractionWin
			  (QUOTE RIGHT)
			  (QUOTE TOP)))))

(NC.BuildCardPartsInspector
  (LAMBDA (Card NoteFile CardsMenuWindow)                    (* rht: "16-Jul-86 23:29")

          (* * Build an attached group of menus for the 4 card parts: substance, links, title, and proplist.
	  These contain items for each version of that part of Card found on Stream. The highlighted item is the one 
	  currently pointed to. Return a list of user's changes.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object formats.)



          (* * rht 7/16/86: Fixed a bug in menu entry naming.)


    (LET ((CheckptPtr (fetch (NoteFile CheckptPtr) of NoteFile))
	  (CardType (NC.FetchTypeFromScavengerInfo Card))
	  (CardStatus (NC.FetchStatus Card))
	  MenusAndItemNums MainWindow Menus OldItemNums)
         (SETQ MenusAndItemNums (LIST (NC.BuildTitlesInspectorMenu Card CardType CheckptPtr)
					  (NC.BuildSubstancesInspectorMenu Card CardType CheckptPtr 
									     CardsMenuWindow)
					  (NC.BuildLinksInspectorMenu Card CheckptPtr)
					  (NC.BuildPropListsInspectorMenu Card CheckptPtr)))
         (SETQ Menus (for MenuAndItemNum in MenusAndItemNums collect (CAR MenuAndItemNum)))
         (SETQ OldItemNums (for MenuAndItemNum in MenusAndItemNums collect (CDR 
										   MenuAndItemNum)))
                                                             (* Titles menu occupies main window.
							     Rest of menus are attached in order below.)
         (SETQ MainWindow (ADDMENU (CAR Menus)
				       NIL
				       (GETBOXPOSITION (fetch (MENU IMAGEWIDTH)
							    of (CAR Menus))
							 (fetch (MENU IMAGEHEIGHT)
							    of (CAR Menus))
							 NIL NIL NIL "Position the card parts menu."))
	   )
         (for Menu in (CDR Menus) do (ATTACHWINDOW (ADDMENU Menu)
							     MainWindow
							     (QUOTE BOTTOM)
							     (QUOTE LEFT)))
                                                             (* Save menus and item numbers of original 
							     selections.)
         (WINDOWPROP MainWindow (QUOTE CARDPARTSMENUS)
		       Menus)
         (WINDOWPROP MainWindow (QUOTE CARDPARTSMENUOLDITEMNUMS)
		       OldItemNums)
         (WINDOWPROP MainWindow (QUOTE NOTEFILE)
		       NoteFile)
         (WINDOWPROP MainWindow (QUOTE CARD)
		       Card)
         (WINDOWPROP MainWindow (QUOTE CARDSMENUWINDOW)
		       CardsMenuWindow)                      (* Shade the original selections.)
         (for Menu in Menus as ItemNum in OldItemNums
	    do (SHADEITEM (CAR (FNTH (fetch (MENU ITEMS) of Menu)
					     ItemNum))
			      Menu NC.LightShade)
		 (PUTMENUPROP Menu (QUOTE CURITEMNUM)
				ItemNum))
         (ATTACHWINDOW (ADDMENU (create
				      MENU
				      ITEMS ←(BQUOTE
					((CANCEL (QUOTE CANCEL)
						 
					 "Quit this card parts inspector, throwing away changes.")
					 (UPDATE (QUOTE UPDATE)
						 "Change to indicated versions for this card.")
					 (RESET (QUOTE RESET)
						  
				       "Go back to original version of card parts for this card.")
					 ,@(if (NOT (NC.UndeletableCardP Card))
					       then (LIST (if (EQ CardStatus (QUOTE DELETED)
									  )
								  then (QUOTE
									   (UNDELETE (QUOTE 
											 UNDELETE)
										     
	      "Undelete this card, restoring to indicated or most recent versions of card parts."))
								else (QUOTE (DELETE (QUOTE
											  DELETE)
											
								     "Mark this card as deleted.")))))
					 ))
				      MENUFONT ← NC.CardInspectorAttachedMenuFont
				      MENUBORDERSIZE ← 1
				      MENUOUTLINESIZE ← 1
				      CENTERFLG ← T
				      MENUROWS ← 2
				      WHENSELECTEDFN ←(FUNCTION 
					NC.CardPartsAttachedMenuWhenSelectedFn)))
			 MainWindow
			 (QUOTE TOP)
			 (QUOTE LEFT))
     MainWindow)))

(NC.BuildTitlesInspectorMenu
  (LAMBDA (Card CardType CheckptPtr)                         (* rht: "16-Jul-86 23:18")

          (* * Make a menu containing items for each title version on Stream for Card. Menu item contains date and title.
	  There is no further detail obtainable for titles. Return cons of menu and current selection.)



          (* * rht 12/8/85: Modified to reflect new card and notefile object formats.)


    (LET ((Versions (NC.FetchScavengerTitleInfo Card))
	  (CurTitleLoc (fetch (Card TitleLoc) of Card))
	  MenuItems SelectionNum Menu)
         (SETQ MenuItems (for TitleInfo in Versions as ItemNum from 1
			      collect (LET ((Loc (CAR TitleInfo))
					      (Date (CADR TitleInfo))
					      (Title (CADDR TitleInfo))
					      Item)
					     (PROG1 (SETQ Item
							(LIST (CONCAT (if (GEQ Loc CheckptPtr)
									      then "*"
									    else "")
									  "["
									  (SUBATOM
									    Title 1
									    (MIN 10 (NCHARS
										     Title)))
									  "] "
									  (OR Date 
									      "NO DATE AVAILABLE"))
								Loc))
						      (if (EQUAL Loc CurTitleLoc)
							  then (SETQ SelectionNum ItemNum))))))
         (if (NULL SelectionNum)
	     then (SETQ MenuItems (CONS (LIST (QUOTE BADTITLE)
						      CurTitleLoc)
					      MenuItems))
		    (SETQ SelectionNum 1))
         (PROG1 (CONS (SETQ Menu (create MENU
						 ITEMS ← MenuItems
						 TITLE ←(CONCAT (if (EQ (NC.FetchStatus
										Card)
									      (QUOTE DELETED))
								      then "DELETED "
								    else "")
								  CardType " | Title Versions")
						 WHENSELECTEDFN ←(FUNCTION 
						   NC.CardPartsMenusWhenSelectedFn)))
			  SelectionNum)                      (* Seems like the only way to communicate to the 
							     whenselectedfn is through menuprops.)
		  (PUTMENUPROP Menu (QUOTE VERSIONS)
				 Versions)
		  (PUTMENUPROP Menu (QUOTE INSPECTORFN)
				 (FUNCTION NC.CardTitleVersionInspector))))))

(NC.ScavengeDatabaseFile
  (LAMBDA (NoteFileOrFileName BadLinkLabelsFlg ListOfBoxesToReconstruct 
			      ListOfCardsNeedingGlobalLinksReconstructed InterestedWindow)
                                                             (* rht: "17-Jul-86 00:19")

          (* Scavenge the database FileName. Essentially throw away all of the information about From and ToLinks and 
	  recreate them by retrieving the link information from the substance of each card and from the list of global links 
	  from the card.)



          (* * rht 8/9/84: Now calls NC.OpenDatabaseFile to do the file open.)



          (* * rht 7/17/85: Changed so can take a stream argument. Also handles link labels. If BadLinkLabelsFlg is non-nil, 
	  then don't try to read current link labels. Just rebuild them from what's out there. Otherwise, only rebuild if 
	  find new any new ones.)



          (* * fgh 22-Jul-85 Takes a list of bad file box cards and reconstructs the file boxes from the From pointer lists 
	  of all the cards in the NoteFile.)



          (* * fgh 30-Jul-85 Takes a list of cards with bad global links and reconstructs the global links list from the From
	  pointer lists of all the cards in the NoteFile.)



          (* * rht 11/23/85: Updated to handle new notefile and card object formats.)



          (* * rht 12/1/85: Now calls NC.GetMainCardData and NC.GetLinks instead of NC.GetNoteCard.)



          (* * rht 12/19/85: Massive overhaul for sake of speed. Should be wizzier now.)



          (* * fgh 2/4/86 Now works on open NFs. No need to error check since this function should always be called from 
	  earlier phases of the inspect & repaier.)



          (* * fgh 5/21/86 Fixed bug in handling of global links.)



          (* * rht 7/16/86: Added InterestedWindow arg.)



          (* * rht 7/16/86: Now calls NC.PutLinks passing UseOldDatesFlg.)


    (PROG (NoteFile FileName CardTotal NoteCardNumber OldLinkLabels DiscoveredLinkLabels 
		      ReconstructLinks ReconstructGlobalLinks ToBeFiledCards)

          (* * First, take care of checking stream's validity, etc.)


	    (SETQ FileName (if (type? NoteFile NoteFileOrFileName)
				 then (SETQ NoteFile NoteFileOrFileName)
					(fetch (NoteFile FullFileName) of NoteFileOrFileName)
			       else NoteFileOrFileName))   (* Try to open notefile.)
	    (if (NULL (OPENP FileName))
		then (if (NULL (SETQ NoteFile
				       (NC.OpenDatabaseFile FileName NIL T NIL NIL NIL NIL T T NIL 
							      InterestedWindow)))
			   then (NC.PrintMsg InterestedWindow NIL "Couldn't open " FileName "."
						 (CHARACTER 13)
						 "Repair aborted."
						 (CHARACTER 13))
				  (RETURN NIL)))

          (* * If link labels aren't screwed up, then read them in.)


	    (OR BadLinkLabelsFlg (SETQ OldLinkLabels (NC.RetrieveLinkLabels NoteFile T)))

          (* * Mark every card that needs its global links or substance reconstructed so we don't have to search the lists so
	  much.)


	    (for Card in ListOfCardsNeedingGlobalLinksReconstructed do (NC.SetUserDataProp
									       Card
									       (QUOTE 
								 NeedsGlobalLinksReconstructedFlg)
									       T))
	    (for Box in ListOfBoxesToReconstruct do (NC.SetUserDataProp Box (QUOTE 
									   NeedsReconstructingFlg)
										T))

          (* Read through all NoteCard substances to find actual pointers. Use this to create the To Links list.
	  The list collection function checks to make sure each link is valid.)


	    (SETQ CardTotal (SUB1 (fetch (NoteFile NextIndexNum)
					       NoteFile)))
	    (NC.PrintMsg InterestedWindow T "Rebuilding notefile links." (CHARACTER 13)
			   "Collecting Links for item " 1 " out of " CardTotal "." (CHARACTER
			     13))
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards
	      NoteFile
	      (FUNCTION (LAMBDA (Card)
		  (SETQ NoteCardNumber (ADD1 NoteCardNumber))
		  (AND (ZEROP (REMAINDER NoteCardNumber 10))
			 (NC.PrintMsg InterestedWindow T "Rebuilding notefile links." (CHARACTER
					  13)
					"Collecting Links for item " NoteCardNumber " out of " 
					CardTotal "." (CHARACTER 13)))
		  (if (NC.FetchUserDataProp Card (QUOTE NeedsReconstructingFlg))
		      then                                 (* Card substance and links will be reconstructed so 
							     no need to try to read substance.)
			     (NC.GetLinks Card)
			     (if (NOT (NC.FetchUserDataProp Card (QUOTE 
								 NeedsGlobalLinksReconstructedFlg)))
				 then (NC.SetUserDataProp Card (QUOTE ScavengerToLinks)
							      (NC.FetchGlobalLinks Card))
					(NC.SetUserDataProp Card (QUOTE ScavengerGlobalLinks)
							      (NC.FetchGlobalLinks Card)))
			     (NC.DeactivateCard Card T)
		    else (NC.GetMainCardData Card)
			   (NC.GetLinks Card)
			   (NC.ActivateCard Card)
			   (if (EQ (NC.FetchStatus Card)
				       (QUOTE ACTIVE))
			       then                        (* Collect links having active destinations.
							     Delete the others.)
				      (NC.SetUserDataProp
					Card
					(QUOTE ScavengerToLinks)
					(NCONC (for Link in (CAR (NC.CollectReferences
									   Card))
						    eachtime (BLOCK)
						    when (if (EQ (NC.FetchStatus
									 (fetch (Link 
										  DestinationCard)
									    of Link))
								       (QUOTE ACTIVE))
							     else (NC.DelReferencesToCard Card 
											     Link)
								    NIL)
						    collect Link)
						 (if (NC.FetchUserDataProp Card (QUOTE 
								 NeedsGlobalLinksReconstructedFlg))
						   else (NC.SetUserDataProp Card (QUOTE 
									     ScavengerGlobalLinks)
										(NC.FetchGlobalLinks
										  Card))
							  (NC.FetchGlobalLinks Card))))
				      (if (NC.FetchUserDataProp Card (QUOTE 
								 NeedsGlobalLinksReconstructedFlg))
					else (NC.SetUserDataProp Card (QUOTE 
									     ScavengerGlobalLinks)
								     (NC.FetchGlobalLinks Card)))

          (* If there are file boxes to be reconstructed, then look thru the From links to see if this card was filed in one 
	  of the to-be-reconstructed boxes)


				      (AND ListOfBoxesToReconstruct
					     (for Link in (NC.FetchFromLinks Card)
						eachtime (BLOCK)
						when (AND (NC.ChildLinkP Link)
							      (NC.FetchUserDataProp
								(fetch (Link SourceCard)
								   of Link)
								(QUOTE NeedsReconstructingFlg)))
						do (push ReconstructLinks Link)))

          (* If there are global links to be reconstructed, then look thru the From links to see if this card had a global 
	  link from a card whose global links need reconstructing.)


				      (AND ListOfCardsNeedingGlobalLinksReconstructed
					     (for Link in (NC.FetchFromLinks Card)
						eachtime (BLOCK)
						when (AND (NC.GlobalLinkP Link)
							      (NC.FetchUserDataProp
								(fetch (Link SourceCard)
								   of Link)
								(QUOTE 
								 NeedsGlobalLinksReconstructedFlg)))
						do (push ReconstructGlobalLinks Link)))
				      (NC.DeactivateCard Card T))))))

          (* * Reconstruct any cards as requested)


	    (for BoxToReconstruct in ListOfBoxesToReconstruct eachtime (BLOCK)
	       do                                          (* Make a new file box using the given card.)
		    (NC.MakeNoteCard (QUOTE FileBox)
				       NoteFile "Untitled: Reconstructed during repair" T NIL 
				       BoxToReconstruct)

          (* File cards whose from links indicate that they used to be filed in this file box. Also add these new links to 
	  collected ToLinks.)


		    (NC.SetUserDataProp BoxToReconstruct (QUOTE ScavengerToLinks)
					  (APPEND (NC.FetchUserDataProp BoxToReconstruct
									    (QUOTE ScavengerToLinks)
									    )
						    (for Link in ReconstructLinks
						       eachtime (BLOCK)
						       when (NC.SameCardP BoxToReconstruct
									      (fetch (Link 
										       SourceCard)
										 of Link))
						       collect (NC.MakeChildLink
								   (fetch (Link DestinationCard)
								      of Link)
								   BoxToReconstruct NIL))))
                                                             (* Put the card away)
		    (NC.PutMainCardData BoxToReconstruct)
		    (NC.DeactivateCard BoxToReconstruct T))

          (* * Reconstruct any global link lists as required)


	    (for Link in ReconstructGlobalLinks bind ThisCardsToLinks ThisCardsGlobalLinks 
							   SourceCard
	       eachtime (BLOCK)
	       do (SETQ SourceCard (fetch (Link SourceCard) of Link)) 
                                                             (* Add it to the GlobalLinks list for its source card 
							     unless it's already there.)
		    (if (for GlobalLink in (SETQ ThisCardsGlobalLinks (NC.FetchUserDataProp
						     SourceCard
						     (QUOTE ScavengerGlobalLinks)))
			     eachtime (BLOCK) never (NC.SameLinkP Link GlobalLink))
			then (NC.SetUserDataProp SourceCard (QUOTE ScavengerGlobalLinks)
						     (CONS Link ThisCardsGlobalLinks)))
                                                             (* Add it to the source card's ToLinks list unless 
							     it's already there)
		    (if (for ToLink in (SETQ ThisCardsToLinks (NC.FetchUserDataProp
						 SourceCard
						 (QUOTE ScavengerToLinks)))
			     eachtime (BLOCK) never (NC.SameLinkP Link ToLink))
			then (NC.SetUserDataProp SourceCard (QUOTE ScavengerToLinks)
						     (CONS Link ThisCardsToLinks))))

          (* * Compute the From Links list by "inverting" the To Links list)


	    (NC.PrintMsg InterestedWindow T "Repairing NoteFile." (CHARACTER 13)
			   "Inverting links for item " 1 " out of " CardTotal "." (CHARACTER 13))
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
			       (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			       (AND (ZEROP (REMAINDER NoteCardNumber 100))
				      (NC.PrintMsg InterestedWindow T "Repairing NoteFile."
						     (CHARACTER 13)
						     "Inverting links for item " NoteCardNumber 
						     " out of "
						     CardTotal "." (CHARACTER 13)))
			       (if (EQ (NC.FetchStatus Card)
					   (QUOTE ACTIVE))
				   then (for Link in (NC.FetchUserDataProp Card (QUOTE
										     ScavengerToLinks)
										   )
					     bind DestinationCard LinkLabel eachtime (BLOCK)
					     do            (* Add this ToLink as a FromLink for the link's 
							     destination card.)
						  (NC.SetUserDataProp (SETQ DestinationCard
									  (fetch (Link 
										  DestinationCard)
									     of Link))
									(QUOTE ScavengerFromLinks)
									(CONS Link
										(
									     NC.FetchUserDataProp
										  DestinationCard
										  (QUOTE 
									       ScavengerFromLinks))))
                                                             (* Accumulate the link labels into a list.)
						  (if (NOT (FMEMB (SETQ LinkLabel
									  (fetch (Link Label)
									     of Link))
									DiscoveredLinkLabels))
						      then (push DiscoveredLinkLabels LinkLabel)))
				     ))))

          (* * Reset all of the To and From Links lists in the database)


	    (NC.PrintMsg InterestedWindow T "Repairing NoteFile." (CHARACTER 13)
			   "Rewriting links for item " 1 " out of " CardTotal "." (CHARACTER 13))
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
			       (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			       (AND (ZEROP (REMAINDER NoteCardNumber 10))
				      (NC.PrintMsg InterestedWindow T "Repairing NoteFile."
						     (CHARACTER 13)
						     "Rewriting links for item " NoteCardNumber 
						     " out of "
						     CardTotal "." (CHARACTER 13)))
			       (if (EQ (NC.FetchStatus Card)
					   (QUOTE ACTIVE))
				   then (NC.SetGlobalLinks Card (NC.FetchUserDataProp
								 Card
								 (QUOTE ScavengerGlobalLinks)))
					  (NC.SetToLinks Card (NC.FetchUserDataProp Card
											(QUOTE
											  
										 ScavengerToLinks)))
					  (NC.SetFromLinks Card (NC.FetchUserDataProp
							       Card
							       (QUOTE ScavengerFromLinks)))
                                                             (* Check whether this card isn't filed anywhere.)
					  (if (AND (NOT (NC.UndeletableCardP Card))
						       (for Link in (NC.FetchFromLinks Card)
							  eachtime (BLOCK) never (
										    NC.ChildLinkP
											 Link)))
					      then (push ToBeFiledCards Card))
					  (NC.PutLinks Card T))
                                                             (* Clean any junk off the card.)
			       (NC.DeactivateCard Card T)
			       (NC.SetUserDataPropList Card NIL))))

          (* * File any unfiled cards in the ToBeFiled box.)


	    (if ToBeFiledCards
		then (NC.PrintMsg InterestedWindow T "Filing " (LENGTH ToBeFiledCards)
				      " cards in ToBeFiled box ..."
				      (CHARACTER 13))
		       (NCP.FileCards ToBeFiledCards (fetch (NoteFile ToBeFiledCard)
							  of NoteFile)))
                                                             (* Rewrite link labels if we've found any new ones.)
	    (if (LDIFFERENCE DiscoveredLinkLabels OldLinkLabels)
		then (NC.StoreLinkLabels NoteFile (UNION DiscoveredLinkLabels OldLinkLabels)))
                                                             (* Clean up and get out.)
	    (NC.CheckpointDatabase NoteFile T)
	    (NC.ForceDatabaseClose NoteFile)
	    (NC.PrintMsg InterestedWindow T "Repair Completed for " (FULLNAME FileName)
			   "."
			   (CHARACTER 13))
	    (if ToBeFiledCards
		then (NC.PrintMsg InterestedWindow NIL "Filed " (LENGTH ToBeFiledCards)
				      " cards in ToBeFiled box.")))))
)
(PUTPROPS RHTPATCH077 COPYRIGHT ("Xerox Corporation" 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1032 55080 (NC.CardInspectorAttachedMenuWhenSelectedFn 1042 . 7645) (
NC.CardInspectorCloseFn 7647 . 9119) (NC.MessageWinAttachedMenuWhenSelectedFn 9121 . 13901) (
NC.GetScavengerInfo 13903 . 16712) (NC.BuildBadCardsList 16714 . 19340) (NC.ScavengerPhase1 19342 . 
33862) (NC.BuildCardPartsInspector 33864 . 37960) (NC.BuildTitlesInspectorMenu 37962 . 40160) (
NC.ScavengeDatabaseFile 40162 . 55078)))))
STOP