anchor.diff:      solutionUniqueName = diffSolutionUniqueName
     }
   
  -  elim diffSolutionInfo devDocument prodDocument output |> ignore;
  +  diffSolution diffSolutionInfo devDocument prodDocument output |> ignore;
     // log.Verbose "Saving";
     // File.WriteAllText (__SOURCE_DIRECTORY__ + @"\diff.xml", to_string dev_doc);
   
  
positive.code:   solutionUniqueName: string
  }
  
  let elim_elem (diffSolutionInfo: DiffSolutionInfo) output (devNode: XmlNode) (prodNode: XmlNode) (resp: RetrieveEntityResponse option)
                type_ devNodePath devId (devReadable: ReadableName) (extraCheck: ExtraChecks) (callbackKind: CallbackKind) =
    let { proxy = proxy; solutionUniqueName = diffSolutionUniqueName; } = diffSolutionInfo
    let devElements = selectNodes devNode devNodePath
  
negative.code:    else
       UnhandledEntity
  
  let diffEntity (diffSolutionInfo: DiffSolutionInfo) genericAddToSolution (dev_ent: XmlNode) (prod_ent: XmlNode) (resp: RetrieveEntityResponse) =
    let { proxy = proxy; solutionUniqueName = diffSolutionUniqueName; } = diffSolutionInfo
    let AddEntityDataToSolution = genericAddToSolution dev_ent prod_ent (Some resp)  
    AddEntityDataToSolution "entity info" "EntityInfo/entity/*[not(self::attributes)]" 
      (Custom (fun id -> "EntityInfo/entity/"+id))
      ElementName
      NoExtra
      EntityMetadataCallback
    
    AddEntityDataToSolution "ribbon" "RibbonDiffXml"
      (Custom (fun id -> "RibbonDiffXml"))
      (Static "Ribbon")
      NoExtra
      RibbonCallback
    
    AddEntityDataToSolution "attribute" "EntityInfo/entity/attributes/attribute"
      (Attribute "PhysicalName")
      (AttributeNamedItem "PhysicalName")
      NoExtra
      (CustomCallback (fun id -> 
          resp.EntityMetadata.Attributes
          |> Array.find (fun a -> a.SchemaName = id)
          |> fun a -> createEntityComponent proxy diffSolutionUniqueName a.MetadataId.Value EntityComponent.Attribute)
      )
  
    AddEntityDataToSolution "form" "FormXml/forms/systemform"
      (Node "formid")
      LocalizedNameDescription
      NoExtra
      (EntityComponentCallback EntityComponent.Form)
    
    AddEntityDataToSolution "view" "SavedQueries/savedqueries/savedquery"
      (Node "savedqueryid")
      LocalizedNameDescription
      NoExtra
      (EntityComponentCallback EntityComponent.View)
    
    AddEntityDataToSolution "chart" "Visualizations/visualization"
      (Node "savedqueryvisualizationid")
      LocalizedNameDescription
      NoExtra
      (EntityComponentCallback EntityComponent.Chart)
  
  
  // Help: https://bettercrm.blog/2017/04/26/solution-component-types-in-dynamics-365/
  let rec diffSolution (diffSolutionInfo: DiffSolutionInfo) (devNode: XmlNode) (prodNode: XmlNode) output =
    log.Verbose "Preprocessing";
    let expr = "//IntroducedVersion|//IsDataSourceSecret|//Format|//CanChangeDateTimeBehavior|//LookupStyle|//CascadeRollupView|//Length|//TriggerOnUpdateAttributeList[not(text())]"
    selectNodes devNode expr |> Seq.iter removeNode;
    selectNodes prodNode expr |> Seq.iter removeNode;
    
    let genericAddToSolution = diffElement diffSolutionInfo output
    let entities = selectNodes devNode "/ImportExportXml/Entities/Entity"
    
    let { proxy = proxy; solutionUniqueName = diffSolutionUniqueName; } = diffSolutionInfo
    
    entities
    |> Seq.iter (fun dev_ent -> 
      let xmlEntityDifference = decideEntityXmlDifference diffSolutionInfo output dev_ent prodNode
      match xmlEntityDifference with 
        | NotEntity (dev_ent, prod_ent, resp) -> 
            diffEntity diffSolutionInfo genericAddToSolution dev_ent prod_ent resp
        | _ -> ()
      )
  
    let AddSolutionDataToSolution = genericAddToSolution devNode prodNode None
  
    AddSolutionDataToSolution "role" "/ImportExportXml/Roles/Role"
      (Attribute "id")
  