bdi-network-resilience

Code for AAMAS 2017 simulation.

8/22/2017 6:15:55 PM

Changes

network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/BinaryPredicate.java 93(+0 -93)

network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/UnaryPredicate.java 82(+0 -82)

Details

diff --git a/network-resilience/.classpath b/network-resilience/.classpath
index 0f45fde..0d9993f 100644
--- a/network-resilience/.classpath
+++ b/network-resilience/.classpath
@@ -11,5 +11,6 @@
 	<classpathentry kind="lib" path="lib/xmlrpc-client-3.1.3.jar"/>
 	<classpathentry kind="lib" path="lib/xmlrpc-common-3.1.3.jar"/>
 	<classpathentry kind="lib" path="lib/xmlrpc-server-3.1.3.jar"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/bdi-jade-extensions"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/AnomalyDetectionCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/AnomalyDetectionCapability.java
index b5bc5ef..a894596 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/AnomalyDetectionCapability.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/AnomalyDetectionCapability.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.agent;
 
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 
@@ -28,7 +29,7 @@ import bdi4jade.annotation.Parameter;
 import bdi4jade.annotation.Parameter.Direction;
 import bdi4jade.belief.Belief;
 import bdi4jade.belief.BeliefSet;
-import bdi4jade.belief.Predicate;
+import bdi4jade.belief.PredicateBelief;
 import bdi4jade.belief.TransientBeliefSet;
 import bdi4jade.core.GoalUpdateSet;
 import bdi4jade.event.GoalEvent;
@@ -86,7 +87,7 @@ public class AnomalyDetectionCapability extends RouterAgentCapability implements
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(AnomalousUsage anomalousUsage) {
-			this.link = anomalousUsage.getConcept();
+			this.link = anomalousUsage.getVariable();
 		}
 	}
 
@@ -136,7 +137,7 @@ public class AnomalyDetectionCapability extends RouterAgentCapability implements
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(Restricted restricted) {
-			this.ip = restricted.getConcept();
+			this.ip = restricted.getVariable();
 		}
 	}
 
@@ -174,7 +175,7 @@ public class AnomalyDetectionCapability extends RouterAgentCapability implements
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(Restricted restricted) {
-			this.ip = restricted.getConcept();
+			this.ip = restricted.getVariable();
 		}
 	}
 
@@ -218,10 +219,10 @@ public class AnomalyDetectionCapability extends RouterAgentCapability implements
 			@Override
 			public boolean isContextApplicable(Goal goal) {
 				BeliefGoal<Restricted> bg = (BeliefGoal<Restricted>) goal;
-				Predicate<IpRateLimited> ipRateLimited = (Predicate<IpRateLimited>) getBeliefBase()
+				PredicateBelief<IpRateLimited> ipRateLimited = (PredicateBelief<IpRateLimited>) getBeliefBase()
 						.getBelief(
 								new IpRateLimited(bg.getBeliefName()
-										.getConcept()));
+										.getVariable()));
 				return (ipRateLimited != null && ipRateLimited.getValue());
 			}
 		};
@@ -230,14 +231,14 @@ public class AnomalyDetectionCapability extends RouterAgentCapability implements
 	@Override
 	public void generateGoals(GoalUpdateSet goalUpdateSet) {
 		// Anomalous(ip) AND not Restricted(ip) --> goal(Restricted(ip)) AND
-		// goal(?belief(Anomalous(ip))
+		// goal(?Benign(ip)
 		Set<Belief<?, ?>> anomalousIpBeliefs = getBeliefBase()
 				.getBeliefsByType(Anomalous.class);
 		for (Belief<?, ?> belief : anomalousIpBeliefs) {
-			Predicate<Anomalous> anomalous = (Predicate<Anomalous>) belief;
-			Ip ip = anomalous.getName().getConcept();
+			PredicateBelief<Anomalous> anomalous = (PredicateBelief<Anomalous>) belief;
+			Ip ip = anomalous.getName().getVariable();
 			if (anomalous.getValue()) {
-				Predicate<Benign> benign = (Predicate<Benign>) getBeliefBase()
+				PredicateBelief<Benign> benign = (PredicateBelief<Benign>) getBeliefBase()
 						.getBelief(new Benign(ip));
 				if (benign == null) {
 					// Anomalous(ip) AND ~Benign(ip) -->
@@ -245,12 +246,12 @@ public class AnomalyDetectionCapability extends RouterAgentCapability implements
 					goal(goalUpdateSet, new Benign(ip), this);
 				}
 
-				Predicate<Restricted> restricted = (Predicate<Restricted>) getBeliefBase()
+				PredicateBelief<Restricted> restricted = (PredicateBelief<Restricted>) getBeliefBase()
 						.getBelief(new Restricted(ip));
 				if ((benign == null || !benign.getValue())
 						&& (restricted == null || !restricted.getValue())) {
-					// Anomalous(l) AND !(not Benign(l)) AND
-					// !(Restricted(l)) --> AttackPrevented(l)
+					// Anomalous(ip) AND !(not Benign(l)) AND
+					// !(Restricted(l)) --> Restricted(ip)
 					goal(goalUpdateSet, new Restricted(ip), true);
 				}
 			}
@@ -259,11 +260,11 @@ public class AnomalyDetectionCapability extends RouterAgentCapability implements
 		Set<Belief<?, ?>> restrictedBeliefs = getBeliefBase().getBeliefsByType(
 				Restricted.class);
 		for (Belief<?, ?> belief : restrictedBeliefs) {
-			Predicate<Restricted> restricted = (Predicate<Restricted>) belief;
+			PredicateBelief<Restricted> restricted = (PredicateBelief<Restricted>) belief;
 			if (restricted.getValue()) {
-				Predicate<Benign> benign = (Predicate<Benign>) getBeliefBase()
+				PredicateBelief<Benign> benign = (PredicateBelief<Benign>) getBeliefBase()
 						.getBelief(
-								new Benign(restricted.getName().getConcept()));
+								new Benign(restricted.getName().getVariable()));
 				if (benign != null && benign.getValue()) {
 					// Restricted(l) AND Benign(l) --> not
 					// Restricted(l)
@@ -274,8 +275,10 @@ public class AnomalyDetectionCapability extends RouterAgentCapability implements
 	}
 
 	@Override
-	protected Class<?> getLowPriorityGoal() {
-		return Benign.class;
+	protected Set<Class<?>> getLowPriorityGoal() {
+		Set<Class<?>> lowPriorityGoals = new HashSet<>();
+		lowPriorityGoals.add(Benign.class);
+		return lowPriorityGoals;
 	}
 
 	@Override
@@ -301,10 +304,10 @@ public class AnomalyDetectionCapability extends RouterAgentCapability implements
 			if (overUsageCause.getValue().isEmpty()) {
 				removeBelief(overUsageCause);
 			}
-			Predicate<AnomalousUsage> anomalousUsage = (Predicate<AnomalousUsage>) getBeliefBase()
+			PredicateBelief<AnomalousUsage> anomalousUsage = (PredicateBelief<AnomalousUsage>) getBeliefBase()
 					.getBelief(
 							new AnomalousUsage(overUsageCause.getName()
-									.getConcept()));
+									.getVariable()));
 			if (anomalousUsage != null
 					&& (anomalousUsage.getValue() == null || !anomalousUsage
 							.getValue())) {
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/belief/AnomalousUsageBelief.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/belief/AnomalousUsageBelief.java
index 7296744..89511be 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/belief/AnomalousUsageBelief.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/belief/AnomalousUsageBelief.java
@@ -38,7 +38,7 @@ public class AnomalousUsageBelief extends DerivedPredicate<AnomalousUsage> {
 	@Override
 	protected Boolean evaluate() {
 		BeliefSet<OverUsageCause, Ip> overUsageCauseBeliefs = (BeliefSet<OverUsageCause, Ip>) getMainBeliefBase()
-				.getBelief(new OverUsageCause(getName().getConcept()));
+				.getBelief(new OverUsageCause(getName().getVariable()));
 		return overUsageCauseBeliefs == null ? false : !overUsageCauseBeliefs
 				.getValue().isEmpty();
 	}
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/belief/BenignBelief.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/belief/BenignBelief.java
index 9bce2e6..4612425 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/belief/BenignBelief.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/belief/BenignBelief.java
@@ -25,7 +25,7 @@ import java.util.Set;
 
 import bdi4jade.belief.Belief;
 import bdi4jade.belief.DerivedPredicate;
-import bdi4jade.belief.Predicate;
+import bdi4jade.belief.PredicateBelief;
 import br.ufrgs.inf.bdinetr.domain.predicate.Benign;
 import br.ufrgs.inf.bdinetr.domain.predicate.Threat;
 
@@ -43,10 +43,10 @@ public class BenignBelief extends DerivedPredicate<Benign> {
 		Set<Belief<?, ?>> threatBeliefs = getMainBeliefBase().getBeliefsByType(
 				Threat.class);
 		for (Belief<?, ?> belief : threatBeliefs) {
-			Predicate<Threat> threat = (Predicate<Threat>) belief;
+			PredicateBelief<Threat> threat = (PredicateBelief<Threat>) belief;
 			assert threat.getValue();
-			if (getName().getConcept().equals(
-					threat.getName().getConcept().getDstIp())) {
+			if (getName().getVariable().equals(
+					threat.getName().getVariable().getDstIp())) {
 				exists = true;
 				break;
 			}
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/ClassifierCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/ClassifierCapability.java
index 955fd13..f694ff6 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/ClassifierCapability.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/ClassifierCapability.java
@@ -27,7 +27,7 @@ import java.util.Set;
 import bdi4jade.annotation.Parameter;
 import bdi4jade.annotation.Parameter.Direction;
 import bdi4jade.belief.Belief;
-import bdi4jade.belief.Predicate;
+import bdi4jade.belief.PredicateBelief;
 import bdi4jade.core.GoalUpdateSet;
 import bdi4jade.event.GoalEvent;
 import bdi4jade.goal.BeliefGoal;
@@ -94,7 +94,7 @@ public class ClassifierCapability extends RouterAgentCapability implements
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(Benign benign) {
-			this.ip = benign.getConcept();
+			this.ip = benign.getVariable();
 		}
 	}
 
@@ -131,7 +131,7 @@ public class ClassifierCapability extends RouterAgentCapability implements
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(Threat threat) {
-			this.flow = threat.getConcept();
+			this.flow = threat.getVariable();
 		}
 	}
 
@@ -158,15 +158,15 @@ public class ClassifierCapability extends RouterAgentCapability implements
 				GoalTemplateFactory.goalOfType(FlowExport.class), this,
 				Role.FLOW_EXPORTER, false);
 
-		analyseIpFlows = new DefaultPlan(
+		this.analyseIpFlows = new DefaultPlan(
 				GoalTemplateFactory.hasBeliefOfType(Benign.class),
 				AnalyseIPFlows.class);
-		limitFlowRate = new DefaultPlan(
+		this.limitFlowRate = new DefaultPlan(
 				GoalTemplateFactory.hasNoBeliefOfType(Threat.class),
 				LimitFlowRatePlan.class) {
 			public boolean isContextApplicable(Goal goal) {
 				BeliefNotPresentGoal<Threat> bg = (BeliefNotPresentGoal<Threat>) goal;
-				Predicate<Threat> threat = (Predicate<Threat>) getBeliefBase()
+				PredicateBelief<Threat> threat = (PredicateBelief<Threat>) getBeliefBase()
 						.getBelief(bg.getBeliefName());
 				return (threat != null && threat.getValue());
 			};
@@ -179,7 +179,7 @@ public class ClassifierCapability extends RouterAgentCapability implements
 		Set<Belief<?, ?>> threatBeliefs = getBeliefBase().getBeliefsByType(
 				Threat.class);
 		for (Belief<?, ?> belief : threatBeliefs) {
-			Predicate<Threat> threat = (Predicate<Threat>) belief;
+			PredicateBelief<Threat> threat = (PredicateBelief<Threat>) belief;
 			if (threat.getValue()) {
 				goal(goalUpdateSet, threat.getName(), (Boolean) null);
 			}
@@ -197,7 +197,7 @@ public class ClassifierCapability extends RouterAgentCapability implements
 				Benign.class);
 		Iterator<Belief<?, ?>> it = benignBeliefs.iterator();
 		while (it.hasNext()) {
-			Predicate<Benign> benignBelief = (Predicate<Benign>) it.next();
+			PredicateBelief<Benign> benignBelief = (PredicateBelief<Benign>) it.next();
 			if (benignBelief.getValue() == null || benignBelief.getValue()) {
 				removeBelief(benignBelief);
 			}
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/GoalRequestPlan.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/GoalRequestPlan.java
index 7d37d87..db4a69e 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/GoalRequestPlan.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/GoalRequestPlan.java
@@ -41,7 +41,7 @@ import java.util.Set;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import bdi4jade.belief.Predicate;
+import bdi4jade.belief.PredicateBelief;
 import bdi4jade.belief.TransientPredicate;
 import bdi4jade.core.BDIAgent;
 import bdi4jade.core.Capability;
@@ -83,7 +83,7 @@ public class GoalRequestPlan extends DefaultPlan {
 						GoalResponse<?> response = (GoalResponse<?>) myAgent
 								.getContentManager().extractContent(reply);
 
-						Predicate<?> predicate = new TransientPredicate(
+						PredicateBelief<?> predicate = new TransientPredicate(
 								response.getPredicate(), response.getValue());
 						((BeliefGoal) getGoal()).setOutputBelief(predicate);
 
@@ -273,11 +273,11 @@ public class GoalRequestPlan extends DefaultPlan {
 		private static final long serialVersionUID = 1328980796345824527L;
 
 		private Capability capability;
-		private Predicate<?> predicate;
+		private PredicateBelief<?> predicate;
 		private boolean done;
 
 		public ReceiveUpdatesBehavior(Agent agent, MessageTemplate mt,
-				Capability capability, Predicate<?> predicate) {
+				Capability capability, PredicateBelief<?> predicate) {
 			super(agent, mt, INFINITE, new DataStore(),
 					ReceiveUpdatesBehavior.class.getSimpleName());
 			this.capability = capability;
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/GoalResponsePlan.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/GoalResponsePlan.java
index 66bfc81..aee3a0c 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/GoalResponsePlan.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/GoalResponsePlan.java
@@ -33,7 +33,7 @@ import org.apache.commons.logging.LogFactory;
 
 import bdi4jade.annotation.Parameter;
 import bdi4jade.annotation.Parameter.Direction;
-import bdi4jade.belief.Predicate;
+import bdi4jade.belief.PredicateBelief;
 import bdi4jade.core.Capability;
 import bdi4jade.event.BeliefEvent;
 import bdi4jade.event.BeliefEvent.Action;
@@ -66,7 +66,7 @@ public class GoalResponsePlan extends DefaultPlan {
 		private Boolean lastValue;
 		private MessageTemplate mt;
 		private Capability partCapability;
-		private Predicate<?> predicate;
+		private PredicateBelief<?> predicate;
 		private GoalRequest<?> request;
 		private long responseTime;
 		private State state;
@@ -81,7 +81,7 @@ public class GoalResponsePlan extends DefaultPlan {
 			if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
 				reply.setPerformative(ACLMessage.INFORM);
 				if (goal instanceof BeliefGoal) {
-					predicate = (Predicate<?>) partCapability.getBeliefBase()
+					predicate = (PredicateBelief<?>) partCapability.getBeliefBase()
 							.getBelief(((BeliefGoal<?>) goal).getBeliefName());
 					GoalResponse response = new GoalResponse();
 					response.setPredicate(predicate.getName());
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/LinkMonitorCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/LinkMonitorCapability.java
index 153d6ca..2f343c4 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/LinkMonitorCapability.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/LinkMonitorCapability.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.agent;
 
+import java.util.HashSet;
 import java.util.Observable;
 import java.util.Observer;
 import java.util.Set;
@@ -28,7 +29,7 @@ import java.util.Set;
 import bdi4jade.annotation.Parameter;
 import bdi4jade.annotation.Parameter.Direction;
 import bdi4jade.belief.Belief;
-import bdi4jade.belief.Predicate;
+import bdi4jade.belief.PredicateBelief;
 import bdi4jade.core.GoalUpdateSet;
 import bdi4jade.event.GoalEvent;
 import bdi4jade.event.GoalListener;
@@ -54,9 +55,8 @@ import br.ufrgs.inf.bdinetr.domain.predicate.OverUsage;
 /**
  * @author Ingrid Nunes
  */
-public class LinkMonitorCapability extends RouterAgentCapability implements
-		BeliefRevisionStrategy, OptionGenerationFunction, GoalListener,
-		Observer {
+public class LinkMonitorCapability extends RouterAgentCapability
+		implements BeliefRevisionStrategy, OptionGenerationFunction, GoalListener, Observer {
 
 	public class LimitLinkRate extends BeliefGoalPlanBody {
 		private static final long serialVersionUID = -3493377510830902961L;
@@ -67,15 +67,13 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 		@Override
 		public void execute() {
 			if (!subgoalDispatched) {
-				dispatchSubgoalAndListen(new BeliefValueGoal<>(
-						new LinkRateLimited(link), true));
+				dispatchSubgoalAndListen(new BeliefValueGoal<>(new LinkRateLimited(link), true));
 				this.subgoalDispatched = true;
 			} else {
 				GoalEvent event = getGoalEvent();
 				if (event != null) {
 					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
-						addBelief(((BeliefGoal<?>) event.getGoal())
-								.getOutputBelief());
+						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
 						belief(new AttackPrevented(link), true);
 					} else {
 						setEndState(EndState.FAILED);
@@ -91,7 +89,7 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(AttackPrevented attackPrevented) {
-			this.link = attackPrevented.getConcept();
+			this.link = attackPrevented.getVariable();
 		}
 	}
 
@@ -104,15 +102,13 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 		@Override
 		public void execute() {
 			if (!subgoalDispatched) {
-				dispatchSubgoalAndListen(new BeliefValueGoal<>(
-						new LinkRateLimited(link), false));
+				dispatchSubgoalAndListen(new BeliefValueGoal<>(new LinkRateLimited(link), false));
 				this.subgoalDispatched = true;
 			} else {
 				GoalEvent event = getGoalEvent();
 				if (event != null) {
 					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
-						addBelief(((BeliefGoal<?>) event.getGoal())
-								.getOutputBelief());
+						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
 						belief(new AttackPrevented(link), false);
 						belief(new AnomalousUsage(link), null);
 					} else {
@@ -129,7 +125,7 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(AttackPrevented attackPrevented) {
-			this.link = attackPrevented.getConcept();
+			this.link = attackPrevented.getVariable();
 		}
 	}
 
@@ -142,39 +138,31 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 	@bdi4jade.annotation.TransientBelief
 	private LinkMonitor role;
 
-	public LinkMonitorCapability(LinkMonitor linkMonitor,
-			GoalRequestPlan beliefGoalRequestPlan) {
+	public LinkMonitorCapability(LinkMonitor linkMonitor, GoalRequestPlan beliefGoalRequestPlan) {
 		this.role = linkMonitor;
 		role.addObserver(this);
 
 		setBeliefRevisionStrategy(this);
 		setOptionGenerationFunction(this);
 
-		beliefGoalRequestPlan.addGoalTemplate(GoalTemplateFactory
-				.hasBeliefOfTypeWithValue(LinkRateLimited.class, true), this,
-				Role.RATE_LIMITER, false);
-		beliefGoalRequestPlan.addGoalTemplate(GoalTemplateFactory
-				.hasBeliefOfTypeWithValue(LinkRateLimited.class, false), this,
-				Role.RATE_LIMITER, false);
+		beliefGoalRequestPlan.addGoalTemplate(GoalTemplateFactory.hasBeliefOfTypeWithValue(LinkRateLimited.class, true),
+				this, Role.RATE_LIMITER, false);
 		beliefGoalRequestPlan.addGoalTemplate(
-				GoalTemplateFactory.hasBeliefOfType(AnomalousUsage.class),
-				this, Role.ANOMALY_DETECTION, true);
+				GoalTemplateFactory.hasBeliefOfTypeWithValue(LinkRateLimited.class, false), this, Role.RATE_LIMITER,
+				false);
+		beliefGoalRequestPlan.addGoalTemplate(GoalTemplateFactory.hasBeliefOfType(AnomalousUsage.class), this,
+				Role.ANOMALY_DETECTION, true);
 
 		this.limitLinkRate = new DefaultPlan(
-				GoalTemplateFactory.hasBeliefOfTypeWithValue(
-						AttackPrevented.class, Boolean.TRUE),
-				LimitLinkRate.class);
+				GoalTemplateFactory.hasBeliefOfTypeWithValue(AttackPrevented.class, Boolean.TRUE), LimitLinkRate.class);
 		this.restoreLinkRate = new DefaultPlan(
-				GoalTemplateFactory.hasBeliefOfTypeWithValue(
-						AttackPrevented.class, Boolean.FALSE),
+				GoalTemplateFactory.hasBeliefOfTypeWithValue(AttackPrevented.class, Boolean.FALSE),
 				RestoreLinkRate.class) {
 			@Override
 			public boolean isContextApplicable(Goal goal) {
 				BeliefGoal<AttackPrevented> bg = (BeliefGoal<AttackPrevented>) goal;
-				Predicate<LinkRateLimited> linkRateLimited = (Predicate<LinkRateLimited>) getBeliefBase()
-						.getBelief(
-								new LinkRateLimited(bg.getBeliefName()
-										.getConcept()));
+				PredicateBelief<LinkRateLimited> linkRateLimited = (PredicateBelief<LinkRateLimited>) getBeliefBase()
+						.getBelief(new LinkRateLimited(bg.getBeliefName().getVariable()));
 				return (linkRateLimited != null && linkRateLimited.getValue());
 			}
 		};
@@ -182,13 +170,12 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 
 	@Override
 	public void generateGoals(GoalUpdateSet goalUpdateSet) {
-		Set<Belief<?, ?>> overUsageBeliefs = getBeliefBase().getBeliefsByType(
-				OverUsage.class);
+		Set<Belief<?, ?>> overUsageBeliefs = getBeliefBase().getBeliefsByType(OverUsage.class);
 		for (Belief<?, ?> belief : overUsageBeliefs) {
-			Predicate<OverUsage> overUsage = (Predicate<OverUsage>) belief;
-			Link link = overUsage.getName().getConcept();
+			PredicateBelief<OverUsage> overUsage = (PredicateBelief<OverUsage>) belief;
+			Link link = overUsage.getName().getVariable();
 			if (overUsage.getValue()) {
-				Predicate<AnomalousUsage> anomalousUsage = (Predicate<AnomalousUsage>) getBeliefBase()
+				PredicateBelief<AnomalousUsage> anomalousUsage = (PredicateBelief<AnomalousUsage>) getBeliefBase()
 						.getBelief(new AnomalousUsage(link));
 				if (anomalousUsage == null) {
 					// OverUsage(l) AND ~AnomalousUsage(l) -->
@@ -196,11 +183,10 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 					goal(goalUpdateSet, new AnomalousUsage(link), this);
 				}
 
-				Predicate<AttackPrevented> attackPrevented = (Predicate<AttackPrevented>) getBeliefBase()
+				PredicateBelief<AttackPrevented> attackPrevented = (PredicateBelief<AttackPrevented>) getBeliefBase()
 						.getBelief(new AttackPrevented(link));
 				if ((anomalousUsage == null || anomalousUsage.getValue())
-						&& (attackPrevented == null || !attackPrevented
-								.getValue())) {
+						&& (attackPrevented == null || !attackPrevented.getValue())) {
 					// OverUsage(l) AND !(not AnomalousUsage(l)) AND
 					// !(AttackPrevented(l)) --> AttackPrevented(l)
 					goal(goalUpdateSet, new AttackPrevented(link), Boolean.TRUE);
@@ -208,28 +194,26 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 			}
 		}
 
-		Set<Belief<?, ?>> attackPreventedBeliefs = getBeliefBase()
-				.getBeliefsByType(AttackPrevented.class);
+		Set<Belief<?, ?>> attackPreventedBeliefs = getBeliefBase().getBeliefsByType(AttackPrevented.class);
 		for (Belief<?, ?> belief : attackPreventedBeliefs) {
-			Predicate<AttackPrevented> attackPrevented = (Predicate<AttackPrevented>) belief;
+			PredicateBelief<AttackPrevented> attackPrevented = (PredicateBelief<AttackPrevented>) belief;
 			if (attackPrevented.getValue()) {
-				Predicate<AnomalousUsage> anomalousUsage = (Predicate<AnomalousUsage>) getBeliefBase()
-						.getBelief(
-								new AnomalousUsage(attackPrevented.getName()
-										.getConcept()));
+				PredicateBelief<AnomalousUsage> anomalousUsage = (PredicateBelief<AnomalousUsage>) getBeliefBase()
+						.getBelief(new AnomalousUsage(attackPrevented.getName().getVariable()));
 				// AttackPrevented(l) AND not AnomalousUsage(l) --> not
 				// AttackPrevented(l)
 				if (anomalousUsage != null && !anomalousUsage.getValue()) {
-					goal(goalUpdateSet, attackPrevented.getName(),
-							Boolean.FALSE);
+					goal(goalUpdateSet, attackPrevented.getName(), Boolean.FALSE);
 				}
 			}
 		}
 	}
 
 	@Override
-	protected Class<?> getLowPriorityGoal() {
-		return AnomalousUsage.class;
+	protected Set<Class<?>> getLowPriorityGoal() {
+		Set<Class<?>> lowPriorityGoals = new HashSet<>();
+		lowPriorityGoals.add(AnomalousUsage.class);
+		return lowPriorityGoals;
 	}
 
 	@Override
@@ -249,7 +233,7 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 		for (Link link : role.getLinks()) {
 			OverUsage overUsage = new OverUsage(link);
 			if (role.isOverUsage(link)) {
-				Predicate<OverUsage> overUsageBelief = (Predicate<OverUsage>) getBeliefBase()
+				PredicateBelief<OverUsage> overUsageBelief = (PredicateBelief<OverUsage>) getBeliefBase()
 						.getBelief(overUsage);
 				if (overUsageBelief == null || !overUsageBelief.getValue()) {
 					belief(overUsage, true);
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RateLimiterCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RateLimiterCapability.java
index ffb1044..c0d6594 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RateLimiterCapability.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RateLimiterCapability.java
@@ -23,7 +23,7 @@ package br.ufrgs.inf.bdinetr.agent;
 
 import bdi4jade.annotation.Parameter;
 import bdi4jade.annotation.Parameter.Direction;
-import bdi4jade.belief.Predicate;
+import bdi4jade.belief.PredicateBelief;
 import bdi4jade.goal.BeliefGoal;
 import bdi4jade.goal.Goal;
 import bdi4jade.goal.GoalTemplateFactory;
@@ -57,7 +57,7 @@ public class RateLimiterCapability extends RouterAgentCapability {
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(FlowRateLimited flowRateLimited) {
-			this.flow = flowRateLimited.getConcept();
+			this.flow = flowRateLimited.getVariable();
 		}
 	}
 
@@ -74,7 +74,7 @@ public class RateLimiterCapability extends RouterAgentCapability {
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(IpRateLimited ipRateLimited) {
-			this.ip = ipRateLimited.getConcept();
+			this.ip = ipRateLimited.getVariable();
 		}
 	}
 
@@ -91,7 +91,7 @@ public class RateLimiterCapability extends RouterAgentCapability {
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(LinkRateLimited linkRateLimited) {
-			this.link = linkRateLimited.getConcept();
+			this.link = linkRateLimited.getVariable();
 		}
 	}
 
@@ -108,7 +108,7 @@ public class RateLimiterCapability extends RouterAgentCapability {
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(IpRateLimited ipRateLimited) {
-			this.ip = ipRateLimited.getConcept();
+			this.ip = ipRateLimited.getVariable();
 		}
 	}
 
@@ -125,7 +125,7 @@ public class RateLimiterCapability extends RouterAgentCapability {
 
 		@Parameter(direction = Direction.IN)
 		public void setBeliefName(LinkRateLimited linkRateLimited) {
-			this.link = linkRateLimited.getConcept();
+			this.link = linkRateLimited.getVariable();
 		}
 	}
 
@@ -160,7 +160,7 @@ public class RateLimiterCapability extends RouterAgentCapability {
 				RestoreLinkRate.class) {
 			public boolean isContextApplicable(Goal goal) {
 				BeliefGoal<LinkRateLimited> bg = (BeliefGoal<LinkRateLimited>) goal;
-				Predicate<LinkRateLimited> rateLimited = (Predicate<LinkRateLimited>) getBeliefBase()
+				PredicateBelief<LinkRateLimited> rateLimited = (PredicateBelief<LinkRateLimited>) getBeliefBase()
 						.getBelief(bg.getBeliefName());
 				return (rateLimited != null && rateLimited.getValue());
 			};
@@ -175,7 +175,7 @@ public class RateLimiterCapability extends RouterAgentCapability {
 				RestoreIPRatePlan.class) {
 			public boolean isContextApplicable(Goal goal) {
 				BeliefGoal<IpRateLimited> bg = (BeliefGoal<IpRateLimited>) goal;
-				Predicate<IpRateLimited> rateLimited = (Predicate<IpRateLimited>) getBeliefBase()
+				PredicateBelief<IpRateLimited> rateLimited = (PredicateBelief<IpRateLimited>) getBeliefBase()
 						.getBelief(bg.getBeliefName());
 				return rateLimited != null && rateLimited.getValue();
 			};
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgentCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgentCapability.java
index 8337217..27ae426 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgentCapability.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgentCapability.java
@@ -28,7 +28,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import bdi4jade.belief.Belief;
-import bdi4jade.belief.Predicate;
+import bdi4jade.belief.PredicateBelief;
 import bdi4jade.belief.TransientPredicate;
 import bdi4jade.core.Capability;
 import bdi4jade.core.GoalUpdateSet;
@@ -46,8 +46,7 @@ import br.ufrgs.inf.bdinetr.domain.Role;
 /**
  * @author Ingrid Nunes
  */
-public abstract class RouterAgentCapability extends Capability implements
-		DeliberationFunction {
+public abstract class RouterAgentCapability extends Capability implements DeliberationFunction {
 
 	public static final String ROLE_BELIEF = "role";
 	private static final long serialVersionUID = -3491170777812144486L;
@@ -63,15 +62,15 @@ public abstract class RouterAgentCapability extends Capability implements
 		log.info("belief added or updated: " + belief);
 	}
 
-	protected Predicate<?> belief(Object proposition, Boolean value) {
+	protected PredicateBelief<?> belief(Object proposition, Boolean value) {
 		if (value == null) {
 			getBeliefBase().removeBelief(proposition);
-			log.info("belief(~" + proposition + "))");
+			log.info("belief(not " + proposition + "))");
 			return null;
 		} else {
-			Predicate<?> predicate = new TransientPredicate(proposition, value);
+			PredicateBelief<?> predicate = new TransientPredicate(proposition, value);
 			getBeliefBase().addOrUpdateBelief(predicate);
-			log.info("belief(" + (value ? "" : "not ") + proposition + ")");
+			log.info("belief(" + predicate + ")");
 			return predicate;
 		}
 	}
@@ -102,7 +101,7 @@ public abstract class RouterAgentCapability extends Capability implements
 		}
 	}
 
-	protected Class<?> getLowPriorityGoal() {
+	protected Set<Class<?>> getLowPriorityGoal() {
 		return null;
 	}
 
@@ -112,13 +111,11 @@ public abstract class RouterAgentCapability extends Capability implements
 		goal(goalUpdateSet, proposition, (GoalListener) null);
 	}
 
-	protected void goal(GoalUpdateSet goalUpdateSet, Object proposition,
-			Boolean value) {
+	protected void goal(GoalUpdateSet goalUpdateSet, Object proposition, Boolean value) {
 		goal(goalUpdateSet, proposition, value, null);
 	}
 
-	protected void goal(GoalUpdateSet goalUpdateSet, Object proposition,
-			Boolean value, GoalListener listener) {
+	protected void goal(GoalUpdateSet goalUpdateSet, Object proposition, Boolean value, GoalListener listener) {
 		Goal goal;
 		if (value == null) {
 			goal = new BeliefNotPresentGoal(proposition);
@@ -135,8 +132,7 @@ public abstract class RouterAgentCapability extends Capability implements
 		}
 	}
 
-	protected void goal(GoalUpdateSet goalUpdateSet, Object proposition,
-			GoalListener listener) {
+	protected void goal(GoalUpdateSet goalUpdateSet, Object proposition, GoalListener listener) {
 		Goal goal = new BeliefPresentGoal(proposition);
 		if (!getMyAgent().hasGoal(goal)) {
 			log.info("goal(?" + proposition + "))");
@@ -148,8 +144,11 @@ public abstract class RouterAgentCapability extends Capability implements
 		if (GoalStatus.WAITING.equals(goalDesc.getStatus())) {
 			if (goalDesc.getGoal() instanceof BeliefGoal) {
 				BeliefGoal<?> bg = (BeliefGoal<?>) goalDesc.getGoal();
-				return bg.getBeliefName().getClass()
-						.equals(getLowPriorityGoal());
+				for (Class<?> goalClass : getLowPriorityGoal()) {
+					if (bg.getBeliefName().getClass().equals(goalClass)) {
+						return true;
+					}
+				}
 			}
 		}
 		return false;
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/BDINetRApp.java b/network-resilience/src/br/ufrgs/inf/bdinetr/BDINetRApp.java
index d05796d..5d71547 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/BDINetRApp.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/BDINetRApp.java
@@ -21,18 +21,6 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr;
 
-import jade.BootProfileImpl;
-import jade.core.Profile;
-import jade.core.ProfileImpl;
-import jade.core.Specifier;
-import jade.core.event.NotificationService;
-import jade.core.messaging.TopicManagementHelper;
-import jade.core.messaging.TopicManagementService;
-import jade.tools.rma.rma;
-import jade.wrapper.AgentContainer;
-import jade.wrapper.AgentController;
-import jade.wrapper.PlatformController;
-
 import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -60,6 +48,17 @@ import br.ufrgs.inf.bdinetr.domain.Role;
 import br.ufrgs.inf.bdinetr.domain.Router;
 import br.ufrgs.inf.bdinetr.domain.dummy.DummyRouterComponentFactory;
 import br.ufrgs.inf.bdinetr.domain.omnet.OMNeTRouterComponentFactory;
+import jade.BootProfileImpl;
+import jade.core.Profile;
+import jade.core.ProfileImpl;
+import jade.core.Specifier;
+import jade.core.event.NotificationService;
+import jade.core.messaging.TopicManagementHelper;
+import jade.core.messaging.TopicManagementService;
+import jade.tools.rma.rma;
+import jade.wrapper.AgentContainer;
+import jade.wrapper.AgentController;
+import jade.wrapper.PlatformController;
 
 /**
  * @author Ingrid Nunes
@@ -67,12 +66,12 @@ import br.ufrgs.inf.bdinetr.domain.omnet.OMNeTRouterComponentFactory;
 public class BDINetRApp {
 
 	enum SimulationType {
-		OMNeT, SIMPLE_NETWORK, COMPLEX_NETWORK
+		OMNeT, SINGLE_AGENT, SIMPLE_NETWORK, COMPLEX_NETWORK, PALLIATIVE_AGENT
 	};
 
 	private static final Set<Link> AFFECTED_LINKS;
 	private static final Network NETWORK;
-	private static final SimulationType SIMULATION_TYPE = SimulationType.SIMPLE_NETWORK;
+	private static final SimulationType SIMULATION_TYPE = SimulationType.PALLIATIVE_AGENT;
 
 	static {
 		PropertyConfigurator.configure(BDINetRApp.class
@@ -97,6 +96,14 @@ public class BDINetRApp {
 			NETWORK.addRouter(new Router(new Ip("Inet.sas1.core0.rateLimiter"),
 					"ratelimiter_one", Role.RATE_LIMITER.getId(), factory));
 			break;
+		case SINGLE_AGENT:
+			factory = new DummyRouterComponentFactory();
+			NETWORK.addRouter(new Router(new Ip("SINGLE_AGENT"), Role.LINK_MONITOR
+					.getId() | Role.RATE_LIMITER.getId() | Role.ANOMALY_DETECTION.getId() | Role.CLASSIFIER
+					.getId() | Role.FLOW_EXPORTER
+					.getId(), factory));
+			AFFECTED_LINKS.add(new Link("AFFECTED_LINK"));
+			break;
 		case SIMPLE_NETWORK:
 			factory = new DummyRouterComponentFactory();
 			NETWORK.addRouter(new Router(new Ip("LC+RL"), Role.LINK_MONITOR
@@ -128,6 +135,14 @@ public class BDINetRApp {
 
 			AFFECTED_LINKS.add(new Link("AFFECTED_LINK"));
 			break;
+		case PALLIATIVE_AGENT:
+			factory = new DummyRouterComponentFactory();
+			NETWORK.addRouterPalliative(new Router(new Ip("PALLIATIVE_AGENT"), Role.LINK_MONITOR
+					.getId() | Role.RATE_LIMITER.getId() | Role.ANOMALY_DETECTION.getId() | Role.CLASSIFIER
+					.getId() | Role.FLOW_EXPORTER
+					.getId(), factory));
+			AFFECTED_LINKS.add(new Link("AFFECTED_LINK"));
+			break;
 		}
 
 		Set<Router> routers = NETWORK.getRouters();
@@ -227,8 +242,7 @@ public class BDINetRApp {
 		for (Link link : AFFECTED_LINKS) {
 			for (Router router : NETWORK.getRouters()) {
 				if (router.hasRole(Role.LINK_MONITOR)) {
-					LinkMonitor lm = (LinkMonitor) router
-							.getRole(Role.LINK_MONITOR);
+					LinkMonitor lm = (LinkMonitor) router.getRole(Role.LINK_MONITOR);
 					lm.setOverUsage(link, true);
 				}
 			}
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/AbstractRouterComponent.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/AbstractRouterComponent.java
index d63b533..160d8f1 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/AbstractRouterComponent.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/AbstractRouterComponent.java
@@ -29,8 +29,7 @@ import br.ufrgs.inf.bdinetr.domain.RouterComponent;
 /**
  * @author Ingrid Nunes
  */
-public abstract class AbstractRouterComponent extends Observable implements
-		RouterComponent {
+public abstract class AbstractRouterComponent extends Observable implements RouterComponent {
 
 	protected final Router router;
 
@@ -38,4 +37,12 @@ public abstract class AbstractRouterComponent extends Observable implements
 		this.router = router;
 	}
 
+	protected synchronized void delay(long sec) {
+		try {
+			Thread.sleep(sec * 1000);
+		} catch (InterruptedException e) {
+			// TODO: handle exception
+		}
+	}
+
 }
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyAnomalyDetection.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyAnomalyDetection.java
index bb1dfb5..7ef7e5a 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyAnomalyDetection.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyAnomalyDetection.java
@@ -32,27 +32,36 @@ import br.ufrgs.inf.bdinetr.domain.Router;
 /**
  * @author Ingrid Nunes
  */
-public class DummyAnomalyDetection extends AbstractRouterComponent implements
-		AnomalyDetection {
+public class DummyAnomalyDetection extends AbstractRouterComponent implements AnomalyDetection {
+	
+	public static final long DELAY = 10;
 
 	private boolean first;
+	private boolean mode;
 
 	public DummyAnomalyDetection(Router router) {
 		super(router);
 		this.first = true;
+		this.mode = true;
 	}
 
 	@Override
 	public Set<Ip> detectIntrusion(Link link) {
 		Set<Ip> intrusions = new HashSet<>();
 		if (link.getId().equals("AFFECTED_LINK")) {
-			if (first) {
+			if (mode) {
 				intrusions.add(new Ip("victim1"));
-				first = false;
-			} else {
 				intrusions.add(new Ip("victim2"));
+			} else {
+				if (first) {
+					intrusions.add(new Ip("victim1"));
+					first = false;
+				} else {
+					intrusions.add(new Ip("victim2"));
+				}
 			}
 		}
+		delay(DELAY);
 		return intrusions;
 	}
 
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyClassifier.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyClassifier.java
index 0f8de5b..f5cf24b 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyClassifier.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyClassifier.java
@@ -33,6 +33,8 @@ import br.ufrgs.inf.bdinetr.domain.Router;
  * @author Ingrid Nunes
  */
 public class DummyClassifier extends AbstractRouterComponent implements Classifier {
+	
+	public static final long DELAY = 30;
 
 	public DummyClassifier(Router router) {
 		super(router);
@@ -50,6 +52,7 @@ public class DummyClassifier extends AbstractRouterComponent implements Classifi
 			flows.add(new Flow(new Ip("DDoS3"), 80, new Ip("victim2"), 80,
 					"http"));
 		}
+		delay(DELAY);
 		return flows;
 	}
 
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyLinkMonitor.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyLinkMonitor.java
index afb3afc..50da416 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyLinkMonitor.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyLinkMonitor.java
@@ -44,7 +44,7 @@ public class DummyLinkMonitor extends AbstractRouterComponent implements
 	public DummyLinkMonitor(Router router) {
 		super(router);
 		this.overUsageLinks = new HashMap<>();
-		this.first = true;
+		this.first = false;
 	}
 
 	@Override
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyRateLimiter.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyRateLimiter.java
index 9faba12..0132665 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyRateLimiter.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/dummy/DummyRateLimiter.java
@@ -37,6 +37,8 @@ import br.ufrgs.inf.bdinetr.domain.Router;
  */
 public class DummyRateLimiter extends AbstractRouterComponent implements
 		RateLimiter, Observable {
+	
+	public static final long DELAY = 2;
 
 	private final Map<Flow, Integer> rateLimitedflows;
 	private final Map<Ip, Integer> rateLimitedIps;
@@ -52,16 +54,19 @@ public class DummyRateLimiter extends AbstractRouterComponent implements
 	@Override
 	public void limitFlow(Flow flow, int rate) {
 		this.rateLimitedflows.put(flow, rate);
+		delay(DELAY);
 	}
 
 	@Override
 	public void limitIp(Ip ip, int rate) {
 		this.rateLimitedIps.put(ip, rate);
+		delay(DELAY);
 	}
 
 	@Override
 	public void limitLink(Link link, int rate) {
 		this.rateLimitedLinks.put(link, rate);
+		delay(DELAY);
 		setChanged();
 		notifyObservers(new LimitLinkEvent(link));
 	}
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/ontology/BDI4JADEOntology.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/ontology/BDI4JADEOntology.java
index bf084e4..b382fc6 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/ontology/BDI4JADEOntology.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/ontology/BDI4JADEOntology.java
@@ -11,7 +11,7 @@ import bdi4jade.belief.AbstractBeliefSet;
 import bdi4jade.belief.Belief;
 import bdi4jade.belief.BeliefSet;
 import bdi4jade.belief.PersistentBelief;
-import bdi4jade.belief.Predicate;
+import bdi4jade.belief.PredicateBelief;
 import bdi4jade.belief.TransientBelief;
 import bdi4jade.belief.TransientBeliefSet;
 import bdi4jade.belief.TransientPredicate;
@@ -58,7 +58,7 @@ public class BDI4JADEOntology extends Ontology implements BDI4JADEVocabulary {
 			
 			add(new PredicateSchema(BELIEF), Belief.class);
 			add(new PredicateSchema(BELIEF_SET), BeliefSet.class);
-			add(new PredicateSchema(PROPOSITIONAL_BELIEF), Predicate.class);
+			add(new PredicateSchema(PROPOSITIONAL_BELIEF), PredicateBelief.class);
 
 			add(new PredicateSchema(ABSTRACT_BELIEF), AbstractBelief.class);
 			add(new PredicateSchema(ABSTRACT_BELIEF_SET), AbstractBeliefSet.class);
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/ontology/BDINetROntology.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/ontology/BDINetROntology.java
index faefac1..f52e366 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/ontology/BDINetROntology.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/ontology/BDINetROntology.java
@@ -28,6 +28,8 @@ import jade.content.schema.ConceptSchema;
 import jade.content.schema.ObjectSchema;
 import jade.content.schema.PredicateSchema;
 import jade.content.schema.PrimitiveSchema;
+import bdi4jade.extension.palliative.logics.BinaryPredicate;
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Flow;
 import br.ufrgs.inf.bdinetr.domain.Ip;
 import br.ufrgs.inf.bdinetr.domain.Link;
@@ -38,7 +40,6 @@ import br.ufrgs.inf.bdinetr.domain.predicate.Anomalous;
 import br.ufrgs.inf.bdinetr.domain.predicate.AnomalousUsage;
 import br.ufrgs.inf.bdinetr.domain.predicate.AttackPrevented;
 import br.ufrgs.inf.bdinetr.domain.predicate.Benign;
-import br.ufrgs.inf.bdinetr.domain.predicate.BinaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.predicate.FlowExport;
 import br.ufrgs.inf.bdinetr.domain.predicate.FlowRateLimited;
 import br.ufrgs.inf.bdinetr.domain.predicate.IpRateLimited;
@@ -46,7 +47,6 @@ import br.ufrgs.inf.bdinetr.domain.predicate.LinkRateLimited;
 import br.ufrgs.inf.bdinetr.domain.predicate.OverUsage;
 import br.ufrgs.inf.bdinetr.domain.predicate.Restricted;
 import br.ufrgs.inf.bdinetr.domain.predicate.Threat;
-import br.ufrgs.inf.bdinetr.domain.predicate.UnaryPredicate;
 
 /**
  * @author Ingrid Nunes
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Anomalous.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Anomalous.java
index 1ce1a20..0f065f5 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Anomalous.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Anomalous.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Ip;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/AnomalousUsage.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/AnomalousUsage.java
index ba21c81..24a0254 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/AnomalousUsage.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/AnomalousUsage.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Link;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/AttackPrevented.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/AttackPrevented.java
index 82f7a61..2e3b3e2 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/AttackPrevented.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/AttackPrevented.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Link;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Benign.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Benign.java
index 880f09f..1deae70 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Benign.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Benign.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Ip;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/FlowRateLimited.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/FlowRateLimited.java
index cd8187e..47307e6 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/FlowRateLimited.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/FlowRateLimited.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Flow;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/IpRateLimited.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/IpRateLimited.java
index 9eaf048..9928fbc 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/IpRateLimited.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/IpRateLimited.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Ip;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/LinkRateLimited.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/LinkRateLimited.java
index 720260e..7fc3706 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/LinkRateLimited.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/LinkRateLimited.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Link;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/OverUsage.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/OverUsage.java
index 7b93463..f8763a1 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/OverUsage.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/OverUsage.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Link;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/OverUsageCause.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/OverUsageCause.java
index 0180a70..51ff5b6 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/OverUsageCause.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/OverUsageCause.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Link;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Restricted.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Restricted.java
index 2f36fd5..b5bef9a 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Restricted.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Restricted.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Ip;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Threat.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Threat.java
index 00169f6..b286271 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Threat.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/predicate/Threat.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.predicate;
 
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
 import br.ufrgs.inf.bdinetr.domain.Flow;
 
 /**
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/Network.java b/network-resilience/src/br/ufrgs/inf/bdinetr/Network.java
index 7a215d5..16ac1f9 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/Network.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/Network.java
@@ -28,13 +28,15 @@ import java.util.Set;
 
 import br.ufrgs.inf.bdinetr.agent.RouterAgent;
 import br.ufrgs.inf.bdinetr.domain.Router;
+import br.ufrgs.inf.bdinetr.palliative.BDI2DoSAgent;
+import jade.core.Agent;
 
 /**
  * @author Ingrid Nunes
  */
 public class Network {
 
-	private final Map<Router, RouterAgent> routerAgents;
+	private final Map<Router, Agent> routerAgents;
 
 	public Network() {
 		this.routerAgents = new HashMap<>();
@@ -44,11 +46,15 @@ public class Network {
 		this.routerAgents.put(router, new RouterAgent(router));
 	}
 
-	public RouterAgent getAgent(Router router) {
+	public void addRouterPalliative(Router router) {
+		this.routerAgents.put(router, new BDI2DoSAgent(router));
+	}
+
+	public Agent getAgent(Router router) {
 		return routerAgents.get(router);
 	}
 
-	public Collection<RouterAgent> getRouterAgents() {
+	public Collection<Agent> getRouterAgents() {
 		return routerAgents.values();
 	}
 
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/palliative/BDI2DoSAgent.java b/network-resilience/src/br/ufrgs/inf/bdinetr/palliative/BDI2DoSAgent.java
new file mode 100644
index 0000000..277fa0e
--- /dev/null
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/palliative/BDI2DoSAgent.java
@@ -0,0 +1,27 @@
+package br.ufrgs.inf.bdinetr.palliative;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import bdi4jade.core.SingleCapabilityAgent;
+import br.ufrgs.inf.bdinetr.agent.RouterAgent;
+import br.ufrgs.inf.bdinetr.domain.Router;
+import br.ufrgs.inf.bdinetr.domain.ontology.BDINetROntology;
+import jade.content.lang.sl.SLCodec;
+
+public class BDI2DoSAgent extends SingleCapabilityAgent {
+
+	private static final Log log = LogFactory.getLog(RouterAgent.class);
+	private static final long serialVersionUID = 6534875498063013722L;
+
+	public BDI2DoSAgent(Router router) {
+		super(new BDI2DoSCapability(router));
+	}
+
+	@Override
+	protected void init() {
+		getContentManager().registerLanguage(new SLCodec());
+		getContentManager().registerOntology(BDINetROntology.getInstance());
+	}
+
+}
\ No newline at end of file
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/palliative/BDI2DoSCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/palliative/BDI2DoSCapability.java
new file mode 100644
index 0000000..a04206f
--- /dev/null
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/palliative/BDI2DoSCapability.java
@@ -0,0 +1,627 @@
+package br.ufrgs.inf.bdinetr.palliative;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Set;
+
+import bdi4jade.annotation.Parameter;
+import bdi4jade.annotation.Parameter.Direction;
+import bdi4jade.belief.Belief;
+import bdi4jade.belief.BeliefSet;
+import bdi4jade.belief.PredicateBelief;
+import bdi4jade.belief.TransientBelief;
+import bdi4jade.belief.TransientBeliefSet;
+import bdi4jade.core.GoalUpdateSet;
+import bdi4jade.event.GoalEvent;
+import bdi4jade.event.GoalListener;
+import bdi4jade.extension.palliative.PlanRequiredResource;
+import bdi4jade.extension.palliative.Resource;
+import bdi4jade.extension.palliative.ResourcePreferences;
+import bdi4jade.extension.palliative.goal.ConstrainedGoal;
+import bdi4jade.extension.palliative.goal.ObjectiveFunction;
+import bdi4jade.extension.palliative.graph.AlternativeCauseSet;
+import bdi4jade.extension.palliative.graph.CauseEffectKnowledgeModel;
+import bdi4jade.extension.palliative.graph.CauseEffectRelationship;
+import bdi4jade.extension.palliative.logics.Fact;
+import bdi4jade.extension.palliative.logics.MathExpression;
+import bdi4jade.extension.palliative.logics.MathExpression.Operator;
+import bdi4jade.extension.palliative.logics.UnaryPredicate;
+import bdi4jade.extension.palliative.reasoning.PalliativeOptionGenerationFunction;
+import bdi4jade.extension.palliative.reasoning.PalliativePlanSelectionStrategy;
+import bdi4jade.goal.BeliefGoal;
+import bdi4jade.goal.BeliefValueGoal;
+import bdi4jade.goal.Goal;
+import bdi4jade.goal.GoalStatus;
+import bdi4jade.goal.GoalTemplate;
+import bdi4jade.goal.GoalTemplateFactory;
+import bdi4jade.goal.PredicateGoal;
+import bdi4jade.plan.DefaultPlan;
+import bdi4jade.plan.Plan;
+import bdi4jade.plan.Plan.EndState;
+import bdi4jade.plan.planbody.BeliefGoalPlanBody;
+import bdi4jade.reasoning.BeliefRevisionStrategy;
+import br.ufrgs.inf.bdinetr.agent.FlowExporterCapability;
+import br.ufrgs.inf.bdinetr.agent.RateLimiterCapability;
+import br.ufrgs.inf.bdinetr.agent.RouterAgentCapability;
+import br.ufrgs.inf.bdinetr.agent.belief.AnomalousUsageBelief;
+import br.ufrgs.inf.bdinetr.agent.belief.BenignBelief;
+import br.ufrgs.inf.bdinetr.domain.AnomalyDetection;
+import br.ufrgs.inf.bdinetr.domain.Classifier;
+import br.ufrgs.inf.bdinetr.domain.Flow;
+import br.ufrgs.inf.bdinetr.domain.FlowExporter;
+import br.ufrgs.inf.bdinetr.domain.Ip;
+import br.ufrgs.inf.bdinetr.domain.Link;
+import br.ufrgs.inf.bdinetr.domain.LinkMonitor;
+import br.ufrgs.inf.bdinetr.domain.RateLimiter;
+import br.ufrgs.inf.bdinetr.domain.Role;
+import br.ufrgs.inf.bdinetr.domain.Router;
+import br.ufrgs.inf.bdinetr.domain.predicate.Anomalous;
+import br.ufrgs.inf.bdinetr.domain.predicate.AnomalousUsage;
+import br.ufrgs.inf.bdinetr.domain.predicate.AttackPrevented;
+import br.ufrgs.inf.bdinetr.domain.predicate.Benign;
+import br.ufrgs.inf.bdinetr.domain.predicate.FlowExport;
+import br.ufrgs.inf.bdinetr.domain.predicate.FlowRateLimited;
+import br.ufrgs.inf.bdinetr.domain.predicate.IpRateLimited;
+import br.ufrgs.inf.bdinetr.domain.predicate.LinkRateLimited;
+import br.ufrgs.inf.bdinetr.domain.predicate.OverUsage;
+import br.ufrgs.inf.bdinetr.domain.predicate.OverUsageCause;
+import br.ufrgs.inf.bdinetr.domain.predicate.Restricted;
+import br.ufrgs.inf.bdinetr.domain.predicate.Threat;
+
+public class BDI2DoSCapability extends RouterAgentCapability implements BeliefRevisionStrategy, GoalListener, Observer {
+
+	public class OverUsageGoal extends ConstrainedGoal {
+
+		public OverUsageGoal(Link link, Boolean value) {
+			super(new PredicateGoal<OverUsage>(new OverUsage(link), false));
+
+			this.addOperationConstraint(new MathExpression<Resource>(Resources.VULNERABILITY, Operator.LESS_THAN, 0.5));
+
+			this.addObjectiveFunction(Resources.TIME, ObjectiveFunction.MINIMIZE);
+			this.addObjectiveFunction(Resources.NETWORK_AVAILABILITY, ObjectiveFunction.MAXIMIZE);
+			this.addObjectiveFunction(Resources.VULNERABILITY, ObjectiveFunction.MINIMIZE);
+		}
+
+	}
+
+	public class LimitLinkRate extends BeliefGoalPlanBody {
+		private static final long serialVersionUID = -3493377510830902961L;
+
+		private Link link;
+		private boolean subgoalDispatched;
+
+		@Override
+		public void execute() {
+			if (!subgoalDispatched) {
+				dispatchSubgoalAndListen(new BeliefValueGoal<>(new LinkRateLimited(link), true));
+				this.subgoalDispatched = true;
+			} else {
+				GoalEvent event = getGoalEvent();
+				if (event != null) {
+					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
+						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
+						belief(new AttackPrevented(link), true);
+					} else {
+						setEndState(EndState.FAILED);
+					}
+				}
+			}
+		}
+
+		@Override
+		protected void init() {
+			this.subgoalDispatched = false;
+		}
+
+		@Parameter(direction = Direction.IN)
+		public void setBeliefName(UnaryPredicate<Link> attackPrevented) {
+			this.link = attackPrevented.getVariable();
+		}
+	}
+
+	public class RestoreLinkRate extends BeliefGoalPlanBody {
+		private static final long serialVersionUID = -3493377510830902961L;
+
+		private Link link;
+		private boolean subgoalDispatched;
+
+		@Override
+		public void execute() {
+			if (!subgoalDispatched) {
+				dispatchSubgoalAndListen(new BeliefValueGoal<>(new LinkRateLimited(link), false));
+				this.subgoalDispatched = true;
+			} else {
+				GoalEvent event = getGoalEvent();
+				if (event != null) {
+					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
+						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
+						belief(new AttackPrevented(link), false);
+						belief(new AnomalousUsage(link), null);
+					} else {
+						setEndState(EndState.FAILED);
+					}
+				}
+			}
+		}
+
+		@Override
+		protected void init() {
+			this.subgoalDispatched = false;
+		}
+
+		@Parameter(direction = Direction.IN)
+		public void setBeliefName(AttackPrevented attackPrevented) {
+			this.link = attackPrevented.getVariable();
+		}
+	}
+
+	public class AnalyseLinkStatistics extends BeliefGoalPlanBody {
+		private static final long serialVersionUID = -3493377510830902961L;
+
+		private Link link;
+
+		@Override
+		public void execute() {
+			Set<Ip> outliers = getAnomalyDetection().detectIntrusion(link);
+			BeliefSet<OverUsageCause, Ip> overUsageCause = new TransientBeliefSet<OverUsageCause, Ip>(
+					new OverUsageCause(link));
+			if (outliers != null && !outliers.isEmpty()) {
+				for (Ip outlier : outliers) {
+					belief(new Anomalous(outlier), true);
+					belief(new Benign(outlier), null);
+					overUsageCause.addValue(outlier);
+				}
+			}
+			addBelief(overUsageCause);
+			addBelief(new AnomalousUsageBelief(new AnomalousUsage(link)));
+		}
+
+		@Parameter(direction = Direction.IN)
+		public void setBeliefName(AnomalousUsage anomalousUsage) {
+			this.link = anomalousUsage.getVariable();
+		}
+	}
+
+	public class LimitIPRatePlan extends BeliefGoalPlanBody {
+		private static final long serialVersionUID = -3493377510830902961L;
+
+		private Ip ip;
+		private boolean subgoalDispatched;
+
+		@Override
+		public void execute() {
+			if (!subgoalDispatched) {
+				dispatchSubgoalAndListen(new BeliefValueGoal<>(new IpRateLimited(ip), true));
+				this.subgoalDispatched = true;
+			} else {
+				GoalEvent event = getGoalEvent();
+				if (event != null) {
+					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
+						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
+						belief(new Restricted(ip), true);
+
+						Set<Belief<?, ?>> overUsageCauseBeliefs = getBeliefBase()
+								.getBeliefsByType(OverUsageCause.class);
+						Iterator<Belief<?, ?>> it = overUsageCauseBeliefs.iterator();
+						while (it.hasNext()) {
+							BeliefSet<OverUsageCause, Ip> overUsageCause = (BeliefSet<OverUsageCause, Ip>) it.next();
+							if (overUsageCause.hasValue(ip)) {
+								// ip in OverUsageCause(l) --> remove
+								overUsageCause.removeValue(ip);
+							}
+						}
+						belief(new Anomalous(ip), false);
+					} else {
+						setEndState(EndState.FAILED);
+					}
+				}
+			}
+		}
+
+		@Override
+		protected void init() {
+			this.subgoalDispatched = false;
+		}
+
+		@Parameter(direction = Direction.IN)
+		public void setBeliefName(UnaryPredicate<Ip> restricted) {
+			this.ip = restricted.getVariable();
+		}
+	}
+
+	public class RestoreIPRatePlan extends BeliefGoalPlanBody {
+		private static final long serialVersionUID = -3493377510830902961L;
+
+		private Ip ip;
+		private boolean subgoalDispatched;
+
+		@Override
+		public void execute() {
+			if (!subgoalDispatched) {
+				dispatchSubgoalAndListen(new BeliefValueGoal<>(new IpRateLimited(ip), false));
+				this.subgoalDispatched = true;
+			} else {
+				GoalEvent event = getGoalEvent();
+				if (event != null) {
+					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
+						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
+						belief(new Restricted(ip), false);
+						belief(new Anomalous(ip), null);
+					} else {
+						setEndState(EndState.FAILED);
+					}
+				}
+			}
+		}
+
+		@Override
+		protected void init() {
+			this.subgoalDispatched = false;
+		}
+
+		@Parameter(direction = Direction.IN)
+		public void setBeliefName(Restricted restricted) {
+			this.ip = restricted.getVariable();
+		}
+	}
+
+	public class AnalyseIPFlows extends BeliefGoalPlanBody {
+		private static final long serialVersionUID = -3493377510830902961L;
+
+		private Ip ip;
+		private boolean subgoalDispatched;
+
+		@Override
+		public void execute() {
+			if (!subgoalDispatched) {
+				dispatchSubgoalAndListen(new FlowExport(ip));
+				this.subgoalDispatched = true;
+			} else {
+				GoalEvent event = getGoalEvent();
+				if (event != null) {
+					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
+						Set<Flow> malicious = getClassifier().classifyFlows(ip);
+						for (Flow flow : malicious) {
+							belief(new Threat(flow), true);
+						}
+						addBelief(new BenignBelief(new Benign(ip)));
+					} else {
+						setEndState(EndState.FAILED);
+					}
+				} else {
+					block();
+				}
+			}
+		}
+
+		@Override
+		public void init() {
+			this.subgoalDispatched = false;
+		}
+
+		@Parameter(direction = Direction.IN)
+		public void setBeliefName(Benign benign) {
+			this.ip = benign.getVariable();
+		}
+	}
+
+	public class LimitFlowRatePlan extends BeliefGoalPlanBody {
+		private static final long serialVersionUID = -3493377510830902961L;
+
+		private Flow flow;
+		private boolean subgoalDispatched;
+
+		@Override
+		public void execute() {
+			if (!subgoalDispatched) {
+				dispatchSubgoalAndListen(new BeliefValueGoal<>(new FlowRateLimited(flow), true));
+				this.subgoalDispatched = true;
+			} else {
+				GoalEvent event = getGoalEvent();
+				if (event != null) {
+					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
+						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
+						belief(new Threat(flow), false);
+					} else {
+						setEndState(EndState.FAILED);
+					}
+				}
+			}
+		}
+
+		@Override
+		protected void init() {
+			this.subgoalDispatched = false;
+		}
+
+		@Parameter(direction = Direction.IN)
+		public void setBeliefName(Threat threat) {
+			this.flow = threat.getVariable();
+		}
+	}
+
+	public static final String ROUTER_BELIEF = "router";
+	private static final long serialVersionUID = 4633237702870865396L;
+
+	@bdi4jade.annotation.Belief
+	private final Belief<String, Router> router;
+
+	@bdi4jade.annotation.Belief
+	protected CauseEffectKnowledgeModel causeEffectKnowledgeModel = new CauseEffectKnowledgeModel();
+
+	@bdi4jade.annotation.Belief
+	protected ResourcePreferences preferences = new ResourcePreferences();
+
+	@bdi4jade.annotation.Plan
+	private Plan limitLinkRate;
+	@bdi4jade.annotation.Plan
+	private Plan restoreLinkRate;
+
+	@bdi4jade.annotation.Plan
+	private Plan analyseLinkStatistics;
+	@bdi4jade.annotation.Plan
+	private Plan limitIpRate;
+	@bdi4jade.annotation.Plan
+	private Plan restoreIpRate;
+
+	@bdi4jade.annotation.Plan
+	private Plan analyseIpFlows;
+	@bdi4jade.annotation.Plan
+	private Plan limitFlowRate;
+
+	public BDI2DoSCapability(Router router) {
+		this.router = new TransientBelief<>(ROUTER_BELIEF, router);
+		getLinkMonitor().addObserver(this);
+
+		setBeliefRevisionStrategy(this);
+		setOptionGenerationFunction(new MyGoalGenerationFunction());
+		setPlanSelectionStrategy(new PalliativePlanSelectionStrategy(this));
+
+		addPartCapability(new RateLimiterCapability(getRateLimiter()));
+		addPartCapability(new FlowExporterCapability(getFlowExporter()));
+
+		// Cause-Effect Knowledge Model
+		CauseEffectRelationship cer = new CauseEffectRelationship(
+				new Fact(new OverUsage(new Link("AFFECTED_LINK")), true));
+		cer.addOptionalCause(new Fact(new AnomalousUsage(new Link("AFFECTED_LINK")), true));
+		AlternativeCauseSet alternatives = new AlternativeCauseSet(1, 2);
+		alternatives.addAlternativeCause(new Fact(new Anomalous(new Ip("victim1")), true));
+		alternatives.addAlternativeCause(new Fact(new Anomalous(new Ip("victim2")), true));
+		cer.addAlternativeCauseSet(alternatives);
+		causeEffectKnowledgeModel.addCauseEffectRelationship(cer);
+
+		cer = new CauseEffectRelationship(new Fact(new Anomalous(new Ip("victim1")), true));
+		cer.addOptionalCause(new Fact(new Benign(new Ip("victim1")), false));
+		alternatives = new AlternativeCauseSet(1, 2);
+		alternatives.addAlternativeCause(
+				new Fact(new Threat(new Flow(new Ip("DDoS1"), 80, new Ip("victim1"), 80, "http")), true));
+		alternatives.addAlternativeCause(
+				new Fact(new Threat(new Flow(new Ip("DDoS2"), 80, new Ip("victim1"), 80, "http")), true));
+		cer.addAlternativeCauseSet(alternatives);
+		causeEffectKnowledgeModel.addCauseEffectRelationship(cer);
+
+		cer = new CauseEffectRelationship(new Fact(new Anomalous(new Ip("victim2")), true));
+		cer.addOptionalCause(new Fact(new Benign(new Ip("victim2")), false));
+		alternatives = new AlternativeCauseSet(1, 1);
+		alternatives.addAlternativeCause(
+				new Fact(new Threat(new Flow(new Ip("DDoS3"), 80, new Ip("victim2"), 80, "http")), true));
+		cer.addAlternativeCauseSet(alternatives);
+		causeEffectKnowledgeModel.addCauseEffectRelationship(cer);
+
+		// Resource Preferences
+		preferences.getValue().put(Resources.TIME, 0.75);
+		preferences.getValue().put(Resources.NETWORK_AVAILABILITY, 0.25);
+
+		// Plans
+
+		this.limitLinkRate = new DefaultPlan(
+				new GoalTemplate[] { GoalTemplateFactory.hasBeliefOfTypeWithValue(AttackPrevented.class, Boolean.TRUE),
+						GoalTemplateFactory.hasBeliefOfTypeWithValue(OverUsage.class, Boolean.FALSE) },
+				LimitLinkRate.class);
+		PlanRequiredResource prr = new PlanRequiredResource();
+		prr.setRequiredResource(Resources.TIME, 5.0);
+		prr.setRequiredResource(Resources.NETWORK_AVAILABILITY, 0.6);
+		prr.setRequiredResource(Resources.VULNERABILITY, 0.3);
+		this.limitLinkRate.putMetadata(PlanRequiredResource.METADATA_NAME, prr);
+		this.restoreLinkRate = new DefaultPlan(
+				GoalTemplateFactory.hasBeliefOfTypeWithValue(AttackPrevented.class, Boolean.FALSE),
+				RestoreLinkRate.class) {
+			@Override
+			public boolean isContextApplicable(Goal goal) {
+				BeliefGoal<AttackPrevented> bg = (BeliefGoal<AttackPrevented>) goal;
+				PredicateBelief<LinkRateLimited> linkRateLimited = (PredicateBelief<LinkRateLimited>) getBeliefBase()
+						.getBelief(new LinkRateLimited(bg.getBeliefName().getVariable()));
+				return (linkRateLimited != null && linkRateLimited.getValue());
+			}
+		};
+
+		this.analyseLinkStatistics = new DefaultPlan(GoalTemplateFactory.hasBeliefOfType(AnomalousUsage.class),
+				AnalyseLinkStatistics.class);
+		this.limitIpRate = new DefaultPlan(
+				new GoalTemplate[] { GoalTemplateFactory.hasBeliefOfTypeWithValue(Restricted.class, Boolean.TRUE),
+						GoalTemplateFactory.hasBeliefOfTypeWithValue(Anomalous.class, Boolean.FALSE) },
+				LimitIPRatePlan.class);
+		this.restoreIpRate = new DefaultPlan(
+				GoalTemplateFactory.hasBeliefOfTypeWithValue(Restricted.class, Boolean.FALSE),
+				RestoreIPRatePlan.class) {
+			@Override
+			public boolean isContextApplicable(Goal goal) {
+				BeliefGoal<Restricted> bg = (BeliefGoal<Restricted>) goal;
+				PredicateBelief<IpRateLimited> ipRateLimited = (PredicateBelief<IpRateLimited>) getBeliefBase()
+						.getBelief(new IpRateLimited(bg.getBeliefName().getVariable()));
+				return (ipRateLimited != null && ipRateLimited.getValue());
+			}
+		};
+
+		this.analyseIpFlows = new DefaultPlan(GoalTemplateFactory.hasBeliefOfType(Benign.class)
+
+				, AnalyseIPFlows.class);
+		this.limitFlowRate = new DefaultPlan(
+				new GoalTemplate[] { GoalTemplateFactory.hasBeliefOfTypeWithValue(Threat.class, Boolean.FALSE) },
+				LimitFlowRatePlan.class) {
+			public boolean isContextApplicable(Goal goal) {
+				BeliefGoal<Threat> bg = (BeliefGoal<Threat>) goal;
+				PredicateBelief<Threat> threat = (PredicateBelief<Threat>) getBeliefBase()
+						.getBelief(bg.getBeliefName());
+				return (threat != null && threat.getValue());
+			};
+		};
+
+	}
+
+	private LinkMonitor getLinkMonitor() {
+		return (LinkMonitor) router.getValue().getRole(Role.LINK_MONITOR);
+	}
+
+	private RateLimiter getRateLimiter() {
+		return (RateLimiter) router.getValue().getRole(Role.RATE_LIMITER);
+	}
+
+	private FlowExporter getFlowExporter() {
+		return (FlowExporter) router.getValue().getRole(Role.FLOW_EXPORTER);
+	}
+
+	private Classifier getClassifier() {
+		return (Classifier) router.getValue().getRole(Role.CLASSIFIER);
+	}
+
+	private AnomalyDetection getAnomalyDetection() {
+		return (AnomalyDetection) router.getValue().getRole(Role.ANOMALY_DETECTION);
+	}
+
+	@Override
+	public Role getRole() {
+		// FIXME
+		return Role.LINK_MONITOR;
+	}
+
+	@Override
+	protected Set<Class<?>> getLowPriorityGoal() {
+		Set<Class<?>> lowPriorityGoals = new HashSet<>();
+		lowPriorityGoals.add(AnomalousUsage.class);
+		lowPriorityGoals.add(Benign.class);
+		return lowPriorityGoals;
+	}
+
+	class MyGoalGenerationFunction extends PalliativeOptionGenerationFunction {
+
+		private Boolean added = false;
+
+		public MyGoalGenerationFunction() {
+			super(BDI2DoSCapability.this);
+		}
+
+		@Override
+		public void generateGoals(GoalUpdateSet goalUpdateSet) {
+			super.generateGoals(goalUpdateSet);
+
+			// Link Monitor
+			Set<Belief<?, ?>> overUsageBeliefs = getBeliefBase().getBeliefsByType(OverUsage.class);
+			for (Belief<?, ?> belief : overUsageBeliefs) {
+				PredicateBelief<OverUsage> overUsage = (PredicateBelief<OverUsage>) belief;
+				Link link = overUsage.getName().getVariable();
+				if (overUsage.getValue()) {
+					PredicateBelief<AnomalousUsage> anomalousUsage = (PredicateBelief<AnomalousUsage>) getBeliefBase()
+							.getBelief(new AnomalousUsage(link));
+					PredicateBelief<AttackPrevented> attackPrevented = (PredicateBelief<AttackPrevented>) getBeliefBase()
+							.getBelief(new AttackPrevented(link));
+					if (anomalousUsage == null || anomalousUsage.getValue()) {
+						// OverUsage(l) AND !(not AnomalousUsage(l)) -->
+						// ~OverUsage(l)
+						if (!added) {
+							goalUpdateSet.generateGoal(new OverUsageGoal(link, Boolean.FALSE), BDI2DoSCapability.this,
+									null);
+							log.info("OverUsageGoal added.");
+							added = true;
+						}
+					}
+				}
+			}
+
+			Set<Belief<?, ?>> attackPreventedBeliefs = getBeliefBase().getBeliefsByType(AttackPrevented.class);
+			for (Belief<?, ?> belief : attackPreventedBeliefs) {
+				PredicateBelief<AttackPrevented> attackPrevented = (PredicateBelief<AttackPrevented>) belief;
+				if (attackPrevented.getValue()) {
+					PredicateBelief<AnomalousUsage> anomalousUsage = (PredicateBelief<AnomalousUsage>) getBeliefBase()
+							.getBelief(new AnomalousUsage(attackPrevented.getName().getVariable()));
+					// AttackPrevented(l) AND not AnomalousUsage(l) --> not
+					// AttackPrevented(l)
+					if (anomalousUsage != null && !anomalousUsage.getValue()) {
+						goal(goalUpdateSet, attackPrevented.getName(), Boolean.FALSE);
+					}
+				}
+			}
+
+			Set<Belief<?, ?>> restrictedBeliefs = getBeliefBase().getBeliefsByType(Restricted.class);
+			for (Belief<?, ?> belief : restrictedBeliefs) {
+				PredicateBelief<Restricted> restricted = (PredicateBelief<Restricted>) belief;
+				if (restricted.getValue()) {
+					PredicateBelief<Benign> benign = (PredicateBelief<Benign>) getBeliefBase()
+							.getBelief(new Benign(restricted.getName().getVariable()));
+					if (benign != null && benign.getValue()) {
+						// Restricted(l) AND Benign(l) --> not
+						// Restricted(l)
+						goal(goalUpdateSet, restricted.getName(), false);
+					}
+				}
+			}
+
+		}
+	}
+
+	@Override
+	public void goalPerformed(GoalEvent event) {
+		if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
+			addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
+		}
+	}
+
+	@Override
+	public void reviewBeliefs() {
+		for (Link link : getLinkMonitor().getLinks()) {
+			OverUsage overUsage = new OverUsage(link);
+			if (getLinkMonitor().isOverUsage(link)) {
+				PredicateBelief<OverUsage> overUsageBelief = (PredicateBelief<OverUsage>) getBeliefBase()
+						.getBelief(overUsage);
+				if (overUsageBelief == null || !overUsageBelief.getValue()) {
+					belief(overUsage, true);
+					belief(new AnomalousUsage(link), null);
+				}
+			} else {
+				belief(overUsage, false);
+				getLinkMonitor().removeLink(link);
+			}
+		}
+
+		Set<Belief<?, ?>> overUsageCauseBeliefs = getBeliefBase().getBeliefsByType(OverUsageCause.class);
+		Iterator<Belief<?, ?>> it = overUsageCauseBeliefs.iterator();
+		while (it.hasNext()) {
+			BeliefSet<OverUsageCause, Ip> overUsageCause = (BeliefSet<OverUsageCause, Ip>) it.next();
+			if (overUsageCause.getValue().isEmpty()) {
+				removeBelief(overUsageCause);
+			}
+			PredicateBelief<AnomalousUsage> anomalousUsage = (PredicateBelief<AnomalousUsage>) getBeliefBase()
+					.getBelief(new AnomalousUsage(overUsageCause.getName().getVariable()));
+			if (anomalousUsage != null && (anomalousUsage.getValue() == null || !anomalousUsage.getValue())) {
+				removeBelief(anomalousUsage);
+			}
+		}
+
+		Set<Belief<?, ?>> benignBeliefs = getBeliefBase().getBeliefsByType(Benign.class);
+		Iterator<Belief<?, ?>> it2 = benignBeliefs.iterator();
+		while (it2.hasNext()) {
+			PredicateBelief<Benign> benignBelief = (PredicateBelief<Benign>) it2.next();
+			if (benignBelief.getValue() == null || benignBelief.getValue()) {
+				removeBelief(benignBelief);
+			}
+		}
+	}
+
+	@Override
+	public void update(Observable o, Object arg) {
+		getMyAgent().restart();
+	}
+
+}
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/palliative/Resources.java b/network-resilience/src/br/ufrgs/inf/bdinetr/palliative/Resources.java
new file mode 100644
index 0000000..9a689a8
--- /dev/null
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/palliative/Resources.java
@@ -0,0 +1,14 @@
+package br.ufrgs.inf.bdinetr.palliative;
+
+import bdi4jade.extension.palliative.NamedResource;
+import bdi4jade.extension.palliative.Resource;
+
+public interface Resources {
+
+	public static final Resource TIME = new NamedResource("TIME");
+	public static final Resource NETWORK_AVAILABILITY = new NamedResource("NETWORK_AVAILABILITY");
+	public static final Resource VULNERABILITY = new NamedResource("VULNERABILITY");
+
+	public static final Resource RESOURCES[] = { TIME, NETWORK_AVAILABILITY, VULNERABILITY };
+
+}