/**
   * Deletes a given trait from an existing entity represented by a guid.
   *
   * @param guid globally unique identifier for the entity
   * @param traitNameToBeDeleted name of the trait
   * @throws RepositoryException
   */
  @Override
  @GraphTransaction
  public void deleteTrait(String guid, String traitNameToBeDeleted)
      throws TraitNotFoundException, EntityNotFoundException, RepositoryException {
    LOG.debug("Deleting trait={} from entity={}", traitNameToBeDeleted, guid);

    Vertex instanceVertex = graphHelper.getVertexForGUID(guid);

    List<String> traitNames = GraphHelper.getTraitNames(instanceVertex);
    if (!traitNames.contains(traitNameToBeDeleted)) {
      throw new TraitNotFoundException(
          "Could not find trait="
              + traitNameToBeDeleted
              + " in the repository for entity: "
              + guid);
    }

    try {
      final String entityTypeName = GraphHelper.getTypeName(instanceVertex);
      String relationshipLabel = GraphHelper.getTraitLabel(entityTypeName, traitNameToBeDeleted);
      Edge edge = GraphHelper.getEdgeForLabel(instanceVertex, relationshipLabel);
      deleteHandler.deleteEdgeReference(edge, DataTypes.TypeCategory.TRAIT, false, true);

      // update the traits in entity once trait removal is successful
      traitNames.remove(traitNameToBeDeleted);
      updateTraits(instanceVertex, traitNames);
    } catch (Exception e) {
      throw new RepositoryException(e);
    }
  }
 public void deleteEdgeReference(
     Vertex outVertex, String edgeLabel, DataTypes.TypeCategory typeCategory, boolean isComposite)
     throws AtlasException {
   Edge edge = GraphHelper.getEdgeForLabel(outVertex, edgeLabel);
   if (edge != null) {
     deleteEdgeReference(edge, typeCategory, isComposite, false);
   }
 }
  /**
   * Delete all traits from the specified vertex.
   *
   * @param instanceVertex
   * @throws AtlasException
   */
  private void deleteAllTraits(Vertex instanceVertex) throws AtlasException {
    List<String> traitNames = GraphHelper.getTraitNames(instanceVertex);
    LOG.debug("Deleting traits {} for {}", traitNames, string(instanceVertex));
    String typeName = GraphHelper.getTypeName(instanceVertex);

    for (String traitNameToBeDeleted : traitNames) {
      String relationshipLabel = GraphHelper.getTraitLabel(typeName, traitNameToBeDeleted);
      deleteEdgeReference(instanceVertex, relationshipLabel, DataTypes.TypeCategory.TRAIT, false);
    }
  }
  /**
   * Deleting any type vertex. Goes over the complex attributes and removes the references
   *
   * @param instanceVertex
   * @throws AtlasException
   */
  protected void deleteTypeVertex(Vertex instanceVertex, boolean force) throws AtlasException {
    LOG.debug("Deleting {}", string(instanceVertex));
    String typeName = GraphHelper.getTypeName(instanceVertex);
    IDataType type = typeSystem.getDataType(IDataType.class, typeName);
    FieldMapping fieldMapping = getFieldMapping(type);

    for (AttributeInfo attributeInfo : fieldMapping.fields.values()) {
      LOG.debug("Deleting attribute {} for {}", attributeInfo.name, string(instanceVertex));
      String edgeLabel = GraphHelper.getEdgeLabel(type, attributeInfo);

      switch (attributeInfo.dataType().getTypeCategory()) {
        case CLASS:
          // If its class attribute, delete the reference
          deleteEdgeReference(
              instanceVertex, edgeLabel, DataTypes.TypeCategory.CLASS, attributeInfo.isComposite);
          break;

        case STRUCT:
          // If its struct attribute, delete the reference
          deleteEdgeReference(instanceVertex, edgeLabel, DataTypes.TypeCategory.STRUCT, false);
          break;

        case ARRAY:
          // For array attribute, if the element is struct/class, delete all the references
          IDataType elementType = ((DataTypes.ArrayType) attributeInfo.dataType()).getElemType();
          DataTypes.TypeCategory elementTypeCategory = elementType.getTypeCategory();
          if (elementTypeCategory == DataTypes.TypeCategory.STRUCT
              || elementTypeCategory == DataTypes.TypeCategory.CLASS) {
            Iterator<Edge> edges = GraphHelper.getOutGoingEdgesByLabel(instanceVertex, edgeLabel);
            if (edges != null) {
              while (edges.hasNext()) {
                Edge edge = edges.next();
                deleteEdgeReference(
                    edge, elementType.getTypeCategory(), attributeInfo.isComposite, false);
              }
            }
          }
          break;

        case MAP:
          // For map attribute, if the value type is struct/class, delete all the references
          DataTypes.MapType mapType = (DataTypes.MapType) attributeInfo.dataType();
          DataTypes.TypeCategory valueTypeCategory = mapType.getValueType().getTypeCategory();
          String propertyName = GraphHelper.getQualifiedFieldName(type, attributeInfo.name);

          if (valueTypeCategory == DataTypes.TypeCategory.STRUCT
              || valueTypeCategory == DataTypes.TypeCategory.CLASS) {
            List<String> keys = instanceVertex.getProperty(propertyName);
            if (keys != null) {
              for (String key : keys) {
                String mapEdgeLabel = GraphHelper.getQualifiedNameForMapKey(edgeLabel, key);
                deleteEdgeReference(
                    instanceVertex, mapEdgeLabel, valueTypeCategory, attributeInfo.isComposite);
              }
            }
          }
      }
    }

    deleteVertex(instanceVertex, force);
  }