diff --git a/pom.xml b/pom.xml
index a71007824..ef131c531 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
 
     com.qdesrame
     openapi-diff
-    1.2.1-SNAPSHOT
+    2.0.0-SNAPSHOT
     jar
 
     openapi-diff
diff --git a/src/main/java/com/qdesrame/openapi/diff/Main.java b/src/main/java/com/qdesrame/openapi/diff/Main.java
index 2dd52036e..7dc6b3531 100644
--- a/src/main/java/com/qdesrame/openapi/diff/Main.java
+++ b/src/main/java/com/qdesrame/openapi/diff/Main.java
@@ -131,10 +131,10 @@ public static void main(String... args) {
                 }
             }
             if (line.hasOption("state")) {
-                System.out.println(result.isDiff() ? result.isDiffBackwardCompatible() ? "compatible" : "incompatible" : "no_changes");
+                System.out.println(result.isChanged().getValue());
                 System.exit(0);
             } else {
-                System.exit(result.isDiff() ? 1 : 0);
+                System.exit(result.isUnchanged() ? 0 : 1);
             }
         } catch (ParseException e) {
             // oops, something went wrong
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ApiResponseDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/ApiResponseDiff.java
index ac2626d8b..faf5867ca 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/ApiResponseDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/ApiResponseDiff.java
@@ -2,6 +2,7 @@
 
 import com.qdesrame.openapi.diff.model.ChangedApiResponse;
 import com.qdesrame.openapi.diff.model.ChangedResponse;
+import com.qdesrame.openapi.diff.model.DiffContext;
 import io.swagger.v3.oas.models.responses.ApiResponse;
 import io.swagger.v3.oas.models.responses.ApiResponses;
 
@@ -10,6 +11,8 @@
 import java.util.Map;
 import java.util.Optional;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+
 /**
  * Created by adarsh.sharma on 04/01/18.
  */
@@ -20,19 +23,18 @@ public ApiResponseDiff(OpenApiDiff openApiDiff) {
         this.openApiDiff = openApiDiff;
     }
 
-    public Optional diff(ApiResponses left, ApiResponses right) {
+    public Optional diff(ApiResponses left, ApiResponses right, DiffContext context) {
         MapKeyDiff responseMapKeyDiff = MapKeyDiff.diff(left, right);
-        ChangedApiResponse changedApiResponse = new ChangedApiResponse(left, right);
+        ChangedApiResponse changedApiResponse = new ChangedApiResponse(left, right, context);
         changedApiResponse.setAddResponses(responseMapKeyDiff.getIncreased());
         changedApiResponse.setMissingResponses(responseMapKeyDiff.getMissing());
         List sharedResponseCodes = responseMapKeyDiff.getSharedKey();
-
         Map resps = new HashMap<>();
         for (String responseCode : sharedResponseCodes) {
-            openApiDiff.getResponseDiff().diff(left.get(responseCode), right.get(responseCode))
+            openApiDiff.getResponseDiff().diff(left.get(responseCode), right.get(responseCode), context)
                     .ifPresent(changedResponse -> resps.put(responseCode, changedResponse));
         }
         changedApiResponse.setChangedResponses(resps);
-        return changedApiResponse.isDiff() ? Optional.of(changedApiResponse) : Optional.empty();
+        return isChanged(changedApiResponse);
     }
 }
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/CacheKey.java b/src/main/java/com/qdesrame/openapi/diff/compare/CacheKey.java
new file mode 100644
index 000000000..209a1113f
--- /dev/null
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/CacheKey.java
@@ -0,0 +1,43 @@
+package com.qdesrame.openapi.diff.compare;
+
+import com.qdesrame.openapi.diff.model.DiffContext;
+import lombok.Getter;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+@Getter
+public final class CacheKey {
+    private final String left;
+    private final String right;
+    private final DiffContext context;
+
+    public CacheKey(final String left, final String right, final DiffContext context) {
+        this.left = left;
+        this.right = right;
+        this.context = context;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+
+        if (o == null || getClass() != o.getClass()) return false;
+
+        CacheKey cacheKey = (CacheKey) o;
+
+        return new EqualsBuilder()
+                .append(left, cacheKey.left)
+                .append(right, cacheKey.right)
+                .append(context, cacheKey.context)
+                .isEquals();
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder(17, 37)
+                .append(left)
+                .append(right)
+                .append(context)
+                .toHashCode();
+    }
+}
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ContentDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/ContentDiff.java
index a9754fdc5..145118065 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/ContentDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/ContentDiff.java
@@ -2,11 +2,15 @@
 
 import com.qdesrame.openapi.diff.model.ChangedContent;
 import com.qdesrame.openapi.diff.model.ChangedMediaType;
+import com.qdesrame.openapi.diff.model.DiffContext;
 import io.swagger.v3.oas.models.media.Content;
 import io.swagger.v3.oas.models.media.MediaType;
 
 import java.util.*;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isUnchanged;
+
 public class ContentDiff implements Comparable {
 
     private OpenApiDiff openApiDiff;
@@ -20,8 +24,8 @@ public boolean compare(Content left, Content right) {
         return false;
     }
 
-    public Optional diff(Content left, Content right) {
-        ChangedContent changedContent = new ChangedContent(left, right);
+    public Optional diff(Content left, Content right, DiffContext context) {
+        ChangedContent changedContent = new ChangedContent(left, right, context);
 
         MapKeyDiff mediaTypeDiff = MapKeyDiff.diff(left, right);
         changedContent.setIncreased(mediaTypeDiff.getIncreased());
@@ -31,13 +35,13 @@ public Optional diff(Content left, Content right) {
         for (String mediaTypeKey : sharedMediaTypes) {
             MediaType oldMediaType = left.get(mediaTypeKey);
             MediaType newMediaType = right.get(mediaTypeKey);
-            ChangedMediaType changedMediaType = new ChangedMediaType(oldMediaType.getSchema(), newMediaType.getSchema());
-            openApiDiff.getSchemaDiff().diff(new HashSet<>(), oldMediaType.getSchema(), newMediaType.getSchema()).ifPresent(changedMediaType::setChangedSchema);
-            if (changedMediaType.isDiff()) {
+            ChangedMediaType changedMediaType = new ChangedMediaType(oldMediaType.getSchema(), newMediaType.getSchema(), context);
+            openApiDiff.getSchemaDiff().diff(new HashSet<>(), oldMediaType.getSchema(), newMediaType.getSchema(), context).ifPresent(changedMediaType::setChangedSchema);
+            if (!isUnchanged(changedMediaType)) {
                 changedMediaTypes.put(mediaTypeKey, changedMediaType);
             }
         }
         changedContent.setChanged(changedMediaTypes);
-        return changedContent.isDiff() ? Optional.of(changedContent) : Optional.empty();
+        return isChanged(changedContent);
     }
 }
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/HeaderDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/HeaderDiff.java
index f15badf47..b2a6c6dbd 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/HeaderDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/HeaderDiff.java
@@ -1,6 +1,7 @@
 package com.qdesrame.openapi.diff.compare;
 
 import com.qdesrame.openapi.diff.model.ChangedHeader;
+import com.qdesrame.openapi.diff.model.DiffContext;
 import com.qdesrame.openapi.diff.utils.RefPointer;
 import com.qdesrame.openapi.diff.utils.RefType;
 import io.swagger.v3.oas.models.Components;
@@ -10,6 +11,8 @@
 import java.util.Objects;
 import java.util.Optional;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+
 /**
  * Created by adarsh.sharma on 28/12/17.
  */
@@ -25,26 +28,26 @@ public HeaderDiff(OpenApiDiff openApiDiff) {
         this.rightComponents = openApiDiff.getNewSpecOpenApi() != null ? openApiDiff.getNewSpecOpenApi().getComponents() : null;
     }
 
-    public Optional diff(Header left, Header right) {
-        return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref());
+    public Optional diff(Header left, Header right, DiffContext context) {
+        return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref(), context);
     }
 
     @Override
-    protected Optional computeDiff(HashSet refSet, Header left, Header right) {
+    protected Optional computeDiff(HashSet refSet, Header left, Header right, DiffContext context) {
         left = refPointer.resolveRef(leftComponents, left, left.get$ref());
         right = refPointer.resolveRef(rightComponents, right, right.get$ref());
 
-        ChangedHeader changedHeader = new ChangedHeader(left, right);
+        ChangedHeader changedHeader = new ChangedHeader(left, right, context);
 
         changedHeader.setChangeDescription(!Objects.equals(left.getDescription(), right.getDescription()));
         changedHeader.setChangeRequired(getBooleanDiff(left.getRequired(), right.getRequired()));
         changedHeader.setChangeDeprecated(!Boolean.TRUE.equals(left.getDeprecated()) && Boolean.TRUE.equals(right.getDeprecated()));
         changedHeader.setChangeStyle(!Objects.equals(left.getStyle(), right.getStyle()));
         changedHeader.setChangeExplode(getBooleanDiff(left.getExplode(), right.getExplode()));
-        openApiDiff.getSchemaDiff().diff(new HashSet<>(), left.getSchema(), right.getSchema()).ifPresent(changedHeader::setChangedSchema);
-        openApiDiff.getContentDiff().diff(left.getContent(), right.getContent()).ifPresent(changedHeader::setChangedContent);
+        openApiDiff.getSchemaDiff().diff(new HashSet<>(), left.getSchema(), right.getSchema(), context).ifPresent(changedHeader::setChangedSchema);
+        openApiDiff.getContentDiff().diff(left.getContent(), right.getContent(), context).ifPresent(changedHeader::setChangedContent);
 
-        return changedHeader.isDiff() ? Optional.of(changedHeader) : Optional.empty();
+        return isChanged(changedHeader);
     }
 
     private boolean getBooleanDiff(Boolean left, Boolean right) {
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/HeadersDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/HeadersDiff.java
index 58c990dcf..9e39a0306 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/HeadersDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/HeadersDiff.java
@@ -2,6 +2,7 @@
 
 import com.qdesrame.openapi.diff.model.ChangedHeader;
 import com.qdesrame.openapi.diff.model.ChangedHeaders;
+import com.qdesrame.openapi.diff.model.DiffContext;
 import io.swagger.v3.oas.models.headers.Header;
 
 import java.util.HashMap;
@@ -9,6 +10,8 @@
 import java.util.Map;
 import java.util.Optional;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+
 /**
  * Created by adarsh.sharma on 28/12/17.
  */
@@ -19,8 +22,8 @@ public HeadersDiff(OpenApiDiff openApiDiff) {
         this.openApiDiff = openApiDiff;
     }
 
-    public Optional diff(Map left, Map right) {
-        ChangedHeaders changedHeaders = new ChangedHeaders(left, right);
+    public Optional diff(Map left, Map right, DiffContext context) {
+        ChangedHeaders changedHeaders = new ChangedHeaders(left, right, context);
         MapKeyDiff headerMapDiff = MapKeyDiff.diff(left, right);
         changedHeaders.setIncreased(headerMapDiff.getIncreased());
         changedHeaders.setMissing(headerMapDiff.getMissing());
@@ -30,11 +33,11 @@ public Optional diff(Map left, Map changed.put(headerKey, changedHeader));
         }
         changedHeaders.setChanged(changed);
 
-        return changedHeaders.isDiff() ? Optional.of(changedHeaders) : Optional.empty();
+        return isChanged(changedHeaders);
     }
 }
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowDiff.java
index 52a07326f..68d5d2cc0 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowDiff.java
@@ -6,6 +6,8 @@
 import java.util.Objects;
 import java.util.Optional;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+
 /**
  * Created by adarsh.sharma on 12/01/18.
  */
@@ -24,6 +26,6 @@ public Optional diff(OAuthFlow left, OAuthFlow right) {
             changedOAuthFlow.setChangedRefreshUrl(!Objects.equals(left.getRefreshUrl(), right.getRefreshUrl()));
         }
 
-        return changedOAuthFlow.isDiff() ? Optional.of(changedOAuthFlow) : Optional.empty();
+        return isChanged(changedOAuthFlow);
     }
 }
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowsDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowsDiff.java
index 5a83b714e..ae3235a11 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowsDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowsDiff.java
@@ -5,6 +5,8 @@
 
 import java.util.Optional;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+
 /**
  * Created by adarsh.sharma on 12/01/18.
  */
@@ -23,6 +25,6 @@ public Optional diff(OAuthFlows left, OAuthFlows right) {
             openApiDiff.getoAuthFlowDiff().diff(left.getClientCredentials(), right.getClientCredentials()).ifPresent(changedOAuthFlows::setChangedClientCredentialOAuthFlow);
             openApiDiff.getoAuthFlowDiff().diff(left.getAuthorizationCode(), right.getAuthorizationCode()).ifPresent(changedOAuthFlows::setChangedAuthorizationCodeOAuthFlow);
         }
-        return changedOAuthFlows.isDiff() ? Optional.of(changedOAuthFlows) : Optional.empty();
+        return isChanged(changedOAuthFlows);
     }
 }
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/OperationDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/OperationDiff.java
index 8f1c30874..5e17ecc05 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/OperationDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/OperationDiff.java
@@ -2,14 +2,16 @@
 
 import com.qdesrame.openapi.diff.model.ChangedOperation;
 import com.qdesrame.openapi.diff.model.ChangedParameters;
+import com.qdesrame.openapi.diff.model.DiffContext;
 import io.swagger.v3.oas.models.Operation;
-import io.swagger.v3.oas.models.PathItem;
 import io.swagger.v3.oas.models.parameters.Parameter;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+
 /**
  * Created by adarsh.sharma on 04/01/18.
  */
@@ -20,34 +22,34 @@ public OperationDiff(OpenApiDiff openApiDiff) {
         this.openApiDiff = openApiDiff;
     }
 
-    public Optional diff(String pathUrl, PathItem.HttpMethod method, Map pathParameters, Operation oldOperation, Operation newOperation) {
-        ChangedOperation changedOperation = new ChangedOperation(pathUrl, method, oldOperation, newOperation);
+    public Optional diff(Operation oldOperation, Operation newOperation, DiffContext context) {
+        ChangedOperation changedOperation = new ChangedOperation(context.getUrl(), context.getMethod(), oldOperation, newOperation);
 
         changedOperation.setSummary(newOperation.getSummary());
         changedOperation.setDeprecated(!Boolean.TRUE.equals(oldOperation.getDeprecated()) && Boolean.TRUE.equals(newOperation.getDeprecated()));
 
         if (oldOperation.getRequestBody() != null || newOperation.getRequestBody() != null) {
-            openApiDiff.getRequestBodyDiff().diff(oldOperation.getRequestBody(), newOperation.getRequestBody())
+            openApiDiff.getRequestBodyDiff().diff(oldOperation.getRequestBody(), newOperation.getRequestBody(), context.copyAsRequest())
                     .ifPresent(changedOperation::setChangedRequestBody);
         }
 
-        openApiDiff.getParametersDiff().diff(oldOperation.getParameters(), newOperation.getParameters())
+        openApiDiff.getParametersDiff().diff(oldOperation.getParameters(), newOperation.getParameters(), context)
                 .ifPresent(params -> {
-                    removePathParameters(pathParameters, params);
+                    removePathParameters(context.getParameters(), params);
                     changedOperation.setChangedParameters(params);
                 });
 
         if (oldOperation.getResponses() != null || newOperation.getResponses() != null) {
-            openApiDiff.getApiResponseDiff().diff(oldOperation.getResponses(), newOperation.getResponses())
+            openApiDiff.getApiResponseDiff().diff(oldOperation.getResponses(), newOperation.getResponses(), context.copyAsResponse())
                     .ifPresent(changedOperation::setChangedApiResponse);
         }
 
         if (oldOperation.getSecurity() != null || newOperation.getSecurity() != null) {
-            openApiDiff.getSecurityRequirementsDiff().diff(oldOperation.getSecurity(), newOperation.getSecurity())
+            openApiDiff.getSecurityRequirementsDiff().diff(oldOperation.getSecurity(), newOperation.getSecurity(), context)
                     .ifPresent(changedOperation::setChangedSecurityRequirements);
         }
 
-        return changedOperation.isDiff() ? Optional.of(changedOperation) : Optional.empty();
+        return isChanged(changedOperation);
     }
 
     public void removePathParameters(Map pathParameters, ChangedParameters params) {
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ParameterDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/ParameterDiff.java
index 7cea0df62..25bdedb69 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/ParameterDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/ParameterDiff.java
@@ -2,6 +2,7 @@
 
 import com.qdesrame.openapi.diff.model.ChangedParameter;
 import com.qdesrame.openapi.diff.model.ChangedSchema;
+import com.qdesrame.openapi.diff.model.DiffContext;
 import com.qdesrame.openapi.diff.utils.RefPointer;
 import com.qdesrame.openapi.diff.utils.RefType;
 import io.swagger.v3.oas.models.Components;
@@ -11,6 +12,8 @@
 import java.util.Objects;
 import java.util.Optional;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+
 public class ParameterDiff extends ReferenceDiffCache {
 
     private Components leftComponents;
@@ -24,13 +27,13 @@ public ParameterDiff(OpenApiDiff openApiDiff) {
         this.rightComponents = openApiDiff.getNewSpecOpenApi() != null ? openApiDiff.getNewSpecOpenApi().getComponents() : null;
     }
 
-    public Optional diff(Parameter left, Parameter right) {
-        return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref());
+    public Optional diff(Parameter left, Parameter right, DiffContext context) {
+        return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref(), context);
     }
 
     @Override
-    protected Optional computeDiff(HashSet refSet, Parameter left, Parameter right) {
-        ChangedParameter changedParameter = new ChangedParameter(right.getName(), right.getIn());
+    protected Optional computeDiff(HashSet refSet, Parameter left, Parameter right, DiffContext context) {
+        ChangedParameter changedParameter = new ChangedParameter(right.getName(), right.getIn(), context);
         left = refPointer.resolveRef(this.leftComponents, left, left.get$ref());
         right = refPointer.resolveRef(this.rightComponents, right, right.get$ref());
 
@@ -43,14 +46,14 @@ protected Optional computeDiff(HashSet refSet, Paramet
         changedParameter.setChangeAllowEmptyValue(getBooleanDiff(left.getAllowEmptyValue(), right.getAllowEmptyValue()));
         changedParameter.setChangeStyle(!Objects.equals(left.getStyle(), right.getStyle()));
         changedParameter.setChangeExplode(getBooleanDiff(left.getExplode(), right.getExplode()));
-        Optional changedSchema = openApiDiff.getSchemaDiff().diff(refSet, left.getSchema(), right.getSchema());
+        Optional changedSchema = openApiDiff.getSchemaDiff().diff(refSet, left.getSchema(), right.getSchema(), context);
         if (changedSchema.isPresent()) {
             changedParameter.setChangedSchema(changedSchema.get());
         }
-        openApiDiff.getContentDiff().diff(left.getContent(), right.getContent())
+        openApiDiff.getContentDiff().diff(left.getContent(), right.getContent(), context)
                 .ifPresent(changedParameter::setChangedContent);
 
-        return changedParameter.isDiff() ? Optional.of(changedParameter) : Optional.empty();
+        return isChanged(changedParameter);
     }
 
     private boolean getBooleanDiff(Boolean left, Boolean right) {
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ParametersDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/ParametersDiff.java
index 12009be19..f2c50c7c7 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/ParametersDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/ParametersDiff.java
@@ -1,6 +1,7 @@
 package com.qdesrame.openapi.diff.compare;
 
 import com.qdesrame.openapi.diff.model.ChangedParameters;
+import com.qdesrame.openapi.diff.model.DiffContext;
 import com.qdesrame.openapi.diff.utils.RefPointer;
 import com.qdesrame.openapi.diff.utils.RefType;
 import io.swagger.v3.oas.models.Components;
@@ -11,6 +12,8 @@
 import java.util.Objects;
 import java.util.Optional;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+
 /**
  * compare two parameter
  *
@@ -37,8 +40,8 @@ public static boolean same(Parameter left, Parameter right) {
         return Objects.equals(left.getName(), right.getName()) && Objects.equals(left.getIn(), right.getIn());
     }
 
-    public Optional diff(List left, List right) {
-        ChangedParameters changedParameters = new ChangedParameters(left, right != null ? new ArrayList<>(right) : null);
+    public Optional diff(List left, List right, DiffContext context) {
+        ChangedParameters changedParameters = new ChangedParameters(left, right != null ? new ArrayList<>(right) : null, context);
         if (null == left) left = new ArrayList<>();
         if (null == right) right = new ArrayList<>();
 
@@ -51,11 +54,11 @@ public Optional diff(List left, List ri
             } else {
                 Parameter rightPara = rightParam.get();
                 right.remove(rightPara);
-                openApiDiff.getParameterDiff().diff(leftPara, rightPara).ifPresent(changedParameters.getChanged()::add);
+                openApiDiff.getParameterDiff().diff(leftPara, rightPara, context).ifPresent(changedParameters.getChanged()::add);
             }
         }
         changedParameters.getIncreased().addAll(right);
 
-        return changedParameters.isDiff() ? Optional.of(changedParameters) : Optional.empty();
+        return isChanged(changedParameters);
     }
 }
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/PathDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/PathDiff.java
index 73a9d59ad..883a43611 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/PathDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/PathDiff.java
@@ -1,6 +1,7 @@
 package com.qdesrame.openapi.diff.compare;
 
 import com.qdesrame.openapi.diff.model.ChangedPath;
+import com.qdesrame.openapi.diff.model.DiffContext;
 import io.swagger.v3.oas.models.Operation;
 import io.swagger.v3.oas.models.PathItem;
 
@@ -8,6 +9,8 @@
 import java.util.Map;
 import java.util.Optional;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+
 public class PathDiff {
     private OpenApiDiff openApiDiff;
 
@@ -15,8 +18,8 @@ public PathDiff(OpenApiDiff openApiDiff) {
         this.openApiDiff = openApiDiff;
     }
 
-    public Optional diff(String pathUrl, Map pathParameters, PathItem left, PathItem right) {
-        ChangedPath changedPath = new ChangedPath(pathUrl, left, right);
+    public Optional diff(PathItem left, PathItem right, DiffContext context) {
+        ChangedPath changedPath = new ChangedPath(context.getUrl(), left, right, context);
 
         Map oldOperationMap = left.readOperationsMap();
         Map newOperationMap = right.readOperationsMap();
@@ -28,8 +31,8 @@ public Optional diff(String pathUrl, Map pathParame
         for (PathItem.HttpMethod method : sharedMethods) {
             Operation oldOperation = oldOperationMap.get(method);
             Operation newOperation = newOperationMap.get(method);
-            openApiDiff.getOperationDiff().diff(pathUrl, method, pathParameters, oldOperation, newOperation).ifPresent(changedPath.getChanged()::add);
+            openApiDiff.getOperationDiff().diff(oldOperation, newOperation, context.copyWithMethod(method)).ifPresent(changedPath.getChanged()::add);
         }
-        return changedPath.isDiff() ? Optional.of(changedPath) : Optional.empty();
+        return isChanged(changedPath);
     }
 }
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/PathsDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/PathsDiff.java
index 724b83c09..731d3f113 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/PathsDiff.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/PathsDiff.java
@@ -1,6 +1,7 @@
 package com.qdesrame.openapi.diff.compare;
 
 import com.qdesrame.openapi.diff.model.ChangedPaths;
+import com.qdesrame.openapi.diff.model.DiffContext;
 import io.swagger.v3.oas.models.PathItem;
 import io.swagger.v3.oas.models.Paths;
 
@@ -8,6 +9,8 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
+
 public class PathsDiff {
     private static final String REGEX_PATH = "\\{([^/]+)\\}";
     private OpenApiDiff openApiDiff;
@@ -50,12 +53,15 @@ public Optional diff(final Map left, final Map changedPaths.getChanged().put(result.get(), path));
+                DiffContext context = new DiffContext();
+                context.setUrl(url);
+                context.setParameters(params);
+                openApiDiff.getPathDiff().diff(leftPath, rightPath, context).ifPresent(path -> changedPaths.getChanged().put(result.get(), path));
             } else {
                 changedPaths.getMissing().put(url, leftPath);
             }
         });
-        return changedPaths.isDiff() ? Optional.of(changedPaths) : Optional.empty();
+        return isChanged(changedPaths);
     }
 
     public static Paths valOrEmpty(Paths path) {
diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ReferenceDiffCache.java b/src/main/java/com/qdesrame/openapi/diff/compare/ReferenceDiffCache.java
index 53a61a22c..7458e93ff 100644
--- a/src/main/java/com/qdesrame/openapi/diff/compare/ReferenceDiffCache.java
+++ b/src/main/java/com/qdesrame/openapi/diff/compare/ReferenceDiffCache.java
@@ -1,5 +1,7 @@
 package com.qdesrame.openapi.diff.compare;
 
+import com.qdesrame.openapi.diff.model.DiffContext;
+
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -9,49 +11,41 @@
  * Created by adarsh.sharma on 07/01/18.
  */
 public abstract class ReferenceDiffCache {
-    private Map> refDiffMap;
+    private Map refDiffMap;
 
     public ReferenceDiffCache() {
         this.refDiffMap = new HashMap<>();
     }
 
-    private Optional getFromCache(String leftRef, String rightRef) {
-        Optional