static void Integrate(Goal obstructedGoal, Obstacle obstacle, Resolution resolution)
        {
            var anchor = obstructedGoal;
            if (resolution.Parameters.Count > 0) {
                anchor = resolution.Parameters[0];
            }
            anchor = FinalAnchor (anchor);

            if (resolution.ResolutionPattern == ResolutionPattern.GoalSubstitution
                | resolution.ResolutionPattern == ResolutionPattern.GoalWeakening) {

                var goalReplacement = new GoalReplacement (obstructedGoal.model) {
                    Implicit = true
                };
                goalReplacement.SetObstacle (obstacle);
                goalReplacement.SetResolvingGoal (resolution.ResolvingGoal ());
                goalReplacement.SetAnchorGoal (anchor);

                obstructedGoal.model.Add (goalReplacement);

                // Replace in refinements
                var resolving_goal = resolution.ResolvingGoal ();
                foreach (var r in anchor.ParentRefinements ().ToArray ()) {
                    r.Remove (anchor);
                    r.Add (resolving_goal);
                }

                // Replace children refinements
                foreach (var r in anchor.Refinements ().ToArray ()) {
                    anchor.model.Remove (r);
                    var r2 = (GoalRefinement) r.Copy ();
                    r2.Identifier = Guid.NewGuid ().ToString ();
                    r2.SetParentGoal (resolving_goal);
                    resolution.model.Add (r2);
                }

                // Replace in exceptions
                foreach (var r in anchor.Exceptions ().ToArray ()) {
                    r.SetAnchorGoal (resolving_goal);
                }

                // Replace in provided
                foreach (var r in anchor.Provided ().ToArray ()) {
                    r.SetAnchorGoal (resolving_goal);
                }

                // Replace in agent assignements
                foreach (var r in anchor.AgentAssignments ().ToArray ()) {
                    r.GoalIdentifier = resolving_goal.Identifier;
                }

            } else {

                var goalException = new GoalException (obstructedGoal.model) {
                    Implicit = true
                };
                goalException.SetObstacle (obstacle);
                goalException.SetResolvingGoal (resolution.ResolvingGoal ());
                goalException.SetAnchorGoal (anchor);

                obstructedGoal.model.Add (goalException);

                /*
                var obstacleAssumption = new ObstacleAssumption (resolution.model);
                obstacleAssumption.SetAnchorGoal (anchor);
                obstacleAssumption.SetObstacle (obstacle);

                if (anchor.Identifier != obstructedGoal.Identifier) {
                Console.WriteLine ("DownPropagate " + obstacle.FriendlyName + " ("+obstructedGoal.FriendlyName +") on " + anchor.FriendlyName );
                }
                */

                // DownPropagate (obstacleAssumption, anchor);
            }
        }
        protected void Render(GoalReplacement exception)
        {
            if (!shapes.ContainsKey (exception.ResolvingGoalIdentifier)) {
                return;
            }

            if (!shapes.ContainsKey (exception.AnchorGoalIdentifier)) {
                return;
            }

            var anchorGoalGraphic = shapes [exception.AnchorGoalIdentifier].First ();
            var resolvingGoalGraphic = shapes [exception.ResolvingGoalIdentifier].First ();

            var topArrow = GetArrow (resolvingGoalGraphic, anchorGoalGraphic);
            topArrow.Style.Stroke.Pattern = StrokePattern.Dashed;
            AddText (topArrow, @"\b Replace \b0" + exception.Obstacle().FriendlyName);
            Add (exception.Identifier, topArrow);
        }