Force delete is used to remove struct/trait in case of entity updates
@param edge
@param typeCategory
@param isComposite
@param forceDeleteStructTrait
@return returns true if the edge reference is hard deleted
@throws AtlasException
968666
public boolean deleteEdgeReference(AtlasEdge edge, DataTypes.TypeCategory typeCategory, boolean isComposite,
                                    boolean forceDeleteStructTrait) throws AtlasException {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Deleting {}", string(edge));
        }

        boolean forceDelete =
                (typeCategory == DataTypes.TypeCategory.STRUCT || typeCategory == DataTypes.TypeCategory.TRAIT) && forceDeleteStructTrait;
        if (typeCategory == DataTypes.TypeCategory.STRUCT || typeCategory == DataTypes.TypeCategory.TRAIT
                || (typeCategory == DataTypes.TypeCategory.CLASS && isComposite)) {
            //If the vertex is of type struct/trait, delete the edge and then the reference vertex as the vertex is not shared by any other entities.
            //If the vertex is of type class, and its composite attribute, this reference vertex' lifecycle is controlled
            //through this delete, hence delete the edge and the reference vertex.
            AtlasVertex vertexForDelete = edge.getInVertex();

            //If deleting the edge and then the in vertex, reverse attribute shouldn't be updated
            deleteEdge(edge, false, forceDelete);
            deleteTypeVertex(vertexForDelete, typeCategory, forceDelete);
        } else {
            //If the vertex is of type class, and its not a composite attributes, the reference AtlasVertex' lifecycle is not controlled
            //through this delete. Hence just remove the reference edge. Leave the reference AtlasVertex as is

            //If deleting just the edge, reverse attribute should be updated for any references
            //For example, for the department type system, if the person's manager edge is deleted, subordinates of manager should be updated
            deleteEdge(edge, true, false);
        }
        return !softDelete || forceDelete;
    }
1221254
public void delCacheEntry(ValueSet removeList, int cause, int source, boolean fromDepIdTemplateInvalidation, boolean fireEvent) {
        htod.delCacheEntry(removeList, cause, source, fromDepIdTemplateInvalidation, fireEvent);
    }
160437
public static void unlink(final ODatabaseGraphTx iDatabase, final ODocument iSourceVertex, final ODocument iTargetVertex) {
		if (iTargetVertex == null)
			throw new IllegalArgumentException("Missed the target vertex");

		if (iDatabase.existsUserObjectByRID(iSourceVertex.getIdentity())) {
			// WORK ALSO WITH IN MEMORY OBJECTS

			final OGraphVertex vertex = (OGraphVertex) iDatabase.getUserObjectByRecord(iSourceVertex, null);
			// REMOVE THE EDGE OBJECT
			if (vertex.out != null) {
				final Set<OGraphEdge> obj = vertex.out.get();
				if (obj != null)
					for (OGraphEdge e : obj)
						if (e.getIn().getDocument().equals(iTargetVertex))
							obj.remove(e);
			}
		}

		if (iDatabase.existsUserObjectByRID(iTargetVertex.getIdentity())) {
			// WORK ALSO WITH IN MEMORY OBJECTS

			final OGraphVertex vertex = (OGraphVertex) iDatabase.getUserObjectByRecord(iTargetVertex, null);
			// REMOVE THE EDGE OBJECT FROM THE TARGET VERTEX
			if (vertex.in != null) {
				final Set<OGraphEdge> obj = vertex.in.get();
				if (obj != null)
					for (OGraphEdge e : obj)
						if (e.getOut().getDocument().equals(iSourceVertex))
							obj.remove(e);
			}
		}

		final List<ODocument> edges2Remove = new ArrayList<ODocument>();

		// REMOVE THE EDGE DOCUMENT
		ODocument edge = null;
		Set<ODocument> docs = iSourceVertex.field(OGraphDatabase.VERTEX_FIELD_OUT);
		if (docs != null) {
			// USE A TEMP ARRAY TO AVOID CONCURRENT MODIFICATION TO THE ITERATOR
			for (OIdentifiable d : docs) {
				final ODocument doc = (ODocument) d.getRecord();
				if (doc.field(OGraphDatabase.EDGE_FIELD_IN).equals(iTargetVertex)) {
					edges2Remove.add(doc);
					edge = doc;
				}
			}

			for (ODocument d : edges2Remove)
				docs.remove(d);
		}

		if (edge == null)
			throw new OGraphException("Edge not found between the ougoing edges");

		iSourceVertex.setDirty();
		iSourceVertex.save();

		docs = iTargetVertex.field(OGraphDatabase.VERTEX_FIELD_IN);

		// REMOVE THE EDGE DOCUMENT FROM THE TARGET VERTEX
		if (docs != null) {
			edges2Remove.clear();

			for (OIdentifiable d : docs) {
				final ODocument doc = (ODocument) d.getRecord();
				if (doc.field(OGraphDatabase.EDGE_FIELD_IN).equals(iTargetVertex))
					edges2Remove.add(doc);
			}

			for (ODocument d : edges2Remove)
				docs.remove(d);
		}

		iTargetVertex.setDirty();
		iTargetVertex.save();

		edge.delete();
	}
522293
@Override
    public void forceInsert(RevisionInternal inRev,
                            List<String> inHistory,
                            final StorageValidation validationBlock,
                            URL inSource)
            throws CouchbaseLiteException {
        if (readOnly)
            throw new CouchbaseLiteException(Status.FORBIDDEN);

        final byte[] json = inRev.getJson();
        if (json == null)
            throw new CouchbaseLiteException(Status.BAD_JSON);

        final RevisionInternal rev = inRev.copy();
        final List<String> history = inHistory;
        final URL source = inSource;

        final DocumentChange[] change = new DocumentChange[1];

        // TODO: need to implement JNI for c4doc_put()
        Status status = inTransaction(new Task() {
            @Override
            public Status run() {
                try {
                    // First get the CBForest doc:
                    Document doc = getDocumentWithRetry(rev.getDocID(), false, 5);
                    try {
                        int common = doc.insertRevisionWithHistory(
                                json,
                                rev.isDeleted(),
                                rev.getAttachments() != null,
                                history.toArray(new String[history.size()]));
                        if (common < 0)
                            // generation numbers not in descending order
                            return new Status(Status.BAD_REQUEST);
                        else if (common == 0)
                            // No-op: No new revisions were inserted.
                            return new Status(Status.OK);
                        // Validate against the common ancestor:
                        if (validationBlock != null) {
                            RevisionInternal prev = null;
                            if (common < history.size()) {
                                String revID = history.get(common);
                                if (!doc.selectRevID(revID, false)) {
                                    Log.w(TAG, "Unable to select RevID: " + revID);
                                    return new Status(Status.BAD_REQUEST);
                                }
                                prev = new RevisionInternal(rev.getDocID(), revID, doc.deleted());
                            }
                            String parentRevID = (history.size() > 1) ? history.get(1) : null;
                            Status status = validationBlock.validate(rev, prev, parentRevID);
                            if (status.isError())
                                return status;
                        }
                        // Save updated doc back to the database:
                        boolean isWinner = saveForest(doc, history.get(0), rev.getProperties());
                        rev.setSequence(doc.getSelectedSequence());
                        change[0] = changeWithNewRevision(rev, isWinner, doc, source);
                        return new Status(Status.CREATED);
                    } finally {
                        doc.free();
                    }
                } catch (ForestException e) {
                    Log.e(TAG, "ForestDB Error: forceInsert()", e);
                    return new Status(Status.UNKNOWN);
                }
            }
        });

        if (change[0] != null)
            delegate.databaseStorageChanged(change[0]);

        if (status.isError())
            throw new CouchbaseLiteException(status.getCode());
    }
339162
public void deleteBulkDocsAsync(String index, String type,
            QueryBuilder filterQueryBuilder) {
        executeBulkRequestAsync(buildDeleteBulkRequestBuilder(
                buildExtractDeleteRequestBuilderList(index, type,
                        filterQueryBuilder)));
    }
480312
@MustBeLocked (ELockType.WRITE)
  protected final void internalMarkItemUndeleted (@Nonnull final IMPLTYPE aItem)
  {
    internalMarkItemUndeleted (aItem, true);
  }
670949
private ObjectNode objectNodeFromElement(final AtlasElement element) {
        final boolean isEdge = element instanceof AtlasEdge;
        final boolean showTypes = mode == AtlasGraphSONMode.EXTENDED;
        final List<String> propertyKeys = isEdge ? this.edgePropertyKeys : this.vertexPropertyKeys;
        final ElementPropertiesRule elementPropertyConfig = isEdge ? this.edgePropertiesRule
                : this.vertexPropertiesRule;

        final ObjectNode jsonElement = createJSONMap(
                createPropertyMap(element, propertyKeys, elementPropertyConfig, normalized), propertyKeys, showTypes);

        if ((isEdge && this.includeReservedEdgeId) || (!isEdge && this.includeReservedVertexId)) {
            putObject(jsonElement, AtlasGraphSONTokens.INTERNAL_ID, element.getId());
        }

        // it's important to keep the order of these straight.  check AtlasEdge first and then AtlasVertex because there
        // are graph implementations that have AtlasEdge extend from AtlasVertex
        if (element instanceof AtlasEdge) {
            final AtlasEdge edge = (AtlasEdge) element;

            if (this.includeReservedEdgeId) {
                putObject(jsonElement, AtlasGraphSONTokens.INTERNAL_ID, element.getId());
            }

            if (this.includeReservedEdgeType) {
                jsonElement.put(AtlasGraphSONTokens.INTERNAL_TYPE, AtlasGraphSONTokens.EDGE);
            }

            if (this.includeReservedEdgeOutV) {
                putObject(jsonElement, AtlasGraphSONTokens.INTERNAL_OUT_V, edge.getOutVertex().getId());
            }

            if (this.includeReservedEdgeInV) {
                putObject(jsonElement, AtlasGraphSONTokens.INTERNAL_IN_V, edge.getInVertex().getId());
            }

            if (this.includeReservedEdgeLabel) {
                jsonElement.put(AtlasGraphSONTokens.INTERNAL_LABEL, edge.getLabel());
            }
        } else if (element instanceof AtlasVertex) {
            if (this.includeReservedVertexId) {
                putObject(jsonElement, AtlasGraphSONTokens.INTERNAL_ID, element.getId());
            }

            if (this.includeReservedVertexType) {
                jsonElement.put(AtlasGraphSONTokens.INTERNAL_TYPE, AtlasGraphSONTokens.VERTEX);
            }
        }

        return jsonElement;
    }
1122982
@Override
    public void validateUpdate(IDataType newType) throws TypeUpdateException {
        super.validateUpdate(newType);

        StructType newStructType = (StructType) newType;
        try {
            TypeUtils.validateUpdate(fieldMapping, newStructType.fieldMapping);
        } catch (TypeUpdateException e) {
            throw new TypeUpdateException(newType, e);
        }
    }
975320
private AtlasEdge addOrUpdateClassVertex(AtlasVertex instanceVertex, AtlasEdge currentEdge,
            ITypedReferenceableInstance newAttributeValue, AttributeInfo attributeInfo,
            String edgeLabel) throws AtlasException {
        AtlasVertex newReferenceVertex = getClassVertex(newAttributeValue);
        if( ! GraphHelper.elementExists(newReferenceVertex) && newAttributeValue != null) {
            LOG.error("Could not find vertex for Class Reference {}", newAttributeValue);
            throw new EntityNotFoundException("Could not find vertex for Class Reference " + newAttributeValue);
        }

        AtlasEdge newEdge = null;
        if (GraphHelper.elementExists(currentEdge) && newAttributeValue != null) {
            newEdge = updateClassEdge(instanceVertex, currentEdge, newAttributeValue, newReferenceVertex,
                    attributeInfo, edgeLabel);
        } else if (! GraphHelper.elementExists(currentEdge) && newAttributeValue != null){
            newEdge = addClassEdge(instanceVertex, newReferenceVertex, edgeLabel);

        }
        return newEdge;
    }
607436
void mapTraitInstanceToVertex(ITypedStruct traitInstance, IDataType entityType, AtlasVertex parentInstanceVertex)
            throws AtlasException {
        // add a new AtlasVertex for the struct or trait instance
        final String traitName = traitInstance.getTypeName();
        AtlasVertex traitInstanceVertex = graphHelper.createVertexWithoutIdentity(traitInstance.getTypeName(), null,
                typeSystem.getDataType(TraitType.class, traitName).getAllSuperTypeNames());
        if (LOG.isDebugEnabled()) {
            LOG.debug("created vertex {} for trait {}", string(traitInstanceVertex), traitName);
        }

        // map all the attributes to this newly created AtlasVertex
        mapInstanceToVertex(traitInstance, traitInstanceVertex, traitInstance.fieldMapping().fields, false, Operation.CREATE);

        // add an edge to the newly created AtlasVertex from the parent
        String relationshipLabel = GraphHelper.getTraitLabel(entityType.getName(), traitName);
        graphHelper.getOrCreateEdge(parentInstanceVertex, traitInstanceVertex, relationshipLabel);
    }
801848
public static Specification<JpaDistributionSetType> isDeleted(final Boolean isDeleted) {
        return (targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(JpaDistributionSetType_.deleted),
                isDeleted);
    }
1365396
protected void fireLayerRemovedEvent(MapLayer layer, int oldChildIndex) {
		fireLayerHierarchyChangedEvent(new MapLayerHierarchyEvent(
				this, layer, Type.REMOVE_CHILD, oldChildIndex, layer.isTemporaryLayer()));
	}
756884
private List<AtlasEdge> removeUnusedArrayEntries(AtlasAttribute attribute, List<AtlasEdge> currentEntries, List<AtlasEdge> newEntries) throws AtlasBaseException {
        if (CollectionUtils.isNotEmpty(currentEntries)) {
            AtlasType entryType = ((AtlasArrayType) attribute.getAttributeType()).getElementType();

            if (AtlasGraphUtilsV1.isReference(entryType)) {
                Collection<AtlasEdge> edgesToRemove = CollectionUtils.subtract(currentEntries, newEntries);

                if (CollectionUtils.isNotEmpty(edgesToRemove)) {
                    List<AtlasEdge> additionalElements = new ArrayList<>();

                    for (AtlasEdge edge : edgesToRemove) {
                        boolean deleted = deleteHandler.deleteEdgeReference(edge, entryType.getTypeCategory(), attribute.isOwnedRef(),
                                                                             true, attribute.getRelationshipEdgeDirection());

                        if (!deleted) {
                            additionalElements.add(edge);
                        }
                    }

                    return additionalElements;
                }
            }
        }

        return Collections.emptyList();
    }
1014467
private AtlasEdge addOrUpdateStruct(AtlasVertex instanceVertex, AttributeInfo attributeInfo,
            ITypedStruct newAttributeValue, AtlasEdge currentEdge,
            String edgeLabel, Operation operation) throws AtlasException {
        AtlasEdge newEdge = null;
        if (GraphHelper.elementExists(currentEdge) && newAttributeValue != null) {
            //update
            updateStructVertex(newAttributeValue, currentEdge, operation);
            newEdge = currentEdge;
        } else if (! GraphHelper.elementExists(currentEdge) && newAttributeValue != null) {
            //add
            newEdge = addStructVertex(newAttributeValue, instanceVertex, attributeInfo, edgeLabel);
        }
        return newEdge;
    }
310813
public void deleteBulkDocsAsync(String index, String type,
            ActionListener<BulkResponse> bulkResponseActionListener) {
        executeBulkRequestAsync(
                buildDeleteBulkRequestBuilder(
                        buildAllDeleteRequestBuilderList(index, type)),
                bulkResponseActionListener);
    }
1295474
@DELETE
    @Path("/guid/{guid}/classification/{classificationName}")
    @Produces(Servlets.JSON_MEDIA_TYPE)
    public void deleteClassification(@PathParam("guid") String guid,
                                     @PathParam("classificationName") final String classificationName) throws AtlasBaseException {
        AtlasPerfTracer perf = null;

        try {
            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityREST.deleteClassification(" + guid + "," + classificationName + ")");
            }

            if (StringUtils.isEmpty(guid)) {
                throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
            }

            ensureClassificationType(classificationName);

            entitiesStore.deleteClassifications(guid, new ArrayList<String>() {{ add(classificationName);}} );
        } finally {
            AtlasPerfTracer.log(perf);
        }
    }
1261469
void removeReferences( Vertex remove , EdgeType type ) {
		EdgeSet removeSet = remove.getEdgeSet(type);
		for (int i = removeSet.size()-1; i >= 0; i--) {
			Vertex v = removeSet.get(i).dst;
			EdgeSet setV = v.getEdgeSet(type);
			// remove the connection from v to 'remove'. Be careful since the connection isn't always mutual
			// at this point
			int ridx = setV.find(remove);
			if( ridx != -1 )
				setV.edges.remove(ridx);
		}
		removeSet.reset();
	}