APIdia Launch Partner
Top Description Inners Fields Constructors Methods
javax.swing.text

public Class GapContent

extends GapVector
implements Content, Serializable
Class Inheritance
All Implemented Interfaces
java.io.Serializable, javax.swing.text.AbstractDocument.Content
Annotations
@SuppressWarnings:serial
Imports
java.io.Serial, .IOException, .ObjectInputStream, .Serializable, java.util.Arrays, .Vector, javax.swing.undo.AbstractUndoableEdit, .CannotRedoException, .CannotUndoException, .UndoableEdit, javax.swing.SwingUtilities, java.lang.ref.WeakReference, .ReferenceQueue

An implementation of the AbstractDocument.Content interface implemented using a gapped buffer similar to that used by emacs. The underlying storage is an array of Unicode characters with a gap somewhere. The gap is moved to the location of changes to take advantage of common behavior where most changes are in the same location. Changes that occur at a gap boundary are generally cheap and moving the gap is generally cheaper than moving the array contents directly to accommodate the change.

The positions tracking change are also generally cheap to maintain. The Position implementations (marks) store the array index and can easily calculate the sequential position from the current gap location. Changes only require updating the marks between the old and new gap boundaries when the gap is moved, so generally updating the marks is pretty cheap. The marks are stored sorted so they can be located quickly with a binary search. This increases the cost of adding a mark, and decreases the cost of keeping the mark updated.

Author
Timothy Prinzing

Nested and Inner Type Summary

Modifier and TypeClass and Description
pack-priv class
GapContent.InsertUndo

UnoableEdit created for inserts.

pack-priv class
GapContent.MarkData

Holds the data for a mark...

pack-priv static class
pack-priv class
GapContent.RemoveUndo

UndoableEdit created for removes.

pack-priv class
pack-priv class
GapContent.UndoPosRef

Used to hold a reference to a Mark that is being reset as the result of removing from the content.

Field Summary

Modifier and TypeField and Description
private static final char[]
pack-priv static final int
private transient GapContent.MarkVector
private transient ReferenceQueue<GapContent.StickyPosition>
private transient GapContent.MarkData
search

Record used for searching for the place to start updating mark indexes when the gap boundaries are moved.

private transient int
unusedMarks

The number of unused mark entries

Constructor Summary

AccessConstructor and Description
public
GapContent()

Creates a new GapContent object.

public
GapContent(int
the initial size
initialLength
)

Creates a new GapContent object, with the initial size specified.

Method Summary

Modifier and TypeMethod and Description
protected Object
allocateArray(int len)

Implements abstract javax.swing.text.GapVector.allocateArray.

Allocate an array to store items of the type appropriate (which is determined by the subclass).

pack-priv final int

Returns:

< 0 if o1 < o2, 0 if the same, > 0 if o1 > o2
compare
(GapContent.MarkData
the first object
o1
,
GapContent.MarkData
the second object
o2
)

Compares two marks.

public Position

Returns:

the position
createPosition
(int
the offset to track >= 0
offset
)

Implements javax.swing.text.AbstractDocument.Content.createPosition.

Creates a position within the content that will track change as the content is mutated.

pack-priv final int
findMarkAdjustIndex(int searchIndex)

Finds the index to start mark adjustments given some search index.

pack-priv final int

Returns:

the index
findSortIndex
(GapContent.MarkData
the mark to insert
o
)

Finds the index of where to insert a new mark.

protected int
getArrayLength()

Implements abstract javax.swing.text.GapVector.getArrayLength.

Get the length of the allocated array.

public void
getChars(int
the starting position >= 0, where + len <= length()
where
,
int
the number of characters to retrieve >= 0
len
,
Segment
the Segment object to return the characters in
chars
)

Implements javax.swing.text.AbstractDocument.Content.getChars.

Retrieves a portion of the content.

pack-priv int
getNewArraySize(int reqSize)

Overrides javax.swing.text.GapVector.getNewArraySize.

Overridden to make growth policy less aggressive for large text amount.

protected Vector<E>

Returns:

the set of instances
getPositionsInRange
(Vector<E>
the Vector to use, with a new one created on null
v
,
int
the starting offset >= 0
offset
,
int
the length >= 0
length
)

Returns a Vector containing instances of UndoPosRef for the Positions in the range offset to offset + length.

public String

Returns:

a string representing the content
getString
(int
the starting position >= 0
where
,
int
the length to retrieve >= 0
len
)

Implements javax.swing.text.AbstractDocument.Content.getString.

Retrieves a portion of the content.

public UndoableEdit

Returns:

an UndoableEdit object for undoing
insertString
(int
the starting position >= 0, < length()
where
,
String
the non-null string to insert
str
)

Implements javax.swing.text.AbstractDocument.Content.insertString.

Inserts a string into the content.

public int

Returns:

the length >= 1
length
()

Implements javax.swing.text.AbstractDocument.Content.length.

Returns the length of the content.

private void
public UndoableEdit

Returns:

an UndoableEdit object for undoing
remove
(int
the starting position >= 0, where + nitems < length()
where
,
int
the number of characters to remove >= 0
nitems
)

Implements javax.swing.text.AbstractDocument.Content.remove.

Removes part of the content.

pack-priv final void
removeUnusedMarks()

Remove all unused marks out of the sorted collection of marks.

protected void
resetMarksAtZero()

Resets all the marks that have an offset of 0 to have an index of zero as well.

pack-priv void
resize(int nsize)

Overrides javax.swing.text.GapVector.resize.

resize the underlying storage array to the given new size

protected void
shiftEnd(int newSize)

Overrides javax.swing.text.GapVector.shiftEnd.

Make the gap bigger, moving any necessary data and updating the appropriate marks

protected void
shiftGap(int newGapStart)

Overrides javax.swing.text.GapVector.shiftGap.

Move the start of the gap to a new location, without changing the size of the gap.

protected void
shiftGapEndUp(int newGapEnd)

Overrides javax.swing.text.GapVector.shiftGapEndUp.

Adjust the gap end upward.

protected void
shiftGapStartDown(int newGapStart)

Overrides javax.swing.text.GapVector.shiftGapStartDown.

Adjust the gap end downward.

protected void
updateUndoPositions(Vector<E>
the UndoPosRef instances to reset
positions
,
int
where the string was inserted
offset
,
int
length of inserted string
length
)

Resets the location for all the UndoPosRef instances in positions.

Inherited from javax.swing.text.GapVector:
closegetArraygetGapEndgetGapStartopenreplace

Field Detail

emptyback to summary
private static final char[] empty
GROWTH_SIZEback to summary
pack-priv static final int GROWTH_SIZE
marksback to summary
private transient GapContent.MarkVector marks
queueback to summary
private transient ReferenceQueue<GapContent.StickyPosition> queue
unusedMarksback to summary
private transient int unusedMarks

The number of unused mark entries

Constructor Detail

GapContentback to summary
public GapContent()

Creates a new GapContent object. Initial size defaults to 10.

GapContentback to summary
public GapContent(int initialLength)

Creates a new GapContent object, with the initial size specified. The initial size will not be allowed to go below 2, to give room for the implied break and the gap.

Parameters
initialLength:int

the initial size

Method Detail

allocateArrayback to summary
protected Object allocateArray(int len)

Implements abstract javax.swing.text.GapVector.allocateArray.

Allocate an array to store items of the type appropriate (which is determined by the subclass).

compareback to summary
pack-priv final int compare(GapContent.MarkData o1, GapContent.MarkData o2)

Compares two marks.

Parameters
o1:GapContent.MarkData

the first object

o2:GapContent.MarkData

the second object

Returns:int

< 0 if o1 < o2, 0 if the same, > 0 if o1 > o2

createPositionback to summary
public Position createPosition(int offset) throws BadLocationException

Implements javax.swing.text.AbstractDocument.Content.createPosition.

Creates a position within the content that will track change as the content is mutated.

Parameters
offset:int

the offset to track >= 0

Returns:Position

the position

Exceptions
BadLocationException:
if the specified position is invalid
findMarkAdjustIndexback to summary
pack-priv final int findMarkAdjustIndex(int searchIndex)

Finds the index to start mark adjustments given some search index.

findSortIndexback to summary
pack-priv final int findSortIndex(GapContent.MarkData o)

Finds the index of where to insert a new mark.

Parameters
o:GapContent.MarkData

the mark to insert

Returns:int

the index

getArrayLengthback to summary
protected int getArrayLength()

Implements abstract javax.swing.text.GapVector.getArrayLength.

Get the length of the allocated array.

getCharsback to summary
public void getChars(int where, int len, Segment chars) throws BadLocationException

Implements javax.swing.text.AbstractDocument.Content.getChars.

Retrieves a portion of the content. If the desired content spans the gap, we copy the content. If the desired content does not span the gap, the actual store is returned to avoid the copy since it is contiguous.

Parameters
where:int

the starting position >= 0, where + len <= length()

len:int

the number of characters to retrieve >= 0

chars:Segment

the Segment object to return the characters in

Exceptions
BadLocationException:
if the specified position is invalid
See Also
AbstractDocument.Content#getChars
getNewArraySizeback to summary
pack-priv int getNewArraySize(int reqSize)

Overrides javax.swing.text.GapVector.getNewArraySize.

Overridden to make growth policy less aggressive for large text amount.

getPositionsInRangeback to summary
protected Vector<E> getPositionsInRange(Vector<E> v, int offset, int length)

Returns a Vector containing instances of UndoPosRef for the Positions in the range offset to offset + length. If v is not null the matching Positions are placed in there. The vector with the resulting Positions are returned.

Parameters
v:Vector<E>

the Vector to use, with a new one created on null

offset:int

the starting offset >= 0

length:int

the length >= 0

Returns:Vector<E>

the set of instances

Annotations
@SuppressWarnings:rawtypes, unchecked
getStringback to summary
public String getString(int where, int len) throws BadLocationException

Implements javax.swing.text.AbstractDocument.Content.getString.

Retrieves a portion of the content.

Parameters
where:int

the starting position >= 0

len:int

the length to retrieve >= 0

Returns:String

a string representing the content

Exceptions
BadLocationException:
if the specified position is invalid
See Also
AbstractDocument.Content#getString
insertStringback to summary
public UndoableEdit insertString(int where, String str) throws BadLocationException

Implements javax.swing.text.AbstractDocument.Content.insertString.

Inserts a string into the content.

Parameters
where:int

the starting position >= 0, < length()

str:String

the non-null string to insert

Returns:UndoableEdit

an UndoableEdit object for undoing

Exceptions
BadLocationException:
if the specified position is invalid
See Also
AbstractDocument.Content#insertString
lengthback to summary
public int length()

Implements javax.swing.text.AbstractDocument.Content.length.

Returns the length of the content.

Returns:int

the length >= 1

See Also
AbstractDocument.Content#length
readObjectback to summary
private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException
Annotations
@Serial
removeback to summary
public UndoableEdit remove(int where, int nitems) throws BadLocationException

Implements javax.swing.text.AbstractDocument.Content.remove.

Removes part of the content.

Parameters
where:int

the starting position >= 0, where + nitems < length()

nitems:int

the number of characters to remove >= 0

Returns:UndoableEdit

an UndoableEdit object for undoing

Exceptions
BadLocationException:
if the specified position is invalid
See Also
AbstractDocument.Content#remove
removeUnusedMarksback to summary
pack-priv final void removeUnusedMarks()

Remove all unused marks out of the sorted collection of marks.

resetMarksAtZeroback to summary
protected void resetMarksAtZero()

Resets all the marks that have an offset of 0 to have an index of zero as well.

resizeback to summary
pack-priv void resize(int nsize)

Overrides javax.swing.text.GapVector.resize.

Doc from javax.swing.text.GapVector.resize.

resize the underlying storage array to the given new size

Annotations
@Override
shiftEndback to summary
protected void shiftEnd(int newSize)

Overrides javax.swing.text.GapVector.shiftEnd.

Make the gap bigger, moving any necessary data and updating the appropriate marks

shiftGapback to summary
protected void shiftGap(int newGapStart)

Overrides javax.swing.text.GapVector.shiftGap.

Move the start of the gap to a new location, without changing the size of the gap. This moves the data in the array and updates the marks accordingly.

shiftGapEndUpback to summary
protected void shiftGapEndUp(int newGapEnd)

Overrides javax.swing.text.GapVector.shiftGapEndUp.

Adjust the gap end upward. This doesn't move any data, but it does update any marks affected by the boundary change. All marks from the old gap end up to the new gap end are squeezed to the end of the gap (their location has been removed).

shiftGapStartDownback to summary
protected void shiftGapStartDown(int newGapStart)

Overrides javax.swing.text.GapVector.shiftGapStartDown.

Adjust the gap end downward. This doesn't move any data, but it does update any marks affected by the boundary change. All marks from the old gap start down to the new gap start are squeezed to the end of the gap (their location has been removed).

updateUndoPositionsback to summary
protected void updateUndoPositions(Vector<E> positions, int offset, int length)

Resets the location for all the UndoPosRef instances in positions.

This is meant for internal usage, and is generally not of interest to subclasses.

Parameters
positions:Vector<E>

the UndoPosRef instances to reset

offset:int

where the string was inserted

length:int

length of inserted string

Annotations
@SuppressWarnings:rawtypes
javax.swing.text back to summary

pack-priv Class GapContent.InsertUndo

extends AbstractUndoableEdit
Class Inheritance
Annotations
@SuppressWarnings:serial

UnoableEdit created for inserts.

Field Summary

Modifier and TypeField and Description
protected int
length

Length of string inserted.

protected int
offset

Where string was inserted.

protected Vector<E>
posRefs

An array of instances of UndoPosRef for the Positions in the range that was removed, valid after undo.

protected String
string

The string that was inserted.

Inherited from javax.swing.undo.AbstractUndoableEdit:
RedoNameUndoName

Constructor Summary

AccessConstructor and Description
protected
InsertUndo(int offset, int length)

Method Summary

Modifier and TypeMethod and Description
public void
redo()

Overrides javax.swing.undo.AbstractUndoableEdit.redo.

Implements javax.swing.undo.UndoableEdit.redo.

Throws CannotRedoException if canRedo returns false.

public void
undo()

Overrides javax.swing.undo.AbstractUndoableEdit.undo.

Implements javax.swing.undo.UndoableEdit.undo.

Throws CannotUndoException if canUndo returns false.

Inherited from javax.swing.undo.AbstractUndoableEdit:
addEditcanRedocanUndodiegetPresentationNamegetRedoPresentationNamegetUndoPresentationNameisSignificantreplaceEdittoString

Field Detail

lengthback to summary
protected int length

Length of string inserted.

offsetback to summary
protected int offset

Where string was inserted.

posRefsback to summary
protected Vector<E> posRefs

An array of instances of UndoPosRef for the Positions in the range that was removed, valid after undo.

Annotations
@SuppressWarnings:rawtypes
stringback to summary
protected String string

The string that was inserted. This will only be valid after an undo.

Constructor Detail

InsertUndoback to summary
protected InsertUndo(int offset, int length)

Method Detail

redoback to summary
public void redo() throws CannotRedoException

Overrides javax.swing.undo.AbstractUndoableEdit.redo.

Implements javax.swing.undo.UndoableEdit.redo.

Doc from javax.swing.undo.AbstractUndoableEdit.redo.

Throws CannotRedoException if canRedo returns false. Sets hasBeenDone to true. Subclasses should override to redo the operation represented by this edit. Override should begin with a call to super.

Exceptions
CannotRedoException:
if canRedo returns false
undoback to summary
public void undo() throws CannotUndoException

Overrides javax.swing.undo.AbstractUndoableEdit.undo.

Implements javax.swing.undo.UndoableEdit.undo.

Doc from javax.swing.undo.AbstractUndoableEdit.undo.

Throws CannotUndoException if canUndo returns false. Sets hasBeenDone to false. Subclasses should override to undo the operation represented by this edit. Override should begin with a call to super.

Exceptions
CannotUndoException:
if canUndo returns false
javax.swing.text back to summary

pack-priv final Class GapContent.MarkData

extends WeakReference<GapContent.StickyPosition>
Class Inheritance

Holds the data for a mark... separately from the real mark so that the real mark (Position that the caller of createPosition holds) can be collected if there are no more references to it. The update table holds only a reference to this data.

Field Summary

Modifier and TypeField and Description
pack-priv int

Constructor Summary

AccessConstructor and Description
pack-priv
MarkData(int index)

pack-priv

Method Summary

Modifier and TypeMethod and Description
public int
getOffset()

Fetch the location in the contiguous sequence being modeled.

pack-priv GapContent.StickyPosition

Field Detail

indexback to summary
pack-priv int index

Constructor Detail

MarkDataback to summary
pack-priv MarkData(int index)
MarkDataback to summary
pack-priv MarkData(int index, GapContent.StickyPosition position, ReferenceQueue<? super GapContent.StickyPosition> queue)

Method Detail

getOffsetback to summary
public int getOffset()

Fetch the location in the contiguous sequence being modeled. The index in the gap array is held by the mark, so it is adjusted according to it's relationship to the gap.

getPositionback to summary
pack-priv GapContent.StickyPosition getPosition()
javax.swing.text back to summary

pack-priv Class GapContent.MarkVector

extends GapVector
Class Inheritance
Annotations
@SuppressWarnings:serial

Field Summary

Modifier and TypeField and Description
pack-priv GapContent.MarkData[]

Constructor Summary

AccessConstructor and Description
pack-priv
pack-priv
MarkVector(int size)

Method Summary

Modifier and TypeMethod and Description
public void
addElement(GapContent.MarkData m)

Add a mark to the end

protected Object
allocateArray(int len)

Implements abstract javax.swing.text.GapVector.allocateArray.

Allocate an array to store items of the type appropriate (which is determined by the subclass).

public GapContent.MarkData
elementAt(int index)

Fetches the mark at the given index

protected int
getArrayLength()

Implements abstract javax.swing.text.GapVector.getArrayLength.

Get the length of the allocated array

public void
insertElementAt(GapContent.MarkData m, int index)

Inserts a mark into the vector

protected void
replaceRange(int start, int end, Object[] marks)

Replaces the elements in the specified range with the passed in objects.

public int
size()

Returns the number of marks currently held

Inherited from javax.swing.text.GapVector:
closegetArraygetGapEndgetGapStartgetNewArraySizeopenreplaceresizeshiftEndshiftGapshiftGapEndUpshiftGapStartDown

Field Detail

oneMarkback to summary
pack-priv GapContent.MarkData[] oneMark

Constructor Detail

MarkVectorback to summary
pack-priv MarkVector()
MarkVectorback to summary
pack-priv MarkVector(int size)

Method Detail

addElementback to summary
public void addElement(GapContent.MarkData m)

Add a mark to the end

allocateArrayback to summary
protected Object allocateArray(int len)

Implements abstract javax.swing.text.GapVector.allocateArray.

Allocate an array to store items of the type appropriate (which is determined by the subclass).

elementAtback to summary
public GapContent.MarkData elementAt(int index)

Fetches the mark at the given index

getArrayLengthback to summary
protected int getArrayLength()

Implements abstract javax.swing.text.GapVector.getArrayLength.

Get the length of the allocated array

insertElementAtback to summary
public void insertElementAt(GapContent.MarkData m, int index)

Inserts a mark into the vector

replaceRangeback to summary
protected void replaceRange(int start, int end, Object[] marks)

Replaces the elements in the specified range with the passed in objects. This will NOT adjust the gap. The passed in indices do not account for the gap, they are the same as would be used int elementAt.

sizeback to summary
public int size()

Returns the number of marks currently held

javax.swing.text back to summary

pack-priv Class GapContent.RemoveUndo

extends AbstractUndoableEdit
Class Inheritance
Annotations
@SuppressWarnings:serial

UndoableEdit created for removes.

Field Summary

Modifier and TypeField and Description
protected int
length

Length of string removed.

protected int
offset

Where the string was removed from.

protected Vector<GapContent.UndoPosRef>
posRefs

An array of instances of UndoPosRef for the Positions in the range that was removed, valid before undo.

protected String
string

The string that was removed.

Inherited from javax.swing.undo.AbstractUndoableEdit:
RedoNameUndoName

Constructor Summary

AccessConstructor and Description
protected
RemoveUndo(int offset, String string)

Method Summary

Modifier and TypeMethod and Description
public void
redo()

Overrides javax.swing.undo.AbstractUndoableEdit.redo.

Implements javax.swing.undo.UndoableEdit.redo.

Throws CannotRedoException if canRedo returns false.

public void
undo()

Overrides javax.swing.undo.AbstractUndoableEdit.undo.

Implements javax.swing.undo.UndoableEdit.undo.

Throws CannotUndoException if canUndo returns false.

Inherited from javax.swing.undo.AbstractUndoableEdit:
addEditcanRedocanUndodiegetPresentationNamegetRedoPresentationNamegetUndoPresentationNameisSignificantreplaceEdittoString

Field Detail

lengthback to summary
protected int length

Length of string removed.

offsetback to summary
protected int offset

Where the string was removed from.

posRefsback to summary
protected Vector<GapContent.UndoPosRef> posRefs

An array of instances of UndoPosRef for the Positions in the range that was removed, valid before undo.

stringback to summary
protected String string

The string that was removed. This is valid when redo is valid.

Constructor Detail

RemoveUndoback to summary
protected RemoveUndo(int offset, String string)
Annotations
@SuppressWarnings:unchecked

Method Detail

redoback to summary
public void redo() throws CannotRedoException

Overrides javax.swing.undo.AbstractUndoableEdit.redo.

Implements javax.swing.undo.UndoableEdit.redo.

Doc from javax.swing.undo.AbstractUndoableEdit.redo.

Throws CannotRedoException if canRedo returns false. Sets hasBeenDone to true. Subclasses should override to redo the operation represented by this edit. Override should begin with a call to super.

Annotations
@SuppressWarnings:unchecked
Exceptions
CannotRedoException:
if canRedo returns false
undoback to summary
public void undo() throws CannotUndoException

Overrides javax.swing.undo.AbstractUndoableEdit.undo.

Implements javax.swing.undo.UndoableEdit.undo.

Doc from javax.swing.undo.AbstractUndoableEdit.undo.

Throws CannotUndoException if canUndo returns false. Sets hasBeenDone to false. Subclasses should override to undo the operation represented by this edit. Override should begin with a call to super.

Exceptions
CannotUndoException:
if canUndo returns false
javax.swing.text back to summary

pack-priv final Class GapContent.StickyPosition

extends Object
implements Position
Class Inheritance
All Implemented Interfaces
javax.swing.text.Position

Field Summary

Modifier and TypeField and Description
pack-priv GapContent.MarkData

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
public int
getOffset()

Implements javax.swing.text.Position.getOffset.

Fetches the current offset within the document.

pack-priv void
public String
toString()

Overrides java.lang.Object.toString.

Returns a string representation of the object.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAllwaitwaitwait

Field Detail

markback to summary
pack-priv GapContent.MarkData mark

Constructor Detail

StickyPositionback to summary
pack-priv StickyPosition()

Method Detail

getOffsetback to summary
public int getOffset()

Implements javax.swing.text.Position.getOffset.

Doc from javax.swing.text.Position.getOffset.

Fetches the current offset within the document.

setMarkback to summary
pack-priv void setMark(GapContent.MarkData mark)
toStringback to summary
public String toString()

Overrides java.lang.Object.toString.

Doc from java.lang.Object.toString.

Returns a string representation of the object. Satisfying this method's contract implies a non-null result must be returned.

javax.swing.text back to summary

pack-priv final Class GapContent.UndoPosRef

extends Object
Class Inheritance

Used to hold a reference to a Mark that is being reset as the result of removing from the content.

Field Summary

Modifier and TypeField and Description
protected GapContent.MarkData
rec

Mark to reset offset.

protected int
undoLocation

Previous Offset of rec.

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
protected void
resetLocation(int
end location of inserted string.
endOffset
,
int
resulting end of gap.
g1
)

Resets the location of the Position to the offset when the receiver was instantiated.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

recback to summary
protected GapContent.MarkData rec

Mark to reset offset.

undoLocationback to summary
protected int undoLocation

Previous Offset of rec.

Constructor Detail

UndoPosRefback to summary
pack-priv UndoPosRef(GapContent.MarkData rec)

Method Detail

resetLocationback to summary
protected void resetLocation(int endOffset, int g1)

Resets the location of the Position to the offset when the receiver was instantiated.

Parameters
endOffset:int

end location of inserted string.

g1:int

resulting end of gap.